Verktyget BCP (Bulk Copy Program) i SQL Server tillåter databasadministratörer att importera data till en tabell och exportera data från en tabell till en platt fil. BCP-verktyget stöder också olika funktioner som underlättar processen för export och import av bulkdata.
Låt oss nu börja med ett affärsscenario.
Affärsscenario
Låt oss säga att vi måste dela en månadsrapport i det specifika formatet till en klient på en säker delad plats som SFTS, det vill säga i början av varje månad måste vi skicka filen till en klient för föregående månad. I det här scenariot kommer vi att försöka skapa den lagrade proceduren för att generera data och exportera dessa data till den platta filen (.txt eller .csv).
Hur importerar och exporterar jag SQL-data?
Det finns flera sätt att göra detta:
- Använd SSMS, kör frågan i frågefönstret och exportera eller SQL Servers import- och exportguide.
- Använda SSIS – Skapa ett paket med SSDT.
- Använder SSRS.
- Använda C# – Skapa konsol eller vinn applikation att exportera.
- BCP-verktyg.
- osv.
Vad är BCP Utility?
BCP (Bulk copy program) verktyg är ett kommandoradsverktyg för att kopiera data mellan en instans av MS SQL Server och en datafil i ett användarspecificerat format. Vi kan exportera och importera stora mängder data in och ut från SQL Server-databaserna snabbt och enkelt.
BCP-verktyget utför följande uppgifter:
- Massexport av data från en SQL Server-tabell till en datafil.
- Massdataexport från en fråga/Lagrad procedur.
- Massdataimport från en datafil till en SQL Server-tabell.
- Generering av formatfiler.
Du kan hitta mer information om BCP Utility här.
Använd miljö
- SQL Server 2017 Developer Edition
- SQL server 2017 Management studio
- Wide World Importers exempeldatabas v1.0
- BCP-verktyg
Hur man exporterar data till en platt fil
Skapa en lagrad procedur för att generera månadsrapportdata.
Skapa först de beroende objekten för den lagrade exportproceduren.
Så vi måste skapa följande tabeller:
- Order_Monthly_Temp_Table tabell:denna temporära tabell används för att lagra månadsbeställningsdata i ett specifikt format för att exportera det till textfil, dvs. i vårt fall sammanfoga alla kolumner i en rad med avgränsare "|".
- Export_Config tabell:denna tabell används för att lagra exportkonfigurationer, t.ex. sökväg för delad mapp, platt filtyp, avgränsare.
Skapa ett skript för Orders_Monthly_Temp_Table
SKAPA TABELL [dbo].[Orders_Monthly_Temp_Table]( [Row] [varchar](200) INTE NULL) PÅ [PRIMÄR]
Skapa ett skript för Export_Config
SKAPA TABELL [dbo].[Export_Config]( [Exp_Id] [int] IDENTITY(1,1) NOT NULL, [ShareFolder] [varchar](200) NOT NULL, [FileType] [varchar](5) NOT NULL, [Avgränsare] [char](1) INTE NULL, BEGRÄNSNING [PK_Export_Config] PRIMÄRNYCKEL KLUSTERAD ( [Exp_Id] ASC)WITH (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV_,_ALLÅT =AV_,_) [USERDATA]) PÅ [USERDATA]GO
Infoga data i Export_Config
SET IDENTITY_INSERT [dbo].[Export_Config] PÅ GOINSERT [dbo].[Export_Config] ([Exp_Id], [ShareMapp], [FileType], [Delimiter]) VÄRDEN (1, N'\\AASHREEPC\FileServer\ OrdersMonthly', N'.txt', N'|')GOSET IDENTITY_INSERT [dbo].[Export_Config] OFFGO
Skapa lagrad procedur och parametrar
- Här är parametrarna för år och månad valfria.
- Om en månad inte anges tar det föregående månad och om månaden är 12 måste vi ta föregående år, för om vi genererar rapporten i jan’2019 för dec’2018.
- Om ett år inte anges tar det det aktuella året och mappsökväg är obligatorisk.
SKAPA PROCEDUR [dbo].[Order_Monthly_Report] @Month INT =NULL ,@Year INT =NULL ,@FolderPath VARCHAR(200) ASBEGIN SET NOCOUNT ON; BÖRJA FÖRSÖK
Parametervalidering
--#region Validering av parametrar IF NULLIF(@Month, '') IS NULL BEGIN SELECT @Month =DATEDEL(mm, DATEADD(month, - 1, GETDATE())) IF (@Month =12) – BEGIN VÄLJ @Year =DATEPART(Year, GETDATE()) - 1 END END IF NULLIF(@Year, '') IS NULL BEGIN SELECT @Year =DATEPART(Year, GETDATE()) END IF NULLIF(@FolderPath, '') IS NULL BEGIN --SELECT @FolderPath ='\\AASHREEPC\FileServer' VÄLJ 'ERROR FolderPath måste anges.' LÄMNA TILLBAKA; END --#endregion Validering av parametrar
Hämta konfigurationen från exporttabellen
DECLARE @ExportPath VARCHAR(200) ,@Delimiter CHAR(1) ,@FileType VARCHAR(5) SELECT @ExportPath =TRIM(ShareMapp) ,@FileType =TRIM(FileType) ,@Delimiter =TRIM(Delimiter) FROM dbo .Export_Config
Hämta startdatum och slutdatum för månaden
DECLARE @MonthStartDate DATETIME =DATEADD(month, @Month - 1, DATEADD(år, @Year - 1900, 0)) ,@MonthEndDate DATETIME =DATEADD(dag, - 1, DATEADD(månad, @Månad, DATEADD( år, @År - 1900, 0))) Kontrollera och skapa den tillfälliga tabellen för rapportdata/resultat OM INTE FINNS (VÄLJ * FROM sys.objects WHERE object_id =OBJECT_ID(N'[dbo].[Orders_Monthly_Temp_Table]') OCH skriv IN (N'U') ) BÖRJA SKAPA TABELL [dbo]. Orders_Monthly_Temp_Table ([Row] [varchar](200) INTE NULL) PÅ [PRIMÄR] END
Infoga data i temptabellen i ett specifikt format, dvs i det här fallet "| – rörsymbolen separerad”
TRUNCATE TABLE Orders_Monthly_Temp_TableINSERT INTO Orders_Monthly_Temp_Table SELECT CAST([OrderID] AS VARCHAR(10)) + ' | ' + CAST(c.[Kundnamn] SOM VARCHAR(50)) + ' | ' + CAST(s.[Fullnamn] SOM VARCHAR(50)) + ' | ' + ISNULL(CAST([PickedByPersonID] AS VARCHAR(4)), '') + ' | ' + CAST(s.[Fullnamn] SOM VARCHAR(20)) + ' | ' + ISNULL(CAST([BackorderID] AS VARCHAR(4)), '') + ' | ' + CAST([OrderDate] AS VARCHAR(20)) + ' | ' + CAST([Förväntat leveransdatum] SOM VARCHAR(20)) + ' | ' + CAST([Kundinköpsordernummer] SOM VARCHAR(10)) + ' | ' + CAST([IsUndersupplyBackordered] AS VARCHAR(4)) + ' | ' + ISNULL(CAST([Kommentarer] SOM VARCHAR(50)), '') + ' | ' + ISNULL(CAST([Leveransinstruktioner] SOM VARCHAR(50)), '') + ' | ' + ISNULL(CAST([Interna kommentarer] SOM VARCHAR(50)), '') + ' | ' + CAST([PickingCompletedWhen] AS VARCHAR(20)) + ' | ' + CAST(o.[Sist redigerad av] SOM VARCHAR(4)) + ' | ' + CAST([LastEditedWhen] AS VARCHAR(20)) AS Row FROM [WideWorldImporters].[Sales].[Order] o INNER JOIN [Försäljning].[Kunder] c PÅ o.[Kund-ID] =c.[Kund-ID] INNER JOIN [Ansökan].[People] p ON o.[SäljarePersonID] =p.[PersonID] VAR OrderDatum MELLAN @MonthStartDate OCH @MonthEndDate
Kod för att exportera data till en platt fil
Skapa mappen om den inte finns med SQL xp_create_subdir
DECLARE @sql VARCHAR(8000) ,@FilePath VARCHAR(200) ,@Query VARCHAR(100) DECLARE @file_results TABLE ( file_exists INT ,file_is_a_directory INT ,parent_directory_exists @FolderPath SET @FolderPath SET INT ) (@Year AS VARCHAR(10)) + '\' + CAST(@Month AS VARCHAR(10)) + '\' INSERT INTO @file_results EXEC MASTER.dbo.xp_fileexist @FolderPath OM INTE FINNS (VÄLJ 1 FRÅN @file_results WHERE_results file_is_a_directory =1 ) EXEC MASTER.dbo.xp_create_subdir @FolderPath
Skapar filen i den delade mappen
SET @FilePath ='"' + @FolderPath + '' + 'Orders_Monthly' + '_' + ( SELECT Format(GETDATE(), N'yyyyMMddHHmmss') ) + '.txt"' SET @Query =' "SELECT * from ' + ( SELECT DB_NAME() ) + '.dbo.Orders_Monthly_Temp_Table"' DECLARE @exe_path10 VARCHAR(200) =' cd C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130 &' SELECT @ sql =@exe_path10 + ' bcp.exe ' + @Query + ' queryout ' + @FilePath + ' -T -c -q -t0x7c -r\n ' --+ @@servernamn EXEC master..xp_cmdshell @sql AVSLUTA FÖRSÖK BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber ,ERROR_STATE() AS ErrorState ,ERROR_SEVERITY() AS ErrorSeverity ,ERROR_PROCEDURE() AS ErrorProcedure ,ERROR_LINE() AS ErrorLine ,ERROR_MESSAGEs()Sage; SLUT FÅNGST SET NOCOUNT AV;END
Ändra din katalogkontext till mappen där BPC Utility finns
[tabell id=58 /]
Utför proceduren
DECLARE @return_value intEXEC @return_value =[dbo].[Exp_Orders_Monthly_Report] @Month =NULL, @Year =NULL, @FolderPath =NULLSELECT 'Returvärde' =@return_valueGO
Utdata
Destinationsmapp
Faktisk platt fil (.txt/.cvs)
Delad mapp bör ha behörighet till virtuellt konto "NT SERVICE\MSSQLSERVER"
Högerklicka på filen eller mappen du vill ställa in behörigheter → Klicka på Egenskaper → Klicka på fliken Säkerhet. → Klicka på Redigera → Klicka på Lägg till → Skriv NT SERVICE\MSSQLSERVER i objektnamnsrutan. (klicka inte på "Kontrollera namn" – om du klickar på Kontrollera namn kan det hända att du får felmeddelandet "Ett objekt med namnet "NT SERVICE\MSSQLSERVER" kan inte hittas.) → Klicka på OK → välj MSSQLSERVER-kontot → Lägg till behörigheter ( Full kontroll) som behövs för MSSQLSERVER-kontot:
Aktivera 'xp_cmdshell' SQL Server
EXEC sp_configure 'visa avancerade alternativ', 1GORECONFIGUREGOEXEC sp_configure 'xp_cmdshell', 1GORECONFIGUREGO
Hur man importerar data från platt fil
I det här exemplet använder vi Bulk Insert för att importera data från filen. Vi kan också använda Openrowset etc.
Skapa en lagrad procedur för att importera data från en platt fil i den delade mappen.
Skapa först de beroende objekten för importlagrade proceduren.
Så vi måste skapa följande tabeller
- The Orders_Monthly tabell:denna tabell används för att lagra månadsbeställningsdata från den platta filen.
- Import_Config tabell: den här tabellen används för att lagra importkonfigurationer, t.ex. sökväg för delad mapp, platt filtyp, avgränsare.
SKAPA TABELL [dbo].[Order_Monthly]( [OrderID] [int] NOT NULL, [CustomerName] [varchar](50) NOT NULL, [SäljarePersonName] [varchar](50) NOT NULL, [PickedByPersonName] [ varchar](50) NULL, [ContactPersonName] [varchar](50) NOT NULL, [Backorder OrderID] [varchar](4) NULL, [OrderDate] [date] NOT NULL, [ExpectedDeliveryDate] [date] NOT NULL, [CustomerPurchaseOrderN ] [nvarchar](20) NULL, [IsUndersupplyBackordered] [bit] NOT NULL, [Comments] [nvarchar](max) NULL, [DeliveryInstructions] [nvarchar](max) NULL, [InternalComments] [nvarchar](max) NULL , [PickingCompletedWhen] [datetime2](7) NULL, [LastEditedBy] [int] NOT NULL, [LastEditedWhen] [datetime2](7) NOT NULL, CONSTRAINT [PK_Orders_Monthly] PRIMÄRNYCKEL CLUSTERED ([OrderID =] ASC_)WILD AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [USERDATA]) PÅ [USERDATA] TEXTIMAGE_ON [USERDATA]GO
SKAPA TABELL [dbo].[Import_Config]( [Exp_Id] [int] IDENTITY(1,1) NOT NULL, [ShareFolder] [nchar](200) NOT NULL, [FileType] [varchar](5) NOT NULL, [Delimiter] [char](1) NOT NULL) PÅ [USERDATA]GO
Infoga data i Import_Config
SET IDENTITY_INSERT [dbo].[Import_Config] ON GOINSERT [dbo].[Import_Config] ([Exp_Id], [ShareFolder], [FileType], [Delimiter]) VÄRDEN (1, N'\\AASHREEPC\FileServer\ OrdersMonthly', N'.txt', N'|')GOSET IDENTITY_INSERT [dbo].[Import_Config] OFFGO
Skapa lagrad procedur och parametrar
Samma som i export lagrad procedur.
SKAPA PROCEDUR [dbo].[Imp_Orders_Monthly_Report] @Month INT =NULL ,@Year INT =NULL ,@FolderPath VARCHAR(200) =NULLAS BEGIN SET NOCOUNT ON; BÖRJA FÖRSÖKHämta konfigurationen från importtabellenDECLARE @ImportPath VARCHAR(200) ,@Delimiter CHAR(1) ,@FileType VARCHAR(5) ,@FilePath VARCHAR(200) SELECT @ImportPath =TRIM(ShareFolder) ,@TRIMtFiyplee ) ,@Delimiter =TRIM(Delimiter) FRÅN dbo.Import_Config
Parametervalidering
Samma som i export lagrad procedur.
SET @FolderPath =@ImportPath + '\' + CAST(@Year AS VARCHAR(10)) + '\' + CAST(@Month AS VARCHAR(10)) + '\' END ELSE BEGIN --SELECT @ FolderPath ='\\AASHREEPC\FileServer\OrdersMonthly' VÄLJ 'ERROR FolderPath måste anges.' LÄMNA TILLBAKA; END END --#endregion Validering av parametrar
Kontrollera om filen finns eller inte
SKAPA TABELL #Fil (Filnamn SYSNAME ,Djup TINYINT ,IsFile TINYINT ); INSERT INTO #File ( Filnamn ,Djup ,IsFile ) EXEC xp_DirTree @FolderPath ,1 ,1 VÄLJ TOP 1 @FilePath =@FolderPath + '\' + Filnamn FRÅN #Fil ORDER BY FileName DESC; IF NULLIF((VÄLJ TOP 1 Filnamn FRÅN #Fil ORDNING EFTER Filnamn DESC), '') IS NULL BEGIN VÄLJ 'FEL importfilen finns inte' RETURN; END DROP TABLE #FileImportera data från den delade mappen med Bulk InsertDECLARE @SQL_BULK VARCHAR(MAX) DecLare @Errorlog varchar (Max) =@FolderPath + '\Error.log' SET @SQL_BULK ='BULK INSERT [Orders_'Monthly] FROM 'Monthly] ' + @FilePath + ''' WITH ( DATAFILETYPE =''char'' ,BATCHSIZE =50000 ,CODEPAGE =''RAW'' ,FIRSTROW =1 ,FIELDTERMINATOR ='''[email protected]+''' =,ROWTERMINATOR ''\n'' ,KEEPNULLS ,ERRORFILE ='''+ @Errorlog + ''' ,MAXERRORS =20000 ,TABLOCK )' EXEC (@SQL_BULK)ÄND FÖRSÖK BÖRJA FÅNGA VÄLJ ERROR_NUMBER() SOM ErrorNumber()ERror_Error_Number ,ERROR_SEVERITY() AS ErrorSeverity ,ERROR_PROCEDURE() AS ErrorProcedure ,ERROR_LINE() AS ErrorLine ,ERROR_MESSAGE() AS Err ellerMeddelande; SLUT FÅNGST SET NOCOUNT AV;END
Utför proceduren
DECLARE @return_value intEXEC @return_value =[dbo].[Imp_Orders_Monthly_Report] @Month =NULL, @Year =NULL, @FolderPath =NULL VÄLJ 'Returvärde' =@return_valueGO
Utdata
Verifiering
Automatisera processen:
För att köra export- och importprocessen automatiskt på en schemalagd tid. låt oss säga att vi måste köra exporten den första dagen i månaden kl. 12.00 i månaden för den senaste månadsrapporten och köra importen senare. Så vi måste skapa SQL-jobbet för det.
Steg för att skapa SQL-jobbet för export och import.
- Öppna MS SQL Server Management Studio →
- och du bör ha "SQL Server Agent" →
- Utöka "SQL Server Agent" i Object Explorer. →
- Högerklicka på JOBB och välj "Nytt jobb..." →
- Du kan se fönstret "Nytt jobb" och ange namnet ="Order_Monthly_Export" &Beskrivning
Gå sedan till fliken Steg → Klicka på Ny knapp längst ner → ett nytt fönster för jobbsteg öppnas → Ange namnet ="exekvera [Exp_Orders_Monthly_Report] SP" och skriv ="Transact-SQL Script (T-SQL)" → Klistra in följande skript i kommandotextområdet och klicka på OK.
ANVÄND [WideWorldImporters]GODECLARE @return_value int+EXEC @return_value =[dbo].[Exp_Orders_Monthly_Report] @Month =NULL, @Year =NULL, @FolderPath =NULLSELECT =Return
Gå sedan till fliken Schema → Klicka på Ny knapp längst ned → ett nytt schema för jobb öppnas. Ange namnet ="Beställ månadsschema" och ange följande detaljer och klicka på OK → Återigen Klicka på OK i fönstret Nytt jobb.
Jobbet skulle skapas framgångsrikt.
Testa SQL-jobbet:
Ta bort alla filer i den delade mappen för testning.
För att köra jobbet manuellt för testning:Högerklicka på det nyskapade jobbet → Klicka på "Starta jobb i steg..." så kan vi se jobbet körs
Vi kan se att filen skapas i den delade mappen.
Obs! Följ stegen ovan för att skapa SQL-jobbet (Orders_Monthly_Import) för import också.
Jag hoppas att du nu har en bättre förståelse för hur du använder BCP-verktyget.
Användbart verktyg:
dbForge Data Pump – ett SSMS-tillägg för att fylla SQL-databaser med externa källdata och migrera data mellan system.