Database
 sql >> Baza danych >  >> RDS >> Database

Jak eksportować dane do płaskiego pliku za pomocą narzędzia BCP i importować dane za pomocą wstawiania zbiorczego?

Narzędzie BCP (Bulk Copy Program) w SQL Server umożliwia administratorom baz danych importowanie danych do tabeli i eksportowanie danych z tabeli do zwykłego pliku. Narzędzie BCP obsługuje również różne funkcje, które ułatwiają proces eksportowania i importowania danych zbiorczych.

Teraz zacznijmy od scenariusza biznesowego.

Scenariusz biznesowy

Załóżmy, że musimy udostępnić klientowi miesięczny raport w określonym formacie w zabezpieczonej udostępnionej lokalizacji, takiej jak SFTS, tj. na początku każdego miesiąca musimy wysłać klientowi plik za poprzedni miesiąc. W tym scenariuszu spróbujemy utworzyć procedurę składowaną w celu wygenerowania danych i wyeksportowania tych danych do zwykłego pliku (.txt lub .csv).

Jak importować i eksportować dane SQL?

Można to zrobić na kilka sposobów:

  • Używając SSMS, uruchom zapytanie w oknie zapytania i eksportuj lub kreatora importu i eksportu SQL Server.
  • Korzystanie z SSIS – tworzenie pakietu przy użyciu SSDT.
  • Korzystanie z usług SSRS.
  • Korzystanie z C# – Utwórz konsolę lub wygraj aplikację do wyeksportowania.
  • Narzędzie BCP.
  • itd.

Co to jest narzędzie BCP?

Narzędzie BCP (program do kopiowania zbiorczego) to narzędzie wiersza poleceń do kopiowania danych między instancją MS SQL Server a plikiem danych w formacie określonym przez użytkownika. Możemy szybko i łatwo eksportować i importować duże ilości danych do i z baz danych SQL Server.

Narzędzie BCP wykonuje następujące zadania:

  • Zbiorczy eksport danych z tabeli SQL Server do pliku danych.
  • Zbiorczy eksport danych z zapytania/procedury przechowywanej.
  • Zbiorczy import danych z pliku danych do tabeli SQL Server.
  • Generowanie plików formatu.

Więcej informacji na temat narzędzia BCP można znaleźć tutaj.

Wykorzystane środowisko

  • SQL Server 2017 Developer Edition
  • SQL Server 2017 Studio zarządzania
  • Przykładowa baza danych Importerów z całego świata v1.0
  • Narzędzie BCP

Jak wyeksportować dane do pliku płaskiego

Utwórz procedurę składowaną, aby wygenerować miesięczne dane raportu.

Najpierw utwórz obiekty zależne dla procedury zapisanej eksportu.

Musimy więc stworzyć następujące tabele:

  • Tabela_zamówień_miesięcznych_temperaturowych table:ta tymczasowa tabela służy do przechowywania miesięcznych danych zamówień w określonym formacie w celu wyeksportowania ich do pliku tekstowego, tj. w naszym przypadku łączenia wszystkich kolumn w jeden wiersz z ogranicznikiem „|”.
  • Eksportuj_konfigurację table:ta tabela służy do przechowywania konfiguracji eksportu, tj. ścieżki folderu współdzielonego, typu pliku płaskiego, ogranicznika.

Utwórz skrypt dla Orders_Monthly_Temp_Table

CREATE TABLE [dbo].[Orders_Monthly_Temp_Table](
    [Row] [varchar](200) NOT NULL
) ON [PRIMARY]

Utwórz skrypt dla Export_Config

CREATE TABLE [dbo].[Export_Config](
    [Exp_Id] [int] IDENTITY(1,1) NOT NULL,
    [ShareFolder] [varchar](200) NOT NULL,
    [FileType] [varchar](5) NOT NULL,
    [Delimiter] [char](1) NOT NULL,

 CONSTRAINT [PK_Export_Config] PRIMARY KEY CLUSTERED 
(
    [Exp_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [USERDATA]
) ON [USERDATA]
GO

Wstaw dane do Export_Config

SET IDENTITY_INSERT [dbo].[Export_Config] ON 
GO
INSERT [dbo].[Export_Config] ([Exp_Id], [ShareFolder], [FileType], [Delimiter]) VALUES (1, N'\\AASHREEPC\FileServer\OrdersMonthly', N'.txt', N'|')
GO
SET IDENTITY_INSERT [dbo].[Export_Config] OFF
GO

Tworzenie i parametry procedury składowanej

  • Tutaj parametry roku i miesiąca są opcjonalne.
  • Jeśli miesiąc nie jest określony, zajmuje on poprzedni miesiąc, a jeśli miesiąc to 12, musimy wziąć poprzedni rok, ponieważ jeśli generujemy raport w styczniu 2019 r. za grudzień 2018 r.
  • Jeśli nie określono roku, przyjmuje się rok bieżący, a ścieżka folderu jest obowiązkowa.
CREATE PROCEDURE [dbo].[Orders_Monthly_Report] 
    @Month INT = NULL
    ,@Year INT = NULL
    ,@FolderPath VARCHAR(200) 
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY

Weryfikacja parametrów

--#region Parametes validation
        IF NULLIF(@Month, '') IS NULL 
        BEGIN
            SELECT @Month = DATEPART(mm, DATEADD(month, - 1, GETDATE()))

            IF (@Month = 12) –
            BEGIN
                SELECT @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'
            SELECT 'ERROR FolderPath must be specified.'
            RETURN;
        END        
--#endregion Parameters validation

Pobierz konfigurację z tabeli eksportu

DECLARE @ExportPath VARCHAR(200)
            ,@Delimiter CHAR(1)
            ,@FileType VARCHAR(5)

        SELECT @ExportPath = TRIM(ShareFolder)
            ,@FileType = TRIM(FileType)
            ,@Delimiter = TRIM(Delimiter)
        FROM dbo.Export_Config

Pobieranie daty rozpoczęcia i zakończenia miesiąca

DECLARE @MonthStartDate DATETIME = DATEADD(month, @Month - 1, DATEADD(year, @Year - 1900, 0))
            ,@MonthEndDate DATETIME = DATEADD(day, - 1, DATEADD(month, @Month, DATEADD(year, @Year - 1900, 0)))

Check and Create the temporary table for report data/result
IF NOT EXISTS (
                SELECT *
                FROM sys.objects
                WHERE object_id = OBJECT_ID(N'[dbo].[Orders_Monthly_Temp_Table]')
                    AND type IN (N'U')
                )
        BEGIN
            CREATE TABLE [dbo].Orders_Monthly_Temp_Table ([Row] [varchar](200) NOT NULL) ON [PRIMARY]
        END

Wstaw dane do tabeli tymczasowej w określonym formacie, tj. w tym przypadku „| – symbol rury oddzielony”

TRUNCATE TABLE Orders_Monthly_Temp_Table
INSERT INTO Orders_Monthly_Temp_Table
        SELECT CAST([OrderID] AS VARCHAR(10)) + ' | ' + CAST(c.[CustomerName] AS VARCHAR(50)) + ' | ' + CAST(p.[FullName] AS VARCHAR(50)) + ' | ' + ISNULL(CAST([PickedByPersonID] AS VARCHAR(4)), '') + ' | ' + CAST(p.[FullName] AS VARCHAR(20)) + ' | ' + ISNULL(CAST([BackorderOrderID] AS VARCHAR(4)), '') + ' | ' + CAST([OrderDate] AS VARCHAR(20)) + ' | ' + CAST([ExpectedDeliveryDate] AS VARCHAR(20)) + ' | ' + CAST([CustomerPurchaseOrderNumber] AS VARCHAR(10)) + ' | ' + CAST([IsUndersupplyBackordered] AS VARCHAR(4)) + ' | ' + ISNULL(CAST([Comments] AS VARCHAR(50)), '') + ' | ' + ISNULL(CAST([DeliveryInstructions] AS VARCHAR(50)), '') + ' | ' + ISNULL(CAST([InternalComments] AS VARCHAR(50)), '') + ' | ' + CAST([PickingCompletedWhen] AS VARCHAR(20)) + ' | ' + CAST(o.[LastEditedBy] AS VARCHAR(4)) + ' | ' + CAST([LastEditedWhen] AS VARCHAR(20)) AS Row
        FROM [WideWorldImporters].[Sales].[Orders] o
        INNER JOIN [Sales].[Customers] c ON o.[CustomerID] = c.[CustomerID]
        INNER JOIN [Application].[People] p ON o.[SalespersonPersonID] = p.[PersonID]
        WHERE OrderDate BETWEEN @MonthStartDate
                AND @MonthEndDate

Kod eksportu danych do pliku płaskiego

Utwórz folder, jeśli nie istnieje, używając 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 INT
            )

        SET @FolderPath = @FolderPath + '\' + CAST(@Year AS VARCHAR(10)) + '\' + CAST(@Month AS VARCHAR(10)) + '\'

        INSERT INTO @file_results
        EXEC MASTER.dbo.xp_fileexist @FolderPath

        IF NOT EXISTS (
                SELECT 1
                FROM @file_results
                WHERE file_is_a_directory = 1
                )
            EXEC MASTER.dbo.xp_create_subdir @FolderPath

Tworzenie pliku w udostępnionym folderze

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 ' --+ @@servername

        EXEC master..xp_cmdshell @sql
    END TRY

    BEGIN CATCH
        SELECT ERROR_NUMBER() AS ErrorNumber
            ,ERROR_STATE() AS ErrorState
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage;
    END CATCH

    SET NOCOUNT OFF;
END

Zmień kontekst katalogu na folder, w którym znajduje się narzędzie BPC

[identyfikator tabeli=58 /]

Wykonywanie procedury

DECLARE    @return_value int
EXEC    @return_value = [dbo].[Exp_Orders_Monthly_Report]
        @Month = NULL,
        @Year = NULL,
        @FolderPath = NULL
SELECT    'Return Value' = @return_value
GO

Wyjście

Folder docelowy

Rzeczywisty plik płaski (.txt/.cvs)

Udostępniony folder powinien mieć uprawnienia do konta wirtualnego „NT SERVICE\MSSQLSERVER”

Kliknij prawym przyciskiem myszy plik lub folder, dla którego chcesz ustawić uprawnienia → Kliknij Właściwości → Kliknij kartę Zabezpieczenia. → Kliknij Edytuj → Kliknij Dodaj → Wpisz NT SERVICE\MSSQLSERVER w polu nazwy obiektu. (nie klikaj „Sprawdź nazwy” – jeśli klikniesz Sprawdź nazwy może się zdarzyć, że pojawi się błąd „Nie można znaleźć obiektu o nazwie „NT SERVICE\MSSQLSERVER”.) → Kliknij OK → wybierz konto MSSQLSERVER → Dodaj uprawnienia ( Pełna kontrola), które są potrzebne do konta MSSQLSERVER:

Włącz serwer SQL „xp_cmdshell”

EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO

Jak importować dane z pliku płaskiego

W tym przykładzie używamy Wstaw zbiorczy do importowania danych z pliku. Możemy również użyć Openrowset itp.

Utwórz procedurę składowaną, aby zaimportować dane z pliku płaskiego w folderze Udostępnionym.

Najpierw utwórz obiekty zależne dla procedury przechowywanej importu.

Musimy więc stworzyć następujące tabele

  • Zamówienia_Miesięczne table:ta tabela służy do przechowywania miesięcznych danych zamówień z pliku płaskiego.
  • Karta Importuj_konfigurację tabela: ta tabela służy do przechowywania konfiguracji importu, tj. ścieżki folderu współdzielonego, typu pliku płaskiego, ogranicznika.

CREATE TABLE [dbo].[Orders_Monthly](
    [OrderID] [int] NOT NULL,
    [CustomerName] [varchar](50) NOT NULL,
    [SalespersonPersonName] [varchar](50) NOT NULL,
    [PickedByPersonName] [varchar](50) NULL,
    [ContactPersonName] [varchar](50) NOT NULL,
    [BackorderOrderID] [varchar](4) NULL,
    [OrderDate] [date] NOT NULL,
    [ExpectedDeliveryDate] [date] NOT NULL,
    [CustomerPurchaseOrderNumber] [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] PRIMARY KEY CLUSTERED 
(
    [OrderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [USERDATA]
) ON [USERDATA] TEXTIMAGE_ON [USERDATA]
GO

CREATE TABLE [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
) ON [USERDATA]
GO

Wstaw dane do Import_Config

SET IDENTITY_INSERT [dbo].[Import_Config] ON 
GO
INSERT [dbo].[Import_Config] ([Exp_Id], [ShareFolder], [FileType], [Delimiter]) VALUES (1, N'\\AASHREEPC\FileServer\OrdersMonthly', N'.txt', N'|')
GO
SET IDENTITY_INSERT [dbo].[Import_Config] OFF
GO

Tworzenie i parametry procedury składowanej

Tak samo jak w przypadku procedury przechowywanej eksportu.

CREATE PROCEDURE [dbo].[Imp_Orders_Monthly_Report] @Month INT = NULL
    ,@Year INT = NULL
    ,@FolderPath VARCHAR(200) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    BEGIN TRY
Get the configuration from the import table
DECLARE @ImportPath VARCHAR(200)
            ,@Delimiter CHAR(1)
            ,@FileType VARCHAR(5)
            ,@FilePath VARCHAR(200)

        SELECT @ImportPath = TRIM(ShareFolder)
            ,@FileType = TRIM(FileType)
            ,@Delimiter = TRIM(Delimiter)
        FROM dbo.Import_Config

Weryfikacja parametrów

Tak samo jak w przypadku procedury przechowywanej eksportu.

SET @FolderPath = @ImportPath + '\' + CAST(@Year AS VARCHAR(10)) + '\' + CAST(@Month AS VARCHAR(10)) + '\'
            END
            ELSE
            BEGIN
                --SELECT @FolderPath = '\\AASHREEPC\FileServer\OrdersMonthly'
                SELECT 'ERROR FolderPath must be specified.'

                RETURN;
            END
        END

        --#endregion Parametes validation

Sprawdź, czy plik istnieje, czy nie

CREATE TABLE #File (
            FileName SYSNAME
            ,Depth TINYINT
            ,IsFile TINYINT
            );

        INSERT INTO #File (
            FileName
            ,Depth
            ,IsFile
            )
        EXEC xp_DirTree @FolderPath
            ,1
            ,1

        SELECT TOP 1 @FilePath = @FolderPath + '\' + FileName
        FROM #File
        ORDER BY FileName DESC;
        
        IF NULLIF((SELECT TOP 1 FileName FROM #File ORDER BY FileName DESC), '') IS NULL
        BEGIN
                SELECT 'ERROR import File does not exists'
                RETURN;
        END

        DROP TABLE #File
Import the data from the shared folder using Bulk Insert
DECLARE @SQL_BULK VARCHAR(MAX)
        DecLare @Errorlog varchar (Max) = @FolderPath + '\Error.log'
        SET @SQL_BULK = 'BULK
            INSERT [Orders_Monthly]
            FROM ''' + @FilePath + '''
            WITH
            (
                DATAFILETYPE = ''char''
                ,BATCHSIZE = 50000
                ,CODEPAGE = ''RAW''
                ,FIRSTROW = 1
                ,FIELDTERMINATOR = '''[email protected]+'''
                ,ROWTERMINATOR = ''\n''
                ,KEEPNULLS
                ,ERRORFILE = '''+ @Errorlog + '''
                ,MAXERRORS = 20000
                ,TABLOCK
                )'

            EXEC (@SQL_BULK)
END TRY

    BEGIN CATCH
        SELECT ERROR_NUMBER() AS ErrorNumber
            ,ERROR_STATE() AS ErrorState
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage;
    END CATCH

    SET NOCOUNT OFF;
END

Wykonywanie procedury

DECLARE    @return_value int
EXEC    @return_value = [dbo].[Imp_Orders_Monthly_Report]
        @Month = NULL,
        @Year = NULL,
        @FolderPath = NULL
    SELECT    'Return Value' = @return_value
GO

Wyjście

Weryfikacja

Automatyzacja procesu:

Do automatycznego uruchamiania procesu eksportu i importu w zaplanowanym czasie. powiedzmy, że musimy uruchomić eksport pierwszego dnia miesiąca o godzinie 12:00 miesiąca dla raportu z ostatniego miesiąca, a import uruchomić później. W tym celu musimy stworzyć zadanie SQL.

Kroki tworzenia zadania SQL do eksportu i importu.

  • Otwórz MS SQL Server Management Studio →
  • i powinieneś mieć „SQL Server Agent” →
  • Rozwiń „SQL Server Agent” w Eksploratorze obiektów. →
  • Kliknij prawym przyciskiem myszy ZADANIE i wybierz „Nowe zadanie…” →
  • Możesz zobaczyć okno „Nowa oferta pracy” i wprowadzić nazwę =„Orders_Monthly_Export” &opis

Następnie przejdź do zakładki Steps → Kliknij New Button na dole → otworzy się nowe okno Job Steps → Wpisz Name =„wykonaj [Exp_Orders_Monthly_Report] SP” i wpisz =„Transact-SQL Script (T-SQL)” → Wklej następujący skrypt w polu tekstowym polecenia i kliknij OK.

USE [WideWorldImporters]
GO
DECLARE    @return_value int+
EXEC    @return_value = [dbo].[Exp_Orders_Monthly_Report]
        @Month = NULL,
        @Year = NULL,
        @FolderPath = NULL
SELECT    'Return Value' = @return_value
GO

Następnie przejdź do zakładki Harmonogram → Kliknij przycisk Nowy na dole → otworzy się okno Harmonogram nowego zadania. Wprowadź Nazwę =„Zamów Miesięczny Harmonogram” i wprowadź następujące dane, a następnie kliknij OK → Ponownie kliknij OK w oknie Nowa praca.

Praca zostanie pomyślnie utworzona.

Przetestuj zadanie SQL:

Usuń wszystkie pliki w folderze Shared do testowania.

Aby ręcznie uruchomić zadanie w celu przetestowania:Kliknij prawym przyciskiem myszy Nowo utworzone zadanie → Kliknij „Rozpocznij zadanie w kroku…” i zobaczymy uruchomione zadanie

Widzimy, że plik jest tworzony w folderze Shared.

Uwaga:Postępuj zgodnie z powyższymi krokami, aby utworzyć zadanie SQL (Orders_Monthly_Import) również do importu.

Mam nadzieję, że teraz lepiej rozumiesz, jak korzystać z narzędzia BCP.

Przydatne narzędzie:

dbForge Data Pump – dodatek SSMS do wypełniania baz danych SQL zewnętrznymi danymi źródłowymi i migracji danych między systemami.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. T-SQL Wtorek #65:Naucz czegoś nowego

  2. Poznaj podstawy rejestrowania w Javie

  3. 7 kluczowych rzeczy do zapamiętania o globalizacji modelu danych

  4. Jak wybrać odpowiednie typy danych

  5. Połączone serwery Salesforce.com i sp_columns_ex