Bir csv dosyasına seçme sonucu yazma


37

SELECT sorgusu sonuçlarını bir csv dosyasına yazmamız gerekiyor. SQL Server 2008 r2’de T-SQL kullanılarak nasıl yapılabilir? SSIS’de yapılabileceğini biliyorum, ancak bazı nedenlerden dolayı, bu seçeneğe sahip değiliz.

Önerilen makaleyi aşağıdaki makalede kullanmayı denedim, ancak procu çalıştırdığımda SQL, bu proseste adı verilen sys.sp_OACreate ve sys.sp_OADestroy komutunu çalıştıramadığından şikayet ediyor.

Bu bileşenleri nasıl açabileceğimizi veya T-SQL kullanarak bir dosyaya yazmanın daha iyi bir yolunu nasıl biliyoruz?

Şimdiden teşekkürler.

Yanıtlar:


52

BCP yardımcı programını kullanın

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

-cArgüman belirtir c haracter çıkışı, SQL'ın ikil formatın aksine; Bu sekme ayrılmış değerler arasındadır, ama -t ,alan değişiklikleri t virgül erminator. -Tbelirtir Windows kimlik doğrulaması ( " t paslı bağlantı"), aksi kullanın -U MyUserName -P MyPassword.

Bu, sütun başlıklarını varsayılan olarak dışa aktarmaz. Başlıklar için bir UNION ALL kullanmanız gerekir.

VEYA

SQLCMD kullanın

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

VEYA

Powershell kullanın

İşte bir makalenin bağlantısı . Bunu kullanmaya başlarsanız , çıktı dosyasındaki gereksiz sütundan kurtulmak için -notypesonradan ekleme yapmak isteyebilirsiniz Export-Csv $extractFile.


4
+1 BCP yardımcı programı için - kullanımı çok kolaydır, ihracat / ithalat bilgileri için şimdiye kadar kullandığım en hızlı araçtır ve birçok seçenek vardır. İfadenin sonuna "> DosyaAdı.log" eklemenizi tavsiye ederim - bu bir günlük dosyası oluşturur.
saat

24

Eylemi otomatikleştirmenize yardımcı olan önceki cevaba ekleyerek, yalnızca zaman zaman ihtiyacınız olursa Management Studio'da yapabilirsiniz, başlığa sağ tıklayın - Sonuçları farklı kaydet -> bir .csv dosyası seçin .

Veya bunu çalıştırmak istediğiniz her select ifadesi için yapmak istiyorsanız, sonuçların çıktı yönünü bir dosyaya değiştirebilirsiniz. Kullanım Araçlar -> Seçenekler -> Sorgu Sonuçları - dosyaya Sonuçları .

Kolayca otomatikleştirilebilen ve SSIS'den yararlanan bir diğer yol, Management Studio'nun İhracat Verileri özelliğini kullanmaktır. Veritabanına sağ tıklayın -> Görevler -> Verileri dışa aktarın. Orada birçok seçenek olan bir sihirbaz var. Kaynak veritabanını, hedefi ve diğer seçenekleri seçmelisiniz. Hedef için "Düz dosya" olduğundan emin olun.


10

T-SQL kullan

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

Fakat birkaç uyarı var:

  1. Microsoft.ACE.OLEDB.12.0 sağlayıcısına sahip olmanız gerekir. Jet 4.0 sağlayıcısı da işe yarayacak, ancak eski, bu yüzden bunu kullandım.
  2. .CSV dosyası zaten mevcut olacak. Başlık kullanıyorsanız (HDR = YES), .CSV dosyasının ilk satırının tüm alanların ayrılmış bir listesi olduğundan emin olun.

1
Şimdiye kadarki en iyi cevap!
ajeh

1
uyarılar dahil olmak üzere harika bir iş
JJS

5

Düşük teknoloji, ama ...

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

MySQL col1 + ',' + cast(col2 as varchar(10)) + ',' + col3sütun adı olarak kabul edilir ve her yere NULL yazdırır.
Nikhil Wagh

4

Kabul edilebilir bir çözümünüz var gibi gözüküyor, ancak db posta ayarladıysanız, potansiyel olarak şu gibi bir şey yapabilirsiniz:

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

Dosyayı herhangi bir yere e-postayla gönderiyorsanız, birkaç adımda tasarruf etmenizi sağlayabilir.


Tam aradığım şey, sana şeref!
Mashchax

Bununla birlikte, kullanıcı için varsayılan bir özel profiliniz yoksa veritabanınız için ortak bir profiliniz yoksa @profile_name parametresini eklemeniz gerekir.
Mashchax

1

Bu 3 adımda kolayca yapılabilir:

  1. Sorgunuzu bir SELECT INTOsorgu olarak yazın . Bu, aslında sorgu sonuçlarınızı bir tabloya verir.

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

    Not: Bu tablo , sorgu çalıştığında mevcut olamaz , çünkü bu tür bir sorgu, tablonun yürütmenin bir parçası olarak oluşturulmasını istiyor.

  2. Ardından bu tablonun sonuçlarını dışa aktarmak için SSIS kullanın .csv. SSIS Verme sihirbazı, sınırlayıcınızı vb. Seçmenize olanak tanır. Sonuç kümesinin virgül içerdiği durumlarda sınırlayıcı.

    Sağ tıklayın DB Name > Tasks > Export Data

  3. Verme işlemi tamamlandıktan sonra, DROP TABLEgünlük tablonuzu temizlemek için komutu yürütün .

    Drop Table dbo.LogTableName

3
Selam Don. Cevabınıza biraz biçimlendirme ekledim. Neyin değiştiğini görmek için sol alt kısımdaki 'düzenle'yi tıklayabilir ve geri dönmek istiyorsanız tam bir geçmiş görmek için "düzenlenen" xx dakika "bitini tıklayabilirsiniz. Zaten yazılmış olan ve çok fazla dikkat çekmeyecek olan şeyler
Michael Green

0

CSV'leri SQL Server'dan dışa aktarmak için MS Access DoCMD kullanıyorum. Tek bir komutla bunu yapabilir. Erişim veritabanı sadece erişim komutunu etkinleştirmek için kullanılır. İyi performans gösterir ve ek bir fayda olarak (neden olduğundan emin değilsiniz) dışa aktarılan tablo için bir schema.ini oluşturur.

Adem

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

Bu yordam, parametre olarak ilettiğiniz sorgunun çıktısını içeren bir CSV dosyası oluşturur. 2. parametre, CSV dosya adınızdır, dosya adını geçerli bir yazılabilir yolla ilettiğinizden emin olun.

Prosedürü oluşturmak için komut dosyası:

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
kod yalnızca cevaplar burada kabul edilemez olarak görülmez - cevabınıza biraz yorum ekleyebilir misiniz ve neden işe yarıyor? (kod yorumları muhtemelen burada da yardımcı olacaktır)
George.Palacios

Evet, ayrıca başarıyla nasıl kullandığınıza dair bir örnek ekleyebilir misiniz?
Marcello Miorelli
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.