We moeten de SELECT-queryresultaten naar een csv-bestand schrijven. Hoe kan dit worden gedaan met behulp van T-SQL in SQL Server 2008 R2? Ik weet dat het kan worden gedaan in SSIS, maar om een aantal redenen hebben we deze optie niet.
Ik heb geprobeerd de voorgestelde procedure in het onderstaande artikel te gebruiken, maar als ik de procedure start, wordt SQL klaagt dat “sys.sp_OACreate en sys.sp_OADestroy die in dit proces worden aangeroepen niet kunnen draaien.
Weet u hoe we deze componenten kunnen inschakelen of weet u een betere manier om met T-SQL naar een bestand te schrijven?
Bij voorbaat dank.
Antwoord
Gebruik BCP-hulpprogramma
bcp "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" queryout "D:\MyTable.csv" -c -t , -S SERVERNAME -T
Het -c
argument specificeert c haracter-uitvoer, in tegenstelling tot het oorspronkelijke binaire formaat van SQL; dit zijn standaard door tabs gescheiden waarden, maar -t ,
verandert het veld t erminator in kommas. -T
specificeert Windows-authenticatie (“ t geroeste verbinding “), gebruik anders -U MyUserName -P MyPassword
.
Dit exporteert standaard geen kolomkoppen. U moet een UNION ALL gebruiken voor headers
OF
Gebruik SQLCMD
SQLCMD -S SERVERNAME -E -Q "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable" -s "," -o "D:\MyData.csv"
OF
Gebruik Powershell
Hier is een link naar een artikel . Als je dit uiteindelijk gaat gebruiken, wil je misschien -notype
toevoegen na Export-Csv $extractFile
om de onnodige kolom uit het uitvoerbestand te verwijderen.
Opmerkingen
- +1 Voor BCP-hulpprogramma – het is heel gemakkelijk te gebruiken, het is de snelste tool die ik ooit heb gebruikt voor exporteren / importeren informatie en er zijn veel opties. Ik raad je aan om ” > Bestandsnaam.log ” toe te voegen aan het einde van de statement – dit zal een logbestand creëren.
- Elk antwoord waarbij een GUI-programma betrokken is, valt gewoon buiten het bereik. Dit is de beste oplossing vanuit DBA-standpunt!
Antwoord
Toevoegen aan het vorige antwoord, dat helpt u bij het automatiseren van de actie, als u het slechts van tijd tot tijd nodig heeft, kunt u het doen in Management Studio, klik met de rechtermuisknop op de kop – Resultaten opslaan als -> kies een. csv-bestand .
Of als u dat wilt doen voor elke geselecteerde instructie die u uitvoert, kunt u de uitvoerrichting van de resultaten naar een bestand wijzigen. Gebruik Tools -> Options -> Query Results – Results to file .
Een andere manier, dat kan eenvoudig te automatiseren en gebruik te maken van SSIS, is door de functie Gegevens exporteren van Management Studio te gebruiken. Klik met de rechtermuisknop op de database -> Taken -> Gegevens exporteren. Er is een wizard met veel opties. Je moet de brondatabase, de bestemming en andere opties kiezen. Zorg ervoor dat het “plat bestand” is voor de bestemming, blader en kies .csv-type , kies de opmaak die je nodig hebt en aan het einde krijg je “een SSIS-pakket dat lokaal kan worden opgeslagen en indien nodig kan worden herhaald.
Answer
Gebruik 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
Maar er zijn een paar kanttekeningen:
- U moet de Microsoft.ACE.OLEDB.12.0-provider beschikbaar. De Jet 4.0-provider zal ook werken, maar het is oud, dus ik heb deze in plaats daarvan gebruikt.
- Het .CSV-bestand moet al bestaan. Als je headers gebruikt (HDR = YES) , zorg ervoor dat de eerste regel van het .CSV-bestand een gescheiden lijst is van alle velden.
Opmerkingen
- Beste antwoord dus ver!
- goed werk inclusief kanttekeningen
- Nog een waarschuwing: je hebt misschien toestemming nodig, anders zie je: Msg 15281, niveau 16, staat 1, regel 2 SQL Server blokkeerde de toegang tot VERKLARING ‘ OpenRowset / OpenDatasource ‘ van component ‘ Ad hoc gedistribueerde zoekopdrachten ‘ omdat dit onderdeel is uitgeschakeld als onderdeel van de beveiligingsconfiguratie voor deze server. Een systeembeheerder kan het gebruik van ‘ Ad Hoc gedistribueerde zoekopdrachten ‘ inschakelen door sp_configure te gebruiken. Voor meer informatie over het inschakelen van ‘ Ad hoc gedistribueerde zoekopdrachten ‘, zoek je naar ‘ Ad Hoc Gedistribueerde zoekopdrachten ‘ in SQL Server Books Online.
Antwoord
Low tech, maar …
select col1 + "," + cast(col2 as varchar(10)) + "," + col3 from mytable;
Reacties
- MySQL behandelt
col1 + ',' + cast(col2 as varchar(10)) + ',' + col3
als een kolomnaam, en drukt overal NULL af.
Answer
Het lijkt erop dat je al een acceptabele oplossing hebt, maar als je db mail hebt ingesteld, zou in potentie zoiets als dit kunnen doen:
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
Als u het bestand toch ergens e-mailt, kan het u een paar stappen besparen.
Opmerkingen
- Precies wat ik zocht, een pluim voor je!
- Hoewel je de parameter @profile_name moet toevoegen als je geen standaard privéprofiel hebt voor uw gebruiker of openbaar profiel voor de database.
Antwoord
Dit kan eenvoudig worden gedaan in drie stappen proces:
-
Schrijf uw vraag als een
SELECT INTO
vraag. Hierdoor worden de zoekresultaten in feite naar een tabel geëxporteerd.Select Field1 ,Field2 ,Field3 INTO dbo.LogTableName --Table where the query Results get logged into. From Table
Let op, deze tabel kan niet bestaan wanneer de query wordt uitgevoerd, aangezien dit type query de tabel wil maken als onderdeel van de uitvoering.
-
Gebruik vervolgens SSIS om te exporteren de resultaten van die tabel naar
.csv
. Met de SSIS Export-wizard kunt u uw scheidingsteken enz. Kiezen. Dit is erg handig voor het gebruik van een | scheidingsteken in gevallen waarin de resultaatset kommas bevat.Klik met de rechtermuisknop op
DB Name > Tasks > Export Data
-
Zodra de export is voltooid, voert u de
DROP TABLE
commando om je logtabel op te schonen.Drop Table dbo.LogTableName
Reacties
- Hallo Don. Ik heb wat opmaak aan je antwoord toegevoegd. U kunt linksonder op ‘ bewerken ‘ klikken om te zien wat ‘ gewijzigd en klik op het ” bewerkte ” xx minuten ” bit om een volledige geschiedenis te zien als je wilt terugdraaien. Hoewel het werkbaar is, voegt uw antwoord ‘ niet veel toe aan wat ‘ s al is geschreven en zal waarschijnlijk niet veel aandacht trekken.
Answer
Deze procedure genereert een CSV-bestand met de output van de query die je doorgeeft als parameter. De 2e parameter is uw CSV-bestandsnaam, zorg ervoor dat u de bestandsnaam doorgeeft met een geldig schrijfbaar pad.
Hier is het script om de procedure te maken:
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
Reacties
- antwoorden met alleen code worden ‘ hier niet als acceptabel gezien – zou je wat commentaar kunnen geven op je antwoord en waarom het werkt? (codecommentaar zou hier waarschijnlijk ook helpen)
- Ja, en zou je ook een voorbeeld kunnen toevoegen van hoe je het met succes hebt gebruikt?
Antwoord
Ik gebruik MS Access DoCMD om CSV “s uit SQL Server te exporteren. Het is in staat om het te doen met een enkele opdracht. De toegangsdatabase wordt alleen gebruikt om de toegangsopdracht in te schakelen. Het presteert goed, en als een bijkomend voordeel (niet zeker waarom) creëert het een schema.ini voor de geëxporteerde tabel.
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"