Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Cách xuất dữ liệu sang tệp phẳng với BCP Utility và nhập dữ liệu với chèn hàng loạt

Tiện ích BCP (Bulk Copy Program) trong SQL Server cho phép quản trị viên cơ sở dữ liệu nhập dữ liệu vào bảng và xuất dữ liệu từ bảng thành một tệp phẳng. Tiện ích BCP cũng hỗ trợ các tính năng khác nhau tạo điều kiện thuận lợi cho quá trình xuất và nhập dữ liệu hàng loạt.

Bây giờ hãy bắt đầu với một kịch bản kinh doanh.

Tình huống kinh doanh

Giả sử, chúng tôi cần chia sẻ báo cáo hàng tháng ở định dạng cụ thể cho khách hàng ở một vị trí được chia sẻ an toàn như SFTS, tức là vào đầu mỗi tháng, chúng tôi cần gửi tệp cho khách hàng của tháng trước. Trong trường hợp này, chúng tôi sẽ cố gắng tạo quy trình được lưu trữ để tạo dữ liệu và xuất dữ liệu đó sang tệp phẳng (.txt hoặc .csv).

Làm cách nào để nhập và xuất dữ liệu SQL?

Có một số cách để thực hiện việc này:

  • Sử dụng SSMS, Chạy Truy vấn trong cửa sổ Truy vấn và xuất hoặc trình hướng dẫn nhập và xuất SQL Server.
  • Sử dụng SSIS - Tạo gói bằng SSDT.
  • Sử dụng SSRS.
  • Sử dụng C # - Tạo bảng điều khiển hoặc giành ứng dụng để xuất.
  • Tiện ích BCP.
  • v.v.

BCP Utility là gì?

Tiện ích BCP (Chương trình sao chép hàng loạt) là một tiện ích dòng lệnh để sao chép dữ liệu giữa một phiên bản của MS SQL Server và một tệp dữ liệu ở định dạng do người dùng chỉ định. Chúng tôi có thể xuất và nhập một lượng lớn dữ liệu vào và ra khỏi cơ sở dữ liệu SQL Server một cách nhanh chóng và dễ dàng.

Tiện ích BCP thực hiện các tác vụ sau:

  • Xuất dữ liệu hàng loạt từ bảng SQL Server thành tệp dữ liệu.
  • Xuất dữ liệu hàng loạt từ một truy vấn / Thủ tục đã lưu trữ.
  • Nhập dữ liệu hàng loạt từ tệp dữ liệu vào bảng SQL Server.
  • Tạo các tệp định dạng.

Bạn có thể tìm thêm thông tin chi tiết về BCP Utility tại đây.

Môi trường được sử dụng

  • Phiên bản dành cho nhà phát triển SQL Server 2017
  • Phòng thu quản lý SQL server 2017
  • Cơ sở dữ liệu mẫu của Wide World Importers v1.0
  • Tiện ích BCP

Cách xuất dữ liệu sang tệp phẳng

Tạo quy trình đã lưu trữ để tạo dữ liệu báo cáo hàng tháng.

Đầu tiên, tạo các đối tượng phụ thuộc cho thủ tục đã lưu trữ xuất.

Vì vậy, chúng ta phải tạo các bảng sau:

  • Đơn hàng_Monthly_Temp_Table table:bảng tạm thời này được sử dụng để lưu trữ dữ liệu đơn đặt hàng hàng tháng ở một định dạng cụ thể để xuất dữ liệu đó sang tệp văn bản, tức là trong trường hợp của chúng tôi, nối tất cả các cột thành một hàng bằng dấu phân cách “|”.
  • Export_Config table:bảng này được sử dụng để lưu trữ các cấu hình xuất, tức là đường dẫn thư mục được chia sẻ, loại tệp phẳng, dấu phân cách.

Tạo tập lệnh cho Order_Monthly_Temp_Table

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

Tạo tập lệnh cho 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

Chèn dữ liệu vào 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

Tạo và tham số thủ tục đã lưu trữ

  • Đây là thông số năm và tháng là tùy chọn.
  • Nếu một tháng không được chỉ định, thì sẽ lấy tháng trước và nếu tháng là 12, chúng tôi phải lấy năm trước vì nếu chúng tôi tạo báo cáo vào tháng 11 năm 2019 cho tháng 12 năm 2018.
  • Nếu một năm không được chỉ định, thì đó sẽ là năm hiện tại và Đường dẫn thư mục là Bắt buộc.
CREATE PROCEDURE [dbo].[Orders_Monthly_Report] 
    @Month INT = NULL
    ,@Year INT = NULL
    ,@FolderPath VARCHAR(200) 
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY

Xác thực thông số

--#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

Lấy cấu hình từ bảng xuất

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

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

Lấy ngày bắt đầu và ngày kết thúc của tháng

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

Chèn dữ liệu vào bảng tạm ở định dạng cụ thể, tức là trong trường hợp này là “| - ký hiệu đường ống được phân tách ”

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

Mã để xuất dữ liệu sang tệp phẳng

Tạo thư mục nếu không tồn tại Sử dụng 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

Tạo tệp trong thư mục chia sẻ

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

Thay đổi ngữ cảnh thư mục của bạn thành thư mục chứa Tiện ích BPC

[id bảng =58 /]

Thực hiện quy trình

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

Đầu ra

Thư mục đích

Tệp phẳng thực tế (.txt / .cvs)

Thư mục được chia sẻ phải có Quyền đối với Tài khoản Ảo “NT SERVICE \ MSSQLSERVER”

Nhấp chuột phải vào tệp hoặc thư mục bạn muốn đặt quyền → Nhấp vào Thuộc tính → Nhấp vào tab Bảo mật. → Nhấp vào Chỉnh sửa → Nhấp vào Thêm → Nhập NT SERVICE \ MSSQLSERVER vào hộp tên đối tượng. (không nhấp vào “Kiểm tra tên” - nếu bạn nhấp vào Kiểm tra tên, bạn có thể gặp lỗi 'Không thể tìm thấy đối tượng có tên “NT SERVICE \ MSSQLSERVER”.) → Nhấp vào OK → chọn tài khoản MSSQLSERVER → Thêm quyền ( Toàn quyền kiểm soát) cần thiết cho tài khoản MSSQLSERVER:

Bật SQL Server ‘xp_cmdshell’

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

Cách nhập dữ liệu từ tệp phẳng

Trong ví dụ này, chúng tôi đang sử dụng Chèn hàng loạt để nhập dữ liệu từ tệp. Chúng tôi cũng có thể sử dụng Openrowset, v.v.

Tạo quy trình đã lưu trữ để Nhập dữ liệu từ tệp phẳng trong thư mục Chia sẻ.

Đầu tiên, tạo các đối tượng phụ thuộc cho thủ tục đã lưu trữ nhập.

Vì vậy, chúng ta phải tạo các bảng sau

  • Đơn đặt hàng_ Hàng tháng table:bảng này được sử dụng để lưu trữ dữ liệu đơn hàng hàng tháng từ tệp phẳng.
  • Import_Config bảng : bảng này được sử dụng để lưu trữ các cấu hình nhập, tức là đường dẫn thư mục chia sẻ, loại tệp phẳng, dấu phân cách.

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

Chèn dữ liệu vào 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

Tạo và tham số thủ tục đã lưu trữ

Tương tự như trong quy trình xuất Lưu trữ.

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

Xác thực thông số

Tương tự như trong quy trình xuất Lưu trữ.

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

Kiểm tra xem tệp có tồn tại hay không

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

Thực hiện quy trình

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

Đầu ra

Xác minh

Tự động hóa quy trình:

Để chạy quá trình xuất và nhập tự động theo thời gian đã định. giả sử chúng tôi cần chạy xuất vào ngày đầu tiên của tháng lúc 12:00 sáng của tháng cho báo cáo tháng trước và chạy nhập sau đó. Vì vậy, chúng ta cần tạo SQL Job cho việc đó.

Các bước tạo Công việc SQL để Xuất và nhập.

  • Mở MS SQL Server Management Studio →
  • và bạn phải có “SQL Server Agent” →
  • Mở rộng “SQL Server Agent” trên Object Explorer. →
  • Nhấp chuột phải vào CÔNG VIỆC và chọn “Công việc mới…” →
  • Bạn có thể thấy cửa sổ “Công việc mới” và nhập tên =“Đơn hàng_Monthly_Xuất” &Mô tả

Sau đó chuyển đến tab Bước → Nhấp vào Nút mới ở dưới cùng → cửa sổ Bước công việc mới mở ra → Nhập Tên =“thực hiện [Exp_Orders_Monthly_Report] SP” và Nhập =“Tập lệnh giao dịch-SQL (T-SQL)” → Dán tập lệnh sau trong vùng văn bản Lệnh và Nhấp vào 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

Sau đó, chuyển đến tab Lịch biểu → Nhấp vào Nút Mới ở dưới cùng → một cửa sổ Lịch trình công việc mới mở ra. Nhập Tên =“Đặt hàng Lịch trình hàng tháng” và nhập các chi tiết sau và Nhấp vào OK → Một lần nữa Nhấp vào OK trong cửa sổ Công việc mới.

Công việc sẽ được tạo thành công.

Kiểm tra Công việc SQL:

Xóa tất cả các tệp trong thư mục Được chia sẻ để thử nghiệm.

Để chạy công việc theo cách thủ công để kiểm tra:Nhấp chuột phải vào Công việc mới được tạo → Nhấp vào ‘Bắt đầu công việc ở bước ..’ và chúng ta có thể thấy công việc đang chạy

Chúng ta có thể thấy tệp được tạo trong thư mục Chia sẻ.

Lưu ý:Vui lòng làm theo các bước trên để tạo công việc SQL (Lệnh_Monthly_Import) cho Nhập.

Tôi hy vọng rằng bây giờ bạn đã hiểu rõ hơn về cách sử dụng tiện ích BCP.

Công cụ hữu ích:

dbForge Data Pump - một phần bổ trợ SSMS để lấp đầy cơ sở dữ liệu SQL với dữ liệu nguồn bên ngoài và di chuyển dữ liệu giữa các hệ thống.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Triển khai một loại tùy chỉnh

  2. Giới thiệu về Thư viện SQL Python

  3. Cách cài đặt Cassandra v3 trên CentOS 6

  4. Mô hình dữ liệu giao hàng tại nhà hàng

  5. Cách tham gia trên nhiều cột