Vi måste skriva SELECT-sökresultaten till en csv-fil. Hur kan det göras med T-SQL i SQL Server 2008 R2? Jag vet att det kan göras i SSIS, men av vissa anledningar har vi inte det här alternativet.
Jag försökte använda den föreslagna proc i artikeln nedan, men när jag kör proc, SQL klagar som inte kan köra sys.sp_OACreate och sys.sp_OADestroy som kallas i denna proc.
Vet du hur vi kan slå på dessa komponenter eller vet du något bättre sätt att skriva till en fil med T-SQL?
Tack på förhand.
Svar
Använd BCP-verktyg
bcp "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" queryout "D:\MyTable.csv" -c -t , -S SERVERNAME -T
Argumentet -c
anger c karaktärsutgång, i motsats till SQL: s ursprungliga binära format; detta är som standard flikavgränsade värden, men -t ,
ändrar fältet t erminator till kommatecken. -T
anger Windows-autentisering (” t rostig anslutning ”), använd annars -U MyUserName -P MyPassword
.
Detta exporterar inte kolumnrubriker som standard. Du måste använda en UNION ALL för rubriker
ELLER
Använd SQLCMD
SQLCMD -S SERVERNAME -E -Q "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" -s "," -o "D:\MyData.csv"
ELLER
Använd Powershell
Här är en länk till en artikel . Om du slutar använda detta kanske du vill lägga till -notype
efter Export-Csv $extractFile
för att bli av med den onödiga kolumnen i utdatafilen.
Kommentarer
- +1 För BCP-verktyget – det är väldigt enkelt att använda, det är det snabbaste verktyget jag någonsin har använt för export / import information och det finns många alternativ. Jag råder dig att lägga till ” > FileName.log ” i slutet av uttalande – detta skapar en loggfil.
- Alla svar som rör ett GUI-program är helt enkelt utanför räckvidden. Detta är den bästa lösningen ur DBA-synvinkel!
Svar
Lägger till föregående svar, vilket hjälper dig att automatisera åtgärden, om du bara behöver det då och då kan du göra det i Management Studio, helt enkelt högerklicka på rubriken – Spara resultat som -> välj a. csv-fil .
Eller om du vill göra det för varje valt uttalande som du kör kan du ändra resultatets riktning till en fil. Använd Verktyg -> Alternativ -> Frågeresultat – Resultat för fil .
Ett annat sätt som kan automatiseras enkelt och använder SSIS, är med hjälp av Management Studios exportdata-funktion. Högerklicka på databasen -> Uppgifter -> Exportera data. Det finns en guide med många alternativ där. Du bör välja källdatabasen, destinationen och andra alternativ. För destinationen se till att den är platt fil, bläddra och välj .csv-typ , välj vilken formatering du behöver och i slutet får du ett SSIS-paket som kan sparas lokalt och upprepas efter behov.
Svar
Använd 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
Men det finns ett par försiktighetsåtgärder:
- Du måste ha Microsoft.ACE.OLEDB.12.0-leverantören tillgänglig. Jet 4.0-leverantören fungerar också, men den är gammal, så jag använde den här istället.
- .CSV-filen måste redan finnas. Om du använder rubriker (HDR = YES) , se till att den första raden i .CSV-filen är en avgränsad lista över alla fält.
Kommentarer
- Bästa svaret så långt!
- bra jobb inklusive försiktighetsåtgärder
- Ytterligare en försiktighet: du kan behöva behörigheter, annars ser du: Msg 15281, nivå 16, tillstånd 1, rad 2 SQL Server blockerad åtkomst till UTTALANDE ’ OpenRowset / OpenDatasource ’ av komponent ’ Distribuerade ad hoc-frågor ’ eftersom den här komponenten är avstängd som en del av säkerhetskonfigurationen för denna server. En systemadministratör kan aktivera användning av ’ Ad Hoc Distribuerade frågor ’ med hjälp av sp_configure. För mer information om att aktivera ’ Ad Hoc Distribuerade frågor ’, sök efter ’ Ad Hoc Distribuerade frågor ’ i SQL Server Books Online.
Svar
Lågteknologisk, men …
select col1 + "," + cast(col2 as varchar(10)) + "," + col3 from mytable;
Kommentarer
- MySQL behandlar
col1 + ',' + cast(col2 as varchar(10)) + ',' + col3
som ett kolumnnamn och skriver ut NULL överallt.
Svar
Det verkar som om du redan har en acceptabel lösning, men om du har db-e-post konfigurerat dig kan eventuellt göra något så här:
EXEC msdb.dbo.sp_send_dbmail @recipients="[email protected]", @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
Om du skickar filen via e-post någonstans, kan det spara några steg.
Kommentarer
- Precis vad jag letade efter, kudos till dig!
- Även om du måste lägga till parametern @profile_name om du inte har någon privat standardprofil för din användare eller offentlig profil för databasen.
Svar
Detta kan enkelt göras i tre steg process:
-
Skriv din fråga som en
SELECT INTO
-fråga. Detta kommer i huvudsak att exportera dina sökresultat till en tabell.Select Field1 ,Field2 ,Field3 INTO dbo.LogTableName --Table where the query Results get logged into. From Table
Obs! Den här tabellen kan inte finns när frågan körs, eftersom denna typ av fråga vill skapa tabellen som en del av körningen.
-
Använd sedan SSIS för att exportera resultaten av den tabellen till
.csv
. Med guiden SSIS Export kan du välja din avgränsare osv. Det här är verkligen praktiskt för att använda en | avgränsare i fall där resultatsatsen innehåller komma.Högerklicka på
DB Name > Tasks > Export Data
-
När exporten är klar utför du
DROP TABLE
-kommando för att städa upp din loggtabell.Drop Table dbo.LogTableName
Kommentarer
- Hej Don. Jag lade till lite formatering i ditt svar. Du kan klicka på ’ redigera ’ nere till vänster för att se vad ’ ändrats och klicka på ” redigerad ” xx minuter ” bit för att se en fullständig historik om du vill rulla tillbaka. Även om det är användbart kan ditt svar inte ’ lägga till mycket över vad ’ redan har skrivits och det är osannolikt att det kommer att få mycket uppmärksamhet.
Svar
Denna procedur genererar en CSV-fil med utdata från frågan du skickar som parameter. Den andra parametern är ditt CSV-filnamn, se till att du skickar filnamnet med en giltig skrivbar sökväg.
Här är skriptet för att skapa proceduren:
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
Kommentarer
- kod endast svar är inte ’ som inte accepteras här – kan du lägga till kommentarer om ditt svar och varför det fungerar? (kodkommentarer skulle förmodligen hjälpa till här också)
- Ja, och kan du också lägga till ett exempel på hur du lyckas använda det?
Svara
Jag använder MS Access DoCMD för att exportera CSV ”från SQL Server. Den kan göra det med ett enda kommando. Åtkomstdatabasen används bara för att aktivera åtkomstkommandot. Det fungerar bra och som en extra fördel (inte säker på varför) skapar det ett schema.ini för den exporterade tabellen.
Adam
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"