การเขียนผลลัพธ์ที่เลือกไปยังไฟล์ csv


37

เราจำเป็นต้องเขียนผลลัพธ์การสืบค้น SELECT ลงในไฟล์ csv จะใช้ T-SQL ใน SQL Server 2008 r2 ได้อย่างไร ฉันรู้ว่ามันสามารถทำได้ใน SSIS แต่ด้วยเหตุผลบางอย่างเราไม่มีตัวเลือกนี้

ฉันพยายามใช้ proc ที่แนะนำในบทความด้านล่าง แต่เมื่อฉันเรียกใช้ proc, SQL บ่นว่าไม่สามารถเรียกใช้ sys.sp_OACreate และ sys.sp_OADestroy ที่เรียกว่าใน proc นี้

คุณรู้วิธีที่เราสามารถเปิดส่วนประกอบเหล่านี้หรือรู้วิธีการเขียนไฟล์โดยใช้ T-SQL

ขอบคุณล่วงหน้า.

คำตอบ:


52

ใช้ยูทิลิตี้ BCP

bcp "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" queryout "D:\MyTable.csv" -c -t , -S SERVERNAME -T

-cอาร์กิวเมนต์ระบุเอาท์พุท haracter เมื่อเทียบกับรูปแบบไบนารีพื้นเมือง SQL; ค่าเริ่มต้นนี้เป็นค่าที่คั่นด้วยแท็บ แต่-t ,เปลี่ยนฟิลด์t erminator เป็นเครื่องหมายจุลภาค -Tระบุการตรวจสอบของ Windows ( " ทีเชื่อมต่อสนิม") -U MyUserName -P MyPasswordมิฉะนั้นใช้

สิ่งนี้จะไม่ส่งออกส่วนหัวคอลัมน์โดยค่าเริ่มต้น คุณต้องใช้ UNION ALL สำหรับส่วนหัว

หรือ

ใช้ SQLCMD

SQLCMD -S SERVERNAME -E -Q "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable"
-s "," -o "D:\MyData.csv" 

หรือ

ใช้ Powershell

นี่คือเชื่อมโยงไปยังบทความ หากคุณสิ้นสุดการใช้นี้คุณอาจต้องการที่จะผนวก-notypeหลังจากExport-Csv $extractFileการกำจัดของคอลัมน์ที่ไม่จำเป็นในไฟล์ที่ส่งออก


4
+1 สำหรับยูทิลิตี้ BCP - มันใช้งานง่ายมากมันเป็นเครื่องมือที่เร็วที่สุดที่ฉันเคยใช้ในการส่งออก / นำเข้าข้อมูลและมีตัวเลือกมากมาย ฉันจะแนะนำให้คุณเพิ่ม "> FileName.log" ในตอนท้ายของข้อความสั่ง - นี่จะสร้างไฟล์บันทึก
gotqn

24

การเพิ่มคำตอบก่อนหน้าซึ่งจะช่วยให้คุณทำให้การดำเนินการถ้าคุณต้องการมันเพียง แต่จากเวลาที่คุณสามารถทำมันได้ใน Studio จัดการเพียงแค่คลิกขวาบนส่วนหัว - บันทึกผลเป็น -> เลือกไฟล์

หรือถ้าคุณต้องการทำเช่นนั้นสำหรับแต่ละคำสั่ง select ที่คุณเรียกใช้คุณสามารถเปลี่ยนทิศทางผลลัพธ์ของผลลัพธ์เป็นไฟล์ การใช้เครื่องมือ -> ตัวเลือก -> ผลการสืบค้นข้อมูล - ผลการค้นหาไปยังแฟ้ม

อีกวิธีหนึ่งที่สามารถทำให้เป็นอัตโนมัติได้อย่างง่ายดายและใช้ประโยชน์จาก SSIS คือการใช้คุณลักษณะส่งออกข้อมูลของ Management Studio คลิกขวาที่ฐานข้อมูล -> งาน -> ส่งออกข้อมูล มีตัวช่วยสร้างที่มีตัวเลือกมากมาย คุณควรเลือกฐานข้อมูลต้นทางปลายทางและตัวเลือกอื่น ๆ สำหรับปลายทางตรวจสอบให้แน่ใจว่าเป็น "ไฟล์แบน" เรียกดูและเลือกประเภท. csv เลือกรูปแบบที่คุณต้องการและในตอนท้ายคุณจะได้รับแพคเกจ SSIS ที่สามารถบันทึกได้ในพื้นที่และซ้ำตามต้องการ


10

ใช้ T-SQL

INSERT INTO OPENROWSET('Microsoft.ACE.OLEDB.12.0','Text;Database=D:\;HDR=YES;FMT=Delimited','SELECT * FROM [FileName.csv]')
SELECT Field1, Field2, Field3 FROM DatabaseName

แต่มีข้อแม้อยู่สองสามข้อ:

  1. คุณต้องมีผู้ให้บริการ Microsoft.ACE.OLEDB.12.0 ผู้ให้บริการ Jet 4.0 ก็ใช้งานได้เหมือนกัน แต่มันเก่าแก่ดังนั้นฉันจึงใช้มันแทน
  2. ไฟล์. CSV จะต้องมีอยู่แล้ว หากคุณใช้ส่วนหัว (HDR = YES) ตรวจสอบให้แน่ใจว่าบรรทัดแรกของไฟล์. CSV เป็นรายการที่คั่นด้วยเขตข้อมูลทั้งหมด

1
คำตอบที่ดีที่สุด!
ajeh

1
ผลงานยอดเยี่ยมรวมถึง caveats
JJS

5

เทคโนโลยีต่ำ แต่ ...

select
   col1 + ','
+  cast(col2 as varchar(10)) + ','
+  col3
from mytable;

MySQL ถือว่าcol1 + ',' + cast(col2 as varchar(10)) + ',' + col3เป็นชื่อคอลัมน์และพิมพ์ NULL ไปทั่วทุกที่
Nikhil Wagh

4

ดูเหมือนว่าคุณจะมีวิธีแก้ไขปัญหาที่ยอมรับได้ แต่ถ้าคุณตั้งค่าอีเมล db คุณอาจทำสิ่งนี้:

EXEC msdb.dbo.sp_send_dbmail
    @recipients='your.email@domain.com',
    @subject='CSV Extract', 
    @body='See attachment',
    @query ='SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable',
    @attach_query_result_as_file = 1,
    @query_attachment_filename = 'CSV_Extract.txt',
    @query_result_separator = ',',
    @query_result_header = 1

หากคุณกำลังส่งไฟล์อีเมลไปที่ใดที่หนึ่งก็อาจช่วยให้คุณประหยัดได้ไม่กี่ขั้นตอน


เพียงแค่สิ่งที่ฉันกำลังมองหารุ่งโรจน์กับคุณ!
Mashchax

แม้ว่าคุณจะต้องเพิ่มพารามิเตอร์ @profile_name หากคุณไม่มีโปรไฟล์ส่วนตัวเริ่มต้นสำหรับผู้ใช้หรือโปรไฟล์สาธารณะสำหรับฐานข้อมูล
Mashchax

1

สามารถทำได้อย่างง่ายดายในกระบวนการ 3 ขั้นตอน:

  1. เขียนแบบสอบถามของคุณเป็นSELECT INTOแบบสอบถาม สิ่งนี้จะส่งออกผลลัพธ์การสืบค้นของคุณไปยังตารางเป็นหลัก

    Select
      Field1
     ,Field2
     ,Field3
    INTO dbo.LogTableName         --Table where the query Results get logged into.
    From Table

    หมายเหตุตารางนี้ไม่มีอยู่เมื่อมีการเรียกใช้แบบสอบถามเนื่องจากแบบสอบถามชนิดนี้ต้องการสร้างตารางเป็นส่วนหนึ่งของการดำเนินการ

  2. จากนั้นใช้ SSIS .csvในการส่งออกผลของตารางที่ไป ตัวช่วยสร้างการส่งออก SSIS ช่วยให้คุณสามารถเลือกตัวคั่นและอื่น ๆ ได้ซึ่งมีประโยชน์มากสำหรับการใช้ | ตัวคั่นในอินสแตนซ์ที่ชุดผลลัพธ์มีเครื่องหมายจุลภาค

    คลิกขวาที่ DB Name > Tasks > Export Data

  3. เมื่อการส่งออกเสร็จสมบูรณ์ให้ดำเนินการDROP TABLEคำสั่งเพื่อล้างตารางบันทึกของคุณ

    Drop Table dbo.LogTableName

3
สวัสดีดอน ฉันเพิ่มการจัดรูปแบบบางคำตอบของคุณ คุณสามารถคลิกที่ 'แก้ไข' ที่ด้านล่างซ้ายเพื่อดูว่ามีอะไรเปลี่ยนแปลงและคลิกที่บิต "แก้ไข" xx นาที "เพื่อดูประวัติเต็มหากคุณต้องการย้อนกลับแม้จะใช้งานได้ แต่คำตอบของคุณไม่เพิ่มมากนัก สิ่งที่เขียนแล้วและไม่น่าดึงดูดความสนใจมากนัก
Michael Green

0

ฉันใช้ MS Access DoCMD เพื่อส่งออก CSV จาก SQL Server มันสามารถทำได้ด้วยคำสั่งเดียว ฐานข้อมูลการเข้าถึงใช้เพื่อเปิดใช้งานคำสั่งการเข้าถึงเท่านั้น มันทำงานได้ดีและเป็นประโยชน์เพิ่มเติม (ไม่แน่ใจว่าทำไม) มันสร้าง schema.ini สำหรับตารางที่ส่งออก

อาดัม

CMD="SELECT * INTO [Text;HDR=Yes;DATABASE=C:\].[Results.txt]  
FROM [ODBC;DSN=SQL2017;Description=SQL2017;UID=.;Trusted_Connection=Yes;APP=Microsoft Office 2013;WSID=LAPTOP-XYZ;DATABASE=TempDB_DataDump_1].Results "

 Set appAccess = CreateObject("Access.Application") 
                appAccess.OpenCurrentDatabase "anyAccessdatabase.mdb" 
                   ' appAccess.DoCmd.SetWarnings 0
                    appAccess.DoCmd.runsql "CMD"

-1

ขั้นตอนนี้จะสร้างไฟล์ CSV ที่มีผลลัพธ์ของแบบสอบถามที่คุณส่งผ่านเป็นพารามิเตอร์ พารามิเตอร์ที่ 2 คือชื่อไฟล์ CSV ของคุณตรวจสอบให้แน่ใจว่าคุณส่งชื่อไฟล์ด้วยเส้นทางที่สามารถเขียนได้ที่ถูกต้อง

นี่คือสคริปต์ในการสร้างขั้นตอน:

CREATE procedure [dbo].[usp_create_csv_file_from_query]
    @sql Nvarchar(MAX),
    @csvfile Nvarchar(200)
    as
    BEGIN
        if IsNull(@sql,'') = '' or IsNull(@csvfile,'') = ''
        begin
            RAISERROR ('Invalid SQL/CsvFile values passed!; Aborting...', 0, 1) WITH NOWAIT
            return
        end
        DROP TABLE if exists global_temp_CSVtable;
        declare 
            @columnList varchar(4000), 
            @columnList1 varchar(4000),
            @sqlcmd varchar(4000),
            @dos_cmd nvarchar(4000)

        set @sqlcmd = replace(@sql, 'from', 'into global_temp_CSVtable from')
        EXECUTE (@sqlcmd); 

        declare @cols table (i int identity, colname varchar(100))
        insert into @cols
        select column_name
        from information_schema.COLUMNS
        where TABLE_NAME = 'global_temp_CSVtable'

        declare @i int, @maxi int
        select @i = 1, @maxi = MAX(i) from @cols

        while(@i <= @maxi)
        begin
            select @sql = 'alter table global_temp_CSVtable alter column [' + colname + '] VARCHAR(max) NULL'
            from @cols
            where i = @i
            exec sp_executesql @sql
            select @i = @i + 1
        end

        SELECT 
             @columnList = COALESCE(@columnList + ''', ''', '') + column_name 
            ,@columnList1 = COALESCE(@columnList1 + ', ', '') + column_name
        from information_schema.columns
        where table_name =  'global_temp_CSVtable'
        ORDER BY ORDINAL_POSITION;

        SELECT @columnList = '''' + @columnList + '''';

        SELECT @dos_cmd='BCP "SELECT ' + @columnList + 
                        ' UNION ALL ' +
                        'SELECT * from ' + db_name() + '..global_temp_CSVtable" ' + 
                        'QUERYOUT ' + @csvfile + 
                        ' -c -t, -T'
        exec master.dbo.xp_cmdshell @dos_cmd, No_output 
        DROP TABLE if exists global_temp_CSVtable;
    end

2
โค้ดเฉพาะคำตอบจะไม่ถูกมองว่ายอมรับได้ที่นี่ - คุณสามารถเพิ่มความเห็นในคำตอบของคุณและทำไมมันถึงใช้งานได้? (ความเห็นของโค้ดอาจจะช่วยได้ที่นี่ด้วย)
George.Palacios

ใช่และคุณสามารถเพิ่มตัวอย่างเป็นวิธีการใช้งานได้สำเร็จหรือไม่?
Marcello Miorelli
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.