Menggunakan salinan massal dengan driver JDBC

Unduh driver JDBC

Microsoft SQL Server menyertakan utilitas baris perintah populer bernama bcp untuk menyalin file besar secara massal dengan cepat ke dalam tabel atau tampilan di database SQL Server. Kelas ini SQLServerBulkCopy memungkinkan Anda menulis solusi kode di Java yang menyediakan fungsionalitas serupa. Ada cara lain untuk memuat data ke dalam tabel SQL Server (pernyataan INSERT, misalnya) tetapi SQLServerBulkCopy menawarkan keunggulan performa yang signifikan atasnya.

Kelas SQLServerBulkCopy dapat digunakan untuk menulis data hanya ke tabel SQL Server. Tetapi sumber data tidak terbatas pada SQL Server; sumber data apa pun dapat digunakan, selama data dapat dibaca dengan ResultSet, , RowSetatau ISQLServerBulkRecord implementasi.

Dengan menggunakan kelas SQLServerBulkCopy, Anda dapat melakukan:

  • Satu operasi penyalinan massal

  • Beberapa operasi penyalinan massal

  • Operasi penyalinan massal dengan transaksi

Catatan

Saat menggunakan Microsoft JDBC Driver 4.1 untuk SQL Server atau yang lebih lama (yang tidak mendukung kelas SQLServerBulkCopy), Anda dapat menjalankan pernyataan SQL Server Transact-SQL BULK INSERT sebagai gantinya.

Penyiapan contoh penyalinan massal

Kelas SQLServerBulkCopy dapat digunakan untuk menulis data hanya ke tabel SQL Server. Sampel kode yang diperlihatkan dalam artikel ini menggunakan database sampel SQL Server, AdventureWorks. Untuk menghindari perubahan tabel yang ada dalam sampel kode, tulis data ke tabel yang Anda buat terlebih dahulu.

Tabel BulkCopyDemoMatchingColumns dan BulkCopyDemoDifferentColumns keduanya didasarkan pada tabel AdventureWorks Production.Products . Dalam sampel kode yang menggunakan tabel ini, data ditambahkan dari Production.Products tabel ke salah satu tabel sampel ini. Tabel BulkCopyDemoDifferentColumns digunakan saat sampel menggambarkan cara memetakan kolom dari data sumber ke tabel tujuan; BulkCopyDemoMatchingColumns digunakan untuk sebagian besar sampel lainnya.

Beberapa sampel kode menunjukkan cara menggunakan satu kelas SQLServerBulkCopy untuk menulis ke beberapa tabel. Untuk sampel ini, BulkCopyDemoOrderHeader tabel dan BulkCopyDemoOrderDetail digunakan sebagai tabel tujuan. Tabel ini didasarkan pada Sales.SalesOrderHeader tabel dan Sales.SalesOrderDetail di AdventureWorks.

Catatan

Sampel SQLServerBulkCopy kode disediakan untuk menunjukkan sintaksis hanya untuk digunakan SQLServerBulkCopy . Jika tabel sumber dan tujuan terletak di instans SQL Server yang sama, lebih mudah dan lebih cepat untuk menggunakan TRANSACT-SQL INSERT ... Pernyataan SELECT untuk menyalin data.

Penyiapan tabel

Untuk membuat tabel yang diperlukan agar sampel kode berjalan dengan benar, Anda harus menjalankan pernyataan Transact-SQL berikut dalam database SQL Server.

USE AdventureWorks2022;
GO
  
IF EXISTS (SELECT * FROM dbo.sysobjects
 WHERE id = object_id(N'[dbo].[BulkCopyDemoMatchingColumns]')
 AND OBJECTPROPERTY(id, N'IsUserTable') = 1)  
    DROP TABLE [dbo].[BulkCopyDemoMatchingColumns]  
  
CREATE TABLE [dbo].[BulkCopyDemoMatchingColumns]([ProductID] [int] IDENTITY(1,1) NOT NULL,  
    [Name] [nvarchar](50) NOT NULL,  
    [ProductNumber] [nvarchar](25) NOT NULL,  
 CONSTRAINT [PK_ProductID] PRIMARY KEY CLUSTERED
(  
    [ProductID] ASC  
) ON [PRIMARY]) ON [PRIMARY]  
  
IF EXISTS (SELECT * FROM dbo.sysobjects
 WHERE id = object_id(N'[dbo].[BulkCopyDemoDifferentColumns]')
 AND OBJECTPROPERTY(id, N'IsUserTable') = 1)  
    DROP TABLE [dbo].[BulkCopyDemoDifferentColumns]  
  
CREATE TABLE [dbo].[BulkCopyDemoDifferentColumns]([ProdID] [int] IDENTITY(1,1) NOT NULL,  
    [ProdNum] [nvarchar](25) NOT NULL,  
    [ProdName] [nvarchar](50) NOT NULL,  
 CONSTRAINT [PK_ProdID] PRIMARY KEY CLUSTERED
(  
    [ProdID] ASC  
) ON [PRIMARY]) ON [PRIMARY]  
  
IF EXISTS (SELECT * FROM dbo.sysobjects
 WHERE id = object_id(N'[dbo].[BulkCopyDemoOrderHeader]')
 AND OBJECTPROPERTY(id, N'IsUserTable') = 1)  
    DROP TABLE [dbo].[BulkCopyDemoOrderHeader]  
  
CREATE TABLE [dbo].[BulkCopyDemoOrderHeader]([SalesOrderID] [int] IDENTITY(1,1) NOT NULL,  
    [OrderDate] [datetime] NOT NULL,  
    [AccountNumber] [nvarchar](15) NULL,  
 CONSTRAINT [PK_SalesOrderID] PRIMARY KEY CLUSTERED
(  
    [SalesOrderID] ASC  
) ON [PRIMARY]) ON [PRIMARY]  
  
IF EXISTS (SELECT * FROM dbo.sysobjects
 WHERE id = object_id(N'[dbo].[BulkCopyDemoOrderDetail]')
 AND OBJECTPROPERTY(id, N'IsUserTable') = 1)  
    DROP TABLE [dbo].[BulkCopyDemoOrderDetail]  
  
CREATE TABLE [dbo].[BulkCopyDemoOrderDetail]([SalesOrderID] [int] NOT NULL,  
    [SalesOrderDetailID] [int] NOT NULL,  
    [OrderQty] [smallint] NOT NULL,  
    [ProductID] [int] NOT NULL,  
    [UnitPrice] [money] NOT NULL,  
 CONSTRAINT [PK_LineNumber] PRIMARY KEY CLUSTERED
(  
    [SalesOrderID] ASC,  
    [SalesOrderDetailID] ASC  
) ON [PRIMARY]) ON [PRIMARY]  
  

Operasi penyalinan massal tunggal

Pendekatan paling sederhana untuk melakukan operasi penyalinan massal SQL Server adalah dengan melakukan satu operasi terhadap database. Secara default, operasi penyalinan massal dilakukan sebagai operasi yang terisolasi: operasi penyalinan terjadi dengan cara tanpa transaksi, tanpa peluang untuk memutarnya kembali.

Catatan

Jika Anda perlu memutar kembali semua atau sebagian salinan massal saat terjadi kesalahan, Anda dapat menggunakan SQLServerBulkCopy-transaksi terkelola, atau melakukan operasi penyalinan massal dalam transaksi yang ada.
Untuk informasi selengkapnya, lihat Operasi transaksi dan penyalinan massal

Langkah-langkah umum untuk melakukan operasi penyalinan massal adalah:

  1. Hubungkan ke server sumber dan dapatkan data yang akan disalin. Data juga dapat berasal dari sumber lain, jika dapat diambil dari ResultSet objek atau ISQLServerBulkRecord implementasi.

  2. Sambungkan ke server tujuan (kecuali Anda ingin SQLServerBulkCopy membuat koneksi untuk Anda).

  3. Buat SQLServerBulkCopy objek, atur properti yang diperlukan melalui setBulkCopyOptions.

  4. setDestinationTableName Panggil metode untuk menunjukkan tabel target untuk operasi penyisipan massal.

  5. Panggil salah satu metode writeToServer.

  6. Secara opsional, perbarui properti melalui setBulkCopyOptions dan panggil writeToServer lagi seperlunya.

  7. Panggil close, atau bungkus operasi salin massal dalam pernyataan try-with-resources.

Perhatian

Sebaiknya tipe data kolom sumber dan target cocok. Jika jenis data tidak cocok, SQLServerBulkCopy upaya untuk mengonversi setiap nilai sumber ke jenis data target. Konversi dapat memengaruhi kinerja, dan juga dapat mengakibatkan kesalahan yang tidak terduga. Misalnya, jenis data ganda dapat dikonversi ke jenis data desimal sebagian besar waktu, tetapi tidak selalu.

Contoh

Aplikasi berikut menunjukkan cara memuat data menggunakan SQLServerBulkCopy kelas . Dalam contoh ini, ResultSet digunakan untuk menyalin data dari tabel Production.Product di database SQL Server AdventureWorks ke tabel serupa dalam database yang sama.

Penting

Sampel ini tidak akan berjalan kecuali Anda telah membuat tabel kerja seperti yang dijelaskan dalam Penyiapan tabel. Kode ini disediakan untuk menunjukkan sintaksis hanya untuk menggunakan SQLServerBulkCopy . Jika tabel sumber dan tujuan terletak di instans SQL Server yang sama, lebih mudah dan lebih cepat untuk menggunakan TRANSACT-SQL INSERT ... Pernyataan SELECT untuk menyalin data.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;

public class BulkCopySingle {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
        String destinationTable = "dbo.BulkCopyDemoMatchingColumns";
        int countBefore, countAfter;
        ResultSet rsSourceData;

        try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
                Connection destinationConnection = DriverManager.getConnection(connectionUrl);
                Statement stmt = sourceConnection.createStatement();
                SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(destinationConnection)) {

            // Empty the destination table.
            stmt.executeUpdate("DELETE FROM " + destinationTable);

            // Perform an initial count on the destination table.
            countBefore = getRowCount(stmt, destinationTable);

            // Get data from the source table as a ResultSet.
            rsSourceData = stmt.executeQuery("SELECT ProductID, Name, ProductNumber FROM Production.Product");

            // In real world applications you would
            // not use SQLServerBulkCopy to move data from one table to the other
            // in the same database. This is for demonstration purposes only.

            // Set up the bulk copy object.
            // Note that the column positions in the source
            // table match the column positions in
            // the destination table so there is no need to
            // map columns.
            bulkCopy.setDestinationTableName(destinationTable);

            // Write from the source to the destination.
            bulkCopy.writeToServer(rsSourceData);

            // Perform a final count on the destination
            // table to see how many rows were added.
            countAfter = getRowCount(stmt, destinationTable);
            System.out.println((countAfter - countBefore) + " rows were added.");
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static int getRowCount(Statement stmt,
            String tableName) throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        return count;
    }
}

Melakukan operasi penyalinan massal menggunakan Transact-SQL

Contoh berikut mengilustrasikan cara menggunakan metode executeUpdate untuk mengeksekusi pernyataan PENYISIPAN MASSAL.

Catatan

Jalur file sumber data bergantung pada server. Proses server harus memiliki akses ke jalur itu agar operasi penyalinan massal berhasil.

try (Connection con = DriverManager.getConnection(connectionUrl);
        Statement stmt = con.createStatement()) {
    // Perform the BULK INSERT
    stmt.executeUpdate(
            "BULK INSERT Northwind.dbo.[Order Details] " + "FROM 'f:\\mydata\\data.tbl' " + "WITH ( FORMATFILE='f:\\mydata\\data.fmt' )");
}

Beberapa operasi penyalinan massal

Anda bisa melakukan beberapa operasi penyalinan massal menggunakan satu instans kelas SQLServerBulkCopy. Jika parameter operasi berubah di antara salinan (misalnya, nama tabel tujuan), Anda harus memperbaruinya sebelum panggilan berikutnya ke salah writeToServer satu metode, seperti yang ditunjukkan dalam contoh berikut. Kecuali diubah secara eksplisit, semua nilai properti tetap sama seperti pada operasi salin massal sebelumnya untuk instans tertentu.

Catatan

Melakukan beberapa operasi penyalinan massal menggunakan instans SQLServerBulkCopy yang sama biasanya lebih efisien daripada menggunakan instans terpisah untuk setiap operasi.

Jika Anda melakukan beberapa operasi penyalinan massal menggunakan objek SQLServerBulkCopy yang sama, tidak ada batasan apakah informasi sumber atau target sama atau berbeda di setiap operasi. Namun, Anda harus memastikan bahwa informasi asosiasi kolom diatur dengan benar setiap kali Anda menulis ke server.

Penting

Sampel ini tidak akan berjalan kecuali Anda telah membuat tabel kerja seperti yang dijelaskan dalam Penyiapan tabel. Kode ini disediakan untuk menunjukkan sintaksis hanya untuk menggunakan SQLServerBulkCopy . Jika tabel sumber dan tujuan terletak di instans SQL Server yang sama, lebih mudah dan lebih cepat untuk menggunakan TRANSACT-SQL INSERT ... Pernyataan SELECT untuk menyalin data.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;

public class BulkCopyMultiple {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
        String destinationHeaderTable = "dbo.BulkCopyDemoOrderHeader";
        String destinationDetailTable = "dbo.BulkCopyDemoOrderDetail";
        int countHeaderBefore, countDetailBefore, countHeaderAfter, countDetailAfter;
        ResultSet rsHeader, rsDetail;

        try (Connection sourceConnection1 = DriverManager.getConnection(connectionUrl);
                Connection sourceConnection2 = DriverManager.getConnection(connectionUrl);
                Statement stmt = sourceConnection1.createStatement();
                PreparedStatement preparedStmt1 = sourceConnection1.prepareStatement(
                        "SELECT [SalesOrderID], [OrderDate], [AccountNumber] FROM [Sales].[SalesOrderHeader] WHERE [AccountNumber] = ?;");
                PreparedStatement preparedStmt2 = sourceConnection2.prepareStatement(
                        "SELECT [Sales].[SalesOrderDetail].[SalesOrderID], [SalesOrderDetailID], [OrderQty], [ProductID], [UnitPrice] FROM "
                                + "[Sales].[SalesOrderDetail] INNER JOIN [Sales].[SalesOrderHeader] ON "
                                + "[Sales].[SalesOrderDetail].[SalesOrderID] = [Sales].[SalesOrderHeader].[SalesOrderID] WHERE [AccountNumber] = ?;");
                SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(connectionUrl);) {

            // Empty the destination tables.
            stmt.executeUpdate("DELETE FROM " + destinationHeaderTable);
            stmt.executeUpdate("DELETE FROM " + destinationDetailTable);

            // Perform an initial count on the destination
            // table with matching columns.
            countHeaderBefore = getRowCount(stmt, destinationHeaderTable);

            // Perform an initial count on the destination
            // table with different column positions.
            countDetailBefore = getRowCount(stmt, destinationDetailTable);

            // Get data from the source table as a ResultSet.
            // The Sales.SalesOrderHeader and Sales.SalesOrderDetail
            // tables are quite large and could easily cause a timeout
            // if all data from the tables is added to the destination.
            // To keep the example simple and quick, a parameter is
            // used to select only orders for a particular account
            // as the source for the bulk insert.
            preparedStmt1.setString(1, "10-4020-000034");
            rsHeader = preparedStmt1.executeQuery();

            // Get the Detail data in a separate connection.
            preparedStmt2.setString(1, "10-4020-000034");
            rsDetail = preparedStmt2.executeQuery();

            // Create the SQLServerBulkCopySQLServerBulkCopy object.
            SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
            copyOptions.setBulkCopyTimeout(100);
            bulkCopy.setBulkCopyOptions(copyOptions);
            bulkCopy.setDestinationTableName(destinationHeaderTable);

            // Guarantee that columns are mapped correctly by
            // defining the column mappings for the order.
            bulkCopy.addColumnMapping("SalesOrderID", "SalesOrderID");
            bulkCopy.addColumnMapping("OrderDate", "OrderDate");
            bulkCopy.addColumnMapping("AccountNumber", "AccountNumber");

            // Write rsHeader to the destination.
            bulkCopy.writeToServer(rsHeader);

            // Set up the order details destination.
            bulkCopy.setDestinationTableName(destinationDetailTable);

            // Clear the existing column mappings
            bulkCopy.clearColumnMappings();

            // Add order detail column mappings.
            bulkCopy.addColumnMapping("SalesOrderID", "SalesOrderID");
            bulkCopy.addColumnMapping("SalesOrderDetailID", "SalesOrderDetailID");
            bulkCopy.addColumnMapping("OrderQty", "OrderQty");
            bulkCopy.addColumnMapping("ProductID", "ProductID");
            bulkCopy.addColumnMapping("UnitPrice", "UnitPrice");

            // Write rsDetail to the destination.
            bulkCopy.writeToServer(rsDetail);

            // Perform a final count on the destination
            // tables to see how many rows were added.
            countHeaderAfter = getRowCount(stmt, destinationHeaderTable);
            countDetailAfter = getRowCount(stmt, destinationDetailTable);

            System.out.println((countHeaderAfter - countHeaderBefore) + " rows were added to the Header table.");
            System.out.println((countDetailAfter - countDetailBefore) + " rows were added to the Detail table.");
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static int getRowCount(Statement stmt,
            String tableName) throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        return count;
    }
}

Operasi transaksi dan penyalinan massal

Operasi penyalinan massal dapat dilakukan sebagai operasi terisolasi atau sebagai bagian dari transaksi beberapa langkah. Opsi terakhir ini memungkinkan Anda melakukan lebih dari satu operasi penyalinan massal dalam transaksi yang sama, serta melakukan operasi database lainnya (seperti sisipan, pembaruan, dan penghapusan) sambil tetap dapat menerapkan atau mengembalikan seluruh transaksi.

Secara default, operasi penyalinan massal dilakukan sebagai operasi terisolasi. Operasi penyalinan massal terjadi dengan cara yang tidak ditransaksikan, tanpa kesempatan untuk memutarnya kembali. Jika Anda perlu mengembalikan semua atau sebagian salinan massal saat terjadi kesalahan, Anda dapat menggunakan SQLServerBulkCopytransaksi -managed atau melakukan operasi salin massal dalam transaksi yang ada.

Salinan Massal yang Diperluas untuk Gudang Data Azure

Driver versi v8.4.1 menambahkan properti koneksi baru, sendTemporalDataTypesAsStringForBulkCopy. Properti boolean ini secara true default.

Properti koneksi ini, ketika diatur ke false, akan mengirim jenis data DATE, DATETIME, DATIMETIME2, DATETIMEOFFSET, SMALLDATETIME, dan TIME sebagai jenis masing-masing alih-alih mengirimkannya sebagai String.

Mengirim jenis data temporal sebagai jenis masing-masing memungkinkan pengguna mengirim data ke kolom tersebut untuk Azure Synapse Analytics, yang sebelumnya tidak dimungkinkan karena driver mengonversi data menjadi String. Mengirim data String ke kolom temporal berfungsi untuk SQL Server karena SQL Server akan melakukan konversi implisit bagi kami, tetapi tidak sama dengan Azure Synapse Analytics.

Selain itu, bahkan tanpa mengatur string koneksi ini ke 'false', dari v8.4.1 dan seterusnya, datatype MONEY dan SMALLMONEY akan dikirim sebagai jenis data MONEY / SMALLMONEY alih-alih DECIMAL, yang juga memungkinkan jenis data tersebut disalin secara massal ke Azure Synapse Analytics.

Penyalinan Massal yang Diperluas untuk batasan Azure Data Warehouse

Saat ini ada dua batasan:

  1. Dengan properti koneksi ini diatur ke false, driver hanya akan menerima format literal string default dari setiap jenis data temporal, misalnya:

    DATE: YYYY-MM-DD

    DATETIME: YYYY-MM-DD hh:mm:ss[.nnn]

    DATETIME2: YYYY-MM-DD hh:mm:ss[.nnnnnnn]

    DATETIMEOFFSET: YYYY-MM-DD hh:mm:ss[.nnnnnnn] [{+/-}hh:mm]

    SMALLDATETIME:YYYY-MM-DD hh:mm:ss

    TIME: hh:mm:ss[.nnnnnnn]

  2. Dengan properti koneksi ini diatur ke false, jenis kolom yang ditentukan untuk salinan massal harus menghormati bagan pemetaan jenis data dari sini. Misalnya, sebelumnya pengguna dapat menentukan java.sql.Types.TIMESTAMP untuk menyalin data secara massal ke dalam DATE kolom, tetapi dengan fitur ini diaktifkan, mereka harus menentukan java.sql.Types.DATE untuk melakukan hal yang sama.

Melakukan operasi penyalinan massal yang tidak ditransaksikan

Aplikasi berikut menunjukkan apa yang terjadi ketika operasi penyalinan massal yang tidak ditransaksikan mengalami kesalahan sebagian melalui operasi.

Dalam contoh, tabel sumber dan tabel tujuan masing-masing menyertakan kolom Identitas bernama ProductID. Kode pertama-tama menyiapkan tabel tujuan dengan menghapus semua baris lalu menyisipkan satu baris yang ProductID diketahui ada di tabel sumber. Secara default, nilai baru untuk kolom Identitas dihasilkan dalam tabel tujuan untuk setiap baris yang ditambahkan. Dalam contoh ini, opsi diatur saat koneksi dibuka yang memaksa proses beban massal untuk menggunakan nilai Identitas dari tabel sumber sebagai gantinya.

Operasi penyalinan massal dijalankan dengan properti BatchSize diatur ke 10. Ketika operasi menemukan baris yang tidak valid, pengecualian dilemparkan. Dalam contoh pertama ini, operasi penyalinan massal tidak ditransaksikan. Semua batch yang disalin hingga titik kesalahan dilakukan; batch yang berisi kunci duplikat digulung balik, dan operasi penyalinan massal dihentikan sebelum memproses batch lainnya.

Catatan

Sampel ini tidak akan berjalan kecuali Anda telah membuat tabel kerja seperti yang dijelaskan dalam Penyiapan tabel. Kode ini disediakan untuk menunjukkan sintaksis hanya untuk menggunakan SQLServerBulkCopy . Jika tabel sumber dan tujuan terletak di instans SQL Server yang sama, lebih mudah dan lebih cepat untuk menggunakan TRANSACT-SQL INSERT ... Pernyataan SELECT untuk menyalin data.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;

public class BulkCopyNonTransacted {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
        String destinationTable = "dbo.BulkCopyDemoMatchingColumns";
        int countBefore, countAfter;
        ResultSet rsSourceData;

        try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
                Statement stmt = sourceConnection.createStatement();
                SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(connectionUrl)) {

            // Empty the destination table.
            stmt.executeUpdate("DELETE FROM " + destinationTable);

            // Add a single row that will result in duplicate key
            // when all rows from source are bulk copied.
            // Note that this technique will only be successful in
            // illustrating the point if a row with ProductID = 446
            // exists in the AdventureWorks Production.Products table.
            // If you have made changes to the data in this table, change
            // the SQL statement in the code to add a ProductID that
            // does exist in your version of the Production.Products
            // table. Choose any ProductID in the middle of the table
            // (not first or last row) to best illustrate the result.
            stmt.executeUpdate("SET IDENTITY_INSERT " + destinationTable + " ON;" + "INSERT INTO " + destinationTable
                    + "([ProductID], [Name] ,[ProductNumber]) VALUES(446, 'Lock Nut 23','LN-3416'); SET IDENTITY_INSERT " + destinationTable
                    + " OFF");

            // Perform an initial count on the destination table.
            countBefore = getRowCount(stmt, destinationTable);

            // Get data from the source table as a ResultSet.
            rsSourceData = stmt.executeQuery("SELECT ProductID, Name, ProductNumber FROM Production.Product");

            // Set up the bulk copy object using the KeepIdentity option and BatchSize = 10.
            SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
            copyOptions.setKeepIdentity(true);
            copyOptions.setBatchSize(10);

            bulkCopy.setBulkCopyOptions(copyOptions);
            bulkCopy.setDestinationTableName(destinationTable);

            // Write from the source to the destination.
            // This should fail with a duplicate key error
            // after some of the batches have been copied.
            try {
                bulkCopy.writeToServer(rsSourceData);
            }
            catch (SQLException e) {
                e.printStackTrace();
            }

            // Perform a final count on the destination
            // table to see how many rows were added.
            countAfter = getRowCount(stmt, destinationTable);
            System.out.println((countAfter - countBefore) + " rows were added.");
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static int getRowCount(Statement stmt,
            String tableName) throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        return count;
    }
}

Melakukan operasi penyalinan massal khusus dalam transaksi

Secara default, operasi penyalinan massal tidak membuat transaksi itu sendiri. Saat Anda ingin melakukan operasi penyalinan massal khusus, buat instans SQLServerBulkCopy baru dengan string koneksi. Dalam skenario ini, setiap batch operasi salinan massal diterapkan secara implisit oleh database. Anda dapat mengatur UseInternalTransaction opsi ke true dalam SQLServerBulkCopyOptions untuk membuat operasi penyalinan massal membuat transaksi, melakukan penerapan setelah setiap batch operasi salin massal.

SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
copyOptions.setKeepIdentity(true);
copyOptions.setBatchSize(10);
copyOptions.setUseInternalTransaction(true);

Menggunakan transaksi yang ada

Anda dapat meneruskan Connection objek yang mengaktifkan transaksi sebagai parameter dalam SQLServerBulkCopy konstruktor. Dalam situasi ini, operasi penyalinan massal dilakukan dalam transaksi yang ada, dan tidak ada perubahan yang dilakukan pada status transaksi (yaitu, itu tidak dilakukan atau dibatalkan). Ini memungkinkan aplikasi untuk menyertakan operasi penyalinan massal dalam transaksi dengan operasi database lainnya. Jika Anda perlu mengembalikan seluruh operasi penyalinan massal karena terjadi kesalahan, atau jika salinan massal harus dijalankan sebagai bagian dari proses yang lebih besar yang dapat digulung balik, Anda dapat melakukan putar kembali pada objek kapan Connection saja setelah operasi penyalinan massal.

Aplikasi berikut mirip BulkCopyNonTransacteddengan , dengan satu pengecualian: dalam contoh ini, operasi penyalinan massal disertakan dalam transaksi eksternal yang lebih besar. Ketika kesalahan pelanggaran kunci primer terjadi, seluruh transaksi digulung balik dan tidak ada baris yang ditambahkan ke tabel tujuan.

Catatan

Sampel ini tidak akan berjalan kecuali Anda telah membuat tabel kerja seperti yang dijelaskan dalam Penyiapan tabel. Kode ini disediakan untuk menunjukkan sintaksis hanya untuk menggunakan SQLServerBulkCopy . Jika tabel sumber dan tujuan terletak di instans SQL Server yang sama, lebih mudah dan lebih cepat untuk menggunakan TRANSACT-SQL INSERT ... Pernyataan SELECT untuk menyalin data.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;

public class BulkCopyExistingTransactions {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
        String destinationTable = "dbo.BulkCopyDemoMatchingColumns";
        int countBefore, countAfter;
        ResultSet rsSourceData;
        SQLServerBulkCopyOptions copyOptions;

        try (Connection sourceConnection = DriverManager.getConnection(connectionUrl);
                Connection destinationConnection = DriverManager.getConnection(connectionUrl);
                Statement stmt = sourceConnection.createStatement();
                SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(destinationConnection);) {

            // Empty the destination table.
            stmt.executeUpdate("DELETE FROM " + destinationTable);

            // Add a single row that will result in duplicate key
            // when all rows from source are bulk copied.
            // Note that this technique will only be successful in
            // illustrating the point if a row with ProductID = 446
            // exists in the AdventureWorks Production.Products table.
            // If you have made changes to the data in this table, change
            // the SQL statement in the code to add a ProductID that
            // does exist in your version of the Production.Products
            // table. Choose any ProductID in the middle of the table
            // (not first or last row) to best illustrate the result.
            stmt.executeUpdate("SET IDENTITY_INSERT " + destinationTable + " ON;" + "INSERT INTO " + destinationTable
                    + "([ProductID], [Name] ,[ProductNumber]) VALUES(446, 'Lock Nut 23','LN-3416'); SET IDENTITY_INSERT " + destinationTable
                    + " OFF");

            // Perform an initial count on the destination table.
            countBefore = getRowCount(stmt, destinationTable);

            // Get data from the source table as a ResultSet.
            rsSourceData = stmt.executeQuery("SELECT ProductID, Name, ProductNumber FROM Production.Product");

            // Set up the bulk copy object inside the transaction.
            destinationConnection.setAutoCommit(false);

            copyOptions = new SQLServerBulkCopyOptions();
            copyOptions.setKeepIdentity(true);
            copyOptions.setBatchSize(10);

            bulkCopy.setBulkCopyOptions(copyOptions);
            bulkCopy.setDestinationTableName(destinationTable);

            // Write from the source to the destination.
            // This should fail with a duplicate key error.
            try {
                bulkCopy.writeToServer(rsSourceData);
                destinationConnection.commit();
            }
            catch (SQLException e) {
                e.printStackTrace();
                destinationConnection.rollback();
            }

            // Perform a final count on the destination
            // table to see how many rows were added.
            countAfter = getRowCount(stmt, destinationTable);
            System.out.println((countAfter - countBefore) + " rows were added.");
        }
        catch (Exception e) {
            // Handle any errors that may have occurred.
            e.printStackTrace();
        }
    }

    private static int getRowCount(Statement stmt,
            String tableName) throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        return count;
    }
}

Salinan massal dari file CSV

Aplikasi berikut menunjukkan cara memuat data menggunakan SQLServerBulkCopy kelas . Dalam contoh ini, file CSV digunakan untuk menyalin data yang diekspor dari tabel Production.Product di database SQL Server AdventureWorks ke tabel serupa dalam database.

Penting

Sampel ini tidak akan berjalan kecuali Anda telah membuat tabel kerja seperti yang dijelaskan dalam Penyiapan tabel untuk mendapatkannya.

  1. Buka SQL Server Management Studio dan sambungkan ke SQL Server dengan database AdventureWorks.

  2. Perluas database, klik kanan database AdventureWorks, pilih Tugas dan Ekspor Data...

  3. Untuk Sumber Data, pilih Sumber data yang memungkinkan Anda menyambungkan ke SQL Server Anda (misalnya, SQL Server Native Client 11.0), periksa konfigurasi lalu Berikutnya

  4. Untuk Tujuan, pilih Tujuan File Datar dan masukkan Nama File dengan tujuan seperti C:\Test\TestBulkCSVExample.csv. Periksa apakah Format Dibatasi, Kualifikasi teks tidak ada, dan aktifkan Nama kolom di baris data pertama, lalu pilih Berikutnya

  5. Pilih Tulis kueri untuk menentukan data yang akan ditransfer dan Berikutnya. Masukkan PernyataanSELECT ProductID, Name, ProductNumber FROM Production.Product SQL Anda, dan Berikutnya

  6. Periksa konfigurasi: Anda dapat meninggalkan pemisah Baris sebagai {CR}{LF} dan Pemisah Kolom sebagai Koma {,}. Pilih Edit Pemetaan... dan periksa apakah Tipe data sudah benar untuk setiap kolom (misalnya, bilangan bulat untuk ProductID dan string Unicode untuk yang lain).

  7. Lewati ke Depan ke Selesai dan jalankan ekspor.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerBulkCSVFileRecord;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;

public class BulkCopyCSV {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
        String destinationTable = "dbo.BulkCopyDemoMatchingColumns";
        int countBefore, countAfter;

        // Get data from the source file by loading it into a class that implements ISQLServerBulkRecord.
        // Here we are using the SQLServerBulkCSVFileRecord implementation to import the example CSV file.
        try (Connection destinationConnection = DriverManager.getConnection(connectionUrl);
                Statement stmt = destinationConnection.createStatement();
                SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(destinationConnection);
                SQLServerBulkCSVFileRecord fileRecord = new SQLServerBulkCSVFileRecord("C:\\Test\\TestBulkCSVExample.csv", true);) {

            // Set the metadata for each column to be copied.
            fileRecord.addColumnMetadata(1, null, java.sql.Types.INTEGER, 0, 0);
            fileRecord.addColumnMetadata(2, null, java.sql.Types.NVARCHAR, 50, 0);
            fileRecord.addColumnMetadata(3, null, java.sql.Types.NVARCHAR, 25, 0);

            // Empty the destination table.
            stmt.executeUpdate("DELETE FROM " + destinationTable);

            // Perform an initial count on the destination table.
            countBefore = getRowCount(stmt, destinationTable);

            // Set up the bulk copy object.
            // Note that the column positions in the source
            // data reader match the column positions in
            // the destination table so there is no need to
            // map columns.
            bulkCopy.setDestinationTableName(destinationTable);

            // Write from the source to the destination.
            bulkCopy.writeToServer(fileRecord);

            // Perform a final count on the destination
            // table to see how many rows were added.
            countAfter = getRowCount(stmt, destinationTable);
            System.out.println((countAfter - countBefore) + " rows were added.");
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static int getRowCount(Statement stmt,
            String tableName) throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        return count;
    }
}

Menggunakan karakter regex sebagai pemisah

Catatan

Saat mengatur pemisah kustom, keluarkan jika itu adalah karakter regex seperti '|'.

SQLServerBulkCSVFileRecord fileRecord = new SQLServerBulkCSVFileRecord(CSVFilePath, null, "\\|", true);

Salin massal dengan pemisah sebagai data dalam file CSV

Driver versi 8.4.1 menambahkan API SQLServerBulkCSVFileRecord.setEscapeColumnDelimitersCSV(boolean)baru . Ketika diatur ke true, aturan berikut akan berlaku:

  • Setiap bidang mungkin atau mungkin tidak diapit dalam tanda kutip ganda.
  • Jika bidang tidak diapit dengan tanda kutip ganda, tanda kutip ganda mungkin tidak muncul di dalam bidang.
  • Bidang yang berisi tanda kutip ganda, dan pemisah harus diapit dalam tanda kutip ganda.
  • Jika tanda kutip ganda digunakan untuk mengapit bidang, maka tanda kutip ganda yang muncul di dalam bidang harus diloloskan dengan mendahuluinya dengan tanda kutip ganda lainnya.

Salin massal dengan kolom Always Encrypted

Dimulai dengan Microsoft JDBC Driver 6.0 untuk SQL Server, salinan massal didukung dengan kolom Always Encrypted.

Tergantung pada opsi penyalinan massal, dan jenis enkripsi tabel sumber dan tujuan driver JDBC dapat didekripsi secara transparan dan kemudian mengenkripsi data atau dapat mengirim data terenkripsi apa adanya. Misalnya, ketika menyalin data secara massal dari kolom terenkripsi ke kolom yang tidak terenkripsi, driver secara transparan mendekripsi data sebelum mengirim ke SQL Server. Demikian pula ketika menyalin data secara massal dari kolom yang tidak terenkripsi (atau dari file CSV) ke kolom terenkripsi, driver secara transparan mengenkripsi data sebelum mengirim ke SQL Server. Jika sumber dan tujuan dienkripsi, maka tergantung pada allowEncryptedValueModifications opsi penyalinan massal, driver akan mengirim data apa adanya atau akan mendekripsi data dan mengenkripsinya lagi sebelum mengirimnya ke SQL Server.

Untuk informasi selengkapnya, lihat allowEncryptedValueModifications opsi salin massal di bawah ini, dan Menggunakan Always Encrypted dengan Driver JDBC.

Penting

Batasan Microsoft JDBC Driver 6.0 untuk SQL Server, saat menyalin data secara massal dari file CSV ke kolom terenkripsi:

Hanya format literal string default Transact-SQL yang didukung untuk jenis tanggal dan waktu

Jenis data DATETIME dan SMALLDATETIME tidak didukung

SALIN MASSAL API untuk driver JDBC

SQLServerBulkCopy

Memungkinkan Anda memuat tabel SQL Server secara efisien secara massal dengan data dari sumber lain.

Microsoft SQL Server menyertakan utilitas prompt perintah populer bernama bcp untuk memindahkan data dari satu tabel ke tabel lainnya, baik di satu server atau antar server. Kelas ini SQLServerBulkCopy memungkinkan Anda menulis solusi kode di Java yang menyediakan fungsionalitas serupa. Ada cara lain untuk memuat data ke dalam tabel SQL Server (pernyataan INSERT, misalnya), tetapi SQLServerBulkCopy menawarkan keunggulan performa yang signifikan atasnya.

Kelas SQLServerBulkCopy dapat digunakan untuk menulis data hanya ke tabel SQL Server. Namun, sumber data tidak terbatas pada SQL Server; sumber data apa pun dapat digunakan, selama data dapat dibaca dengan ResultSet instans atau ISQLServerBulkRecord implementasi.

Konstruktor Deskripsi
SQLServerBulkCopy(Connection connection) Menginisialisasi instans SQLServerBulkCopy baru kelas menggunakan instans terbuka yang ditentukan dari SQLServerConnection. Connection Jika transaksi telah diaktifkan, operasi penyalinan akan dilakukan dalam transaksi tersebut.
SQLServerBulkCopy(String connectionURL) Menginisialisasi dan membuka instans SQLServerConnection baru berdasarkan yang disediakan connectionURL. Konstruktor menggunakan untuk menginisialisasi instans SQLServerConnectionSQLServerBulkCopy baru kelas.
Properti Deskripsi
String DestinationTableName Nama tabel tujuan di server.

Jika DestinationTableName belum diatur ketika writeToServer dipanggil, akan SQLServerException dilemparkan.

DestinationTableName adalah nama tiga bagian (<database>.<owningschema>.<name>). Anda dapat memenuhi syarat nama tabel dengan database dan skema pemiliknya jika Anda memilih. Namun, jika nama tabel menggunakan garis bawah ("_") atau karakter khusus lainnya, Anda harus keluar dari nama menggunakan tanda kurung di sekitarnya. Untuk informasi selengkapnya, lihat Pengidentifikasi Database.
ColumnMappings Pemetaan kolom menentukan hubungan antara kolom di sumber data dan kolom di tujuan.

Jika pemetaan tidak ditentukan, kolom dipetakan secara implisit berdasarkan posisi ordinal. Agar ini berfungsi, skema sumber dan target harus cocok. Jika tidak, Pengecualian akan dilemparkan.

Jika pemetaan tidak kosong, tidak setiap kolom yang ada di sumber data harus ditentukan. Mereka yang tidak dipetakan diabaikan.

Anda dapat merujuk ke kolom sumber dan target dengan nama atau ordinal.
Metode Deskripsi
void addColumnMapping(int sourceColumn, int destinationColumn) Menambahkan pemetaan kolom baru, menggunakan ordinal untuk menentukan kolom sumber dan tujuan.
void addColumnMapping (int sourceColumn, String destinationColumn) Menambahkan pemetaan kolom baru, menggunakan ordinal untuk kolom sumber dan nama kolom untuk kolom tujuan.
void addColumnMapping (String sourceColumn, int destinationColumn) Menambahkan pemetaan kolom baru, menggunakan nama kolom untuk menjelaskan kolom sumber dan ordinal untuk menentukan kolom tujuan.
void addColumnMapping (String sourceColumn, String destinationColumn) Menambahkan pemetaan kolom baru, menggunakan nama kolom untuk menentukan kolom sumber dan tujuan.
void clearColumnMappings() Menghapus konten pemetaan kolom.
void close() Menutup instans SQLServerBulkCopy .
SQLServerBulkCopyOptions getBulkCopyOptions() Mengambil set saat ini dari SQLServerBulkCopyOptions.
String getDestinationTableName() Ambil nama tabel tujuan saat ini.
void setBulkCopyOptions(SQLServerBulkCopyOptions copyOptions) Memperbarui perilaku SQLServerBulkCopy instans sesuai dengan opsi yang disediakan.
void setDestinationTableName(String tableName) Mengatur nama tabel tujuan.
void writeToServer(ResultSet sourceData) Menyalin semua baris dalam yang disediakan ResultSet ke tabel tujuan yang ditentukan oleh DestinationTableName properti SQLServerBulkCopy objek.
void writeToServer(RowSet sourceData) Menyalin semua baris dalam yang disediakan RowSet ke tabel tujuan yang ditentukan oleh DestinationTableName properti SQLServerBulkCopy objek.
void writeToServer(ISQLServerBulkRecord sourceData) Menyalin semua baris dalam implementasi yang disediakan ISQLServerBulkRecord ke tabel tujuan yang ditentukan oleh DestinationTableName properti SQLServerBulkCopy objek.

SQLServerBulkCopyOptions

Kumpulan pengaturan yang mengontrol perilaku writeToServer metode dalam instans SQLServerBulkCopy.

Konstruktor Deskripsi
SQLServerBulkCopyOptions() Menginisialisasi instans SQLServerBulkCopyOptions baru kelas menggunakan default untuk semua pengaturan.

Getter dan setter ada untuk opsi berikut:

Opsi Deskripsi Default
boolean CheckConstraints Periksa batasan saat data sedang disisipkan. False - batasan tidak diperiksa
boolean FireTriggers Menyebabkan server mengaktifkan pemicu penyisipan untuk baris yang dimasukkan ke dalam database. False - tidak ada pemicu yang diaktifkan
boolean KeepIdentity Pertahankan nilai identitas sumber. False - nilai identitas ditetapkan oleh tujuan
boolean KeepNulls Pertahankan nilai null dalam tabel tujuan terlepas dari pengaturan untuk nilai default. False - nilai null digantikan oleh nilai default jika berlaku.
boolean TableLock Dapatkan kunci pembaruan massal selama durasi operasi penyalinan massal. False - kunci baris digunakan.
boolean UseInternalTransaction Ketika diatur ke true, setiap batch operasi penyalinan massal akan terjadi dalam transaksi. Jika SQLServerBulkCopy menggunakan koneksi yang ada (seperti yang ditentukan oleh konstruktor), akan SQLServerException terjadi. Jika SQLServerBulkCopy membuat koneksi khusus, transaksi akan dibuat dan diterapkan untuk setiap batch. False - tidak ada transaksi
int BatchSize Jumlah baris di setiap batch. Di akhir setiap batch, baris dalam batch dikirim ke server.

Batch selesai ketika BatchSize baris telah diproses atau tidak ada lagi baris untuk dikirim ke sumber data tujuan. SQLServerBulkCopy Jika instans telah dinyatakan dengan UseInternalTransaction opsi diatur ke false, baris dikirim ke baris server BatchSize pada satu waktu, tetapi tidak ada tindakan terkait transaksi yang diambil. Jika UseInternalTransaction diatur ke true, setiap batch baris dilakukan dalam transaksi eksplisit.
0 - menunjukkan bahwa setiap writeToServer operasi adalah satu batch
int BulkCopyTimeout Jumlah detik agar operasi selesai sebelum waktu habis. Nilai 0 menunjukkan tidak ada batas; salinan massal akan menunggu tanpa batas waktu. 60 detik.
boolean allowEncryptedValueModifications Opsi ini tersedia dengan Microsoft JDBC Driver 6.0 (atau lebih tinggi) untuk SQL Server.

Saat diatur ke true, allowEncryptedValueModifications memungkinkan penyalinan massal data terenkripsi antara tabel atau database, tanpa mendekripsi data. Biasanya, aplikasi akan memilih data dari kolom terenkripsi dari satu tabel tanpa mendekripsi data (aplikasi akan terhubung ke database dengan kata kunci pengaturan enkripsi kolom diatur ke dinonaktifkan) dan kemudian akan menggunakan opsi ini untuk menyisipkan data secara massal, yang masih dienkripsi. Untuk informasi selengkapnya, lihat Menggunakan Always Encrypted dengan Driver JDBC.

Berhati-hatilah saat mengatur allowEncryptedValueModifications ke true karena ini dapat menyebabkan kerusakan database karena driver tidak memeriksa apakah data memang dienkripsi, atau apakah data dienkripsi dengan benar menggunakan jenis enkripsi, algoritma, dan kunci yang sama dengan kolom target.

Getter dan setter:

Metode Deskripsi
boolean isCheckConstraints() Menunjukkan apakah batasan akan diperiksa saat data sedang disisipkan atau tidak.
void setCheckConstraints(boolean checkConstraints) Mengatur apakah batasan akan diperiksa saat data sedang disisipkan atau tidak.
boolean isFireTriggers() Menunjukkan apakah server harus mengaktifkan pemicu sisipan untuk baris yang dimasukkan ke dalam database.
void setFireTriggers(boolean fireTriggers) Mengatur apakah server harus diatur ke pemicu kebakaran untuk baris yang dimasukkan ke dalam database.
boolean isKeepIdentity() Menunjukkan apakah akan mempertahankan nilai identitas sumber apa pun atau tidak.
void setKeepIdentity(boolean keepIdentity) Mengatur apakah akan mempertahankan nilai identitas atau tidak.
boolean isKeepNulls() Menunjukkan apakah akan mempertahankan nilai null dalam tabel tujuan terlepas dari pengaturan untuk nilai default, atau apakah nilai tersebut harus digantikan oleh nilai default (jika berlaku).
void setKeepNulls(boolean keepNulls) Mengatur apakah akan mempertahankan nilai null dalam tabel tujuan terlepas dari pengaturan untuk nilai default, atau jika nilai tersebut harus digantikan oleh nilai default (jika berlaku).
boolean isTableLock() Menunjukkan apakah SQLServerBulkCopy harus mendapatkan kunci pembaruan massal selama durasi operasi penyalinan massal.
void setTableLock(boolean tableLock) Mengatur apakah SQLServerBulkCopy harus mendapatkan kunci pembaruan massal selama durasi operasi penyalinan massal.
boolean isUseInternalTransaction() Menunjukkan apakah setiap batch operasi penyalinan massal akan terjadi dalam transaksi.
void setUseInternalTranscation(boolean useInternalTransaction) Mengatur apakah setiap batch operasi penyalinan massal akan terjadi dalam transaksi atau tidak.
int getBatchSize() Mendapatkan jumlah baris di setiap batch. Di akhir setiap batch, baris dalam batch dikirim ke server.
void setBatchSize(int batchSize) Mengatur jumlah baris di setiap batch. Di akhir setiap batch, baris dalam batch dikirim ke server.
int getBulkCopyTimeout() Mendapatkan jumlah detik agar operasi selesai sebelum waktu habis.
void setBulkCopyTimeout(int timeout) Mengatur jumlah detik agar operasi selesai sebelum waktu habis.
boolean isAllowEncryptedValueModifications() Menunjukkan apakah allowEncryptedValueModifications pengaturan diaktifkan atau dinonaktifkan.
void setAllowEncryptedValueModifications(boolean allowEncryptedValueModifications) allowEncryptedValueModifications Mengonfigurasi pengaturan yang digunakan untuk penyalinan massal dengan kolom Always Encrypted.

ISQLServerBulkRecord

Antarmuka ISQLServerBulkRecord dapat digunakan untuk membuat kelas yang membaca data dari sumber apa pun (seperti file) dan memungkinkan SQLServerBulkCopy instans memuat tabel SQL Server secara massal dengan data tersebut.

Metode Antarmuka Deskripsi
set<Integer> getColumnOrdinals() Dapatkan ordinal untuk setiap kolom yang diwakili dalam rekaman data ini.
String getColumnName(int column) Dapatkan nama kolom yang diberikan.
int getColumnType(int column) Dapatkan jenis data JDBC dari kolom yang diberikan.
int getPrecision(int column) Dapatkan presisi untuk kolom yang diberikan.
object[] getRowData() Mendapatkan data untuk baris saat ini sebagai array Objek.

Setiap Objek harus cocok dengan Jenis bahasa Java yang digunakan untuk mewakili jenis data JDBC yang ditunjukkan untuk kolom tertentu. Untuk informasi selengkapnya, lihat Memahami Jenis Data Driver JDBC untuk pemetaan yang sesuai.
int getScale(int column) Dapatkan skala untuk kolom yang diberikan.
boolean isAutoIncrement(int column) Menunjukkan apakah kolom mewakili kolom identitas.
boolean next() Maju ke baris data berikutnya.

SQLServerBulkCSVFileRecord

Implementasi sederhana antarmuka ISQLServerBulkRecord yang dapat digunakan untuk membaca dalam jenis data Java dasar dari file yang dibatasi di mana setiap baris mewakili baris data.

Catatan dan Batasan Implementasi:

  1. Jumlah maksimum data yang diizinkan dalam baris tertentu dibatasi oleh memori yang tersedia karena data dibaca satu baris pada satu waktu.

  2. Streaming jenis data besar seperti varchar(max), , varbinary(max)nvarchar(max), sqlxml, dan ntext tidak didukung.

  3. Pemisah yang ditentukan untuk file CSV tidak boleh muncul di mana pun dalam data dan harus diloloskan dengan benar jika itu adalah karakter terbatas dalam ekspresi reguler Java.

  4. Dalam implementasi file CSV, tanda kutip ganda diperlakukan sebagai bagian dari data. Misalnya, baris hello,"world","hello,world" akan diperlakukan memiliki empat kolom dengan nilai hello, , "world""hello dan world" jika pemisah adalah koma.

  5. Karakter baris baru digunakan sebagai terminator baris dan tidak diizinkan di mana pun dalam data.

Konstruktor Deskripsi
SQLServerBulkCSVFileRecord(String fileToParse, String encoding, String delimiter, boolean firstLineIsColumnNames) Menginisialisasi instans SQLServerBulkCSVFileRecord baru kelas yang akan mengurai setiap baris dengan fileToParse pemisah dan pengodean yang disediakan. Jika firstLineIsColumnNames diatur ke True, baris pertama dalam file akan diurai sebagai nama kolom. Jika pengodean NULL, pengodean default akan digunakan.
SQLServerBulkCSVFileRecord(String fileToParse, String encoding, boolean firstLineIsColumnNames) Menginisialisasi instans SQLServerBulkCSVFileRecord baru kelas yang akan mengurai setiap baris dengan fileToParse koma sebagai pemisah dan pengodean yang disediakan. Jika firstLineIsColumnNames diatur ke True, baris pertama dalam file akan diurai sebagai nama kolom. Jika pengodean NULL, pengodean default akan digunakan.
SQLServerBulkCSVFileRecord(String fileToParse, boolean firstLineIsColumnNames Menginisialisasi instans SQLServerBulkCSVFileRecord baru kelas yang akan mengurai setiap baris dengan fileToParse koma sebagai pemisah dan pengodean default. Jika firstLineIsColumnNames diatur ke True, baris pertama dalam file akan diurai sebagai nama kolom.
Metode Deskripsi
void addColumnMetadata(int positionInFile, String columnName, int jdbcType, int precision, int scale) Menambahkan metadata untuk kolom yang diberikan dalam file.
void close() Merilis sumber daya apa pun yang terkait dengan pembaca file.
void setTimestampWithTimezoneFormat(DateTimeFormatter dateTimeFormatter) Mengatur format untuk mengurai data Tanda Waktu dari file sebagai java.sql.Types.TIMESTAMP_WITH_TIMEZONE.
void setTimestampWithTimezoneFormat(String dateTimeFormat) Mengatur format untuk mengurai data Waktu dari file sebagai java.sql.Types.TIME_WITH_TIMEZONE.
void setTimeWithTimezoneFormat(DateTimeFormatter dateTimeFormatter) Mengatur format untuk mengurai data Waktu dari file sebagai java.sql.Types.TIME_WITH_TIMEZONE.
void setTimeWithTimezoneFormat(String timeFormat) Mengatur format untuk mengurai data Waktu dari file sebagai java.sql.Types.TIME_WITH_TIMEZONE.

Baca juga

Gambaran umum driver JDBC