Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Microsoft SQL Server inclui uma utilidade popular de linha de comandos, nomeada bcp para copiar rapidamente em massa ficheiros grandes em tabelas ou vistas em bases de dados SQL Server. A SQLServerBulkCopy classe permite-te escrever soluções de código em Java que oferecem funcionalidades semelhantes. Há outras maneiras de carregar dados em uma tabela do SQL Server (instruções INSERT, por exemplo), mas SQLServerBulkCopy oferece uma vantagem de desempenho significativa sobre elas.
A SQLServerBulkCopy classe pode ser usada para gravar dados somente em tabelas do SQL Server. Mas a fonte de dados não se limita ao SQL Server; Qualquer fonte de dados pode ser utilizada, desde que os dados possam ser lidos com um ResultSet, RowSet, ou ISQLServerBulkRecord implementação.
Observação
ISQLServerBulkData como fonte de dados não é atualmente totalmente suportada ao usar cópia em massa, e os utilizadores podem encontrar erros ao usar este tipo de fonte de dados. Recomenda-se usar um ResultSet, RowSet, ou ISQLServerBulkRecord em vez disso.
Usando a SQLServerBulkCopy classe, você pode executar:
Uma única operação de cópia em massa
Várias operações de cópia em massa
Uma operação de cópia em massa com uma transação
Observação
Ao usar o Microsoft JDBC Driver 4.1 para SQL Server ou anterior (que não suporta a classe SQLServerBulkCopy), pode executar a instrução SQL Server Transact-SQL BULK INSERT em vez disso.
Exemplo de configuração de cópia em massa
A SQLServerBulkCopy classe pode ser usada para gravar dados somente em tabelas do SQL Server. Os exemplos de código apresentados neste artigo utilizam a base de dados de exemplos do SQL Server, AdventureWorks. Para evitar alterar as tabelas existentes nos exemplos de código, escreva os dados nas tabelas que cria primeiro.
As tabelas BulkCopyDemoMatchingColumns e BulkCopyDemoDifferentColumns são ambas baseadas na tabela AdventureWorks Production.Products. Em exemplos de código que utilizam estas tabelas, os dados são adicionados da Production.Products tabela a uma destas tabelas de exemplo. A BulkCopyDemoDifferentColumns tabela é usada quando o exemplo ilustra como mapear colunas dos dados de origem para a tabela de destino; BulkCopyDemoMatchingColumns é usada para a maioria das outras amostras.
Alguns dos exemplos de código demonstram como usar uma SQLServerBulkCopy classe para gravar em várias tabelas. Para estas amostras, as BulkCopyDemoOrderHeader tabelas e BulkCopyDemoOrderDetail são usadas como tabelas de destino. Estas tabelas baseiam-se nas tabelas Sales.SalesOrderHeader e nas Sales.SalesOrderDetail do AdventureWorks.
Observação
Os SQLServerBulkCopy exemplos de código são fornecidos para demonstrar apenas a sintaxe para o uso de SQLServerBulkCopy. Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, é mais fácil e rápido usar um Transact-SQL INSERT ... Instrução SELECT para copiar os dados.
Configuração de tabela
Para criar as tabelas necessárias para que os exemplos de código sejam executados corretamente, você deve executar as seguintes instruções Transact-SQL em um banco de dados do 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]
Operações de cópia em massa única
A abordagem mais simples para executar uma operação de cópia em massa do SQL Server é executar uma única operação em um banco de dados. Por padrão, uma operação de cópia em massa é executada como uma operação isolada: a operação de cópia ocorre de forma não transacionada, sem oportunidade de revertê-la.
Observação
Se precisar reverter toda ou parte da cópia em massa quando ocorrer um erro, você poderá usar uma SQLServerBulkCopytransação gerenciada ou executar a operação de cópia em massa dentro de uma transação existente.
Para mais informações, consulte Operações de transação e cópia em massa
Os passos gerais para realizar uma operação de cópia em massa são:
Conecte-se ao servidor de origem e obtenha os dados a serem copiados. Os dados também podem vir de outras fontes, desde que possam ser recuperados de um
ResultSetobjeto ou de umaISQLServerBulkRecordimplementação.Conecte-se ao servidor de destino (a menos que pretenda
SQLServerBulkCopyestabelecer uma ligação para si).Crie um objeto
SQLServerBulkCopy, definindo quaisquer propriedades necessárias através desetBulkCopyOptions.Chame o
setDestinationTableNamemétodo para indicar a tabela alvo para a operação de inserção em massa.Ligue para um dos
writeToServermétodos.Opcionalmente, atualize propriedades via
setBulkCopyOptionse chamewriteToServernovamente conforme necessário.Chame
close, ou encapsule as operações de cópia em massa dentro de uma instrução try-with-resources.
Atenção
Recomendamos que os tipos de dados da coluna de origem e de destino coincidam. Se os tipos de dados não coincidirem, SQLServerBulkCopy tenta converter cada valor de origem para o tipo de dado alvo. As conversões podem afetar o desempenho e também podem resultar em erros inesperados. Por exemplo, um tipo de dado duplo pode ser convertido para um tipo de dados decimal na maioria das vezes, mas nem sempre.
Example
A aplicação seguinte demonstra como carregar dados usando a SQLServerBulkCopy classe. Neste exemplo, a ResultSet é usado para copiar dados da tabela Production.Product na base de dados SQL Server AdventureWorks para uma tabela semelhante na mesma base de dados.
Importante
Este exemplo não será executado a menos que tenha criado as tabelas de trabalho conforme descrito na configuração de tabelas. Este código é fornecido para demonstrar a sintaxe apenas para uso SQLServerBulkCopy . Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, é mais fácil e rápido usar um Transact-SQL INSERT ... Instrução SELECT para copiar os dados.
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;
}
}
Realizar uma operação de cópia em massa usando Transact-SQL
O exemplo a seguir ilustra como usar o executeUpdate método para executar a instrução BULK INSERT.
Observação
O caminho do arquivo para a fonte de dados é relativo ao servidor. O processo do servidor deve ter acesso a esse caminho para que a operação de cópia em massa seja bem-sucedida.
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' )");
}
Várias operações de cópia em massa
Você pode executar várias operações de cópia em massa usando uma única instância de uma classe SQLServerBulkCopy. Se os parâmetros de operação mudarem entre cópias (por exemplo, o nome da tabela de destino), deve atualizá-los antes de quaisquer chamadas subsequentes a qualquer um dos writeToServer métodos, como demonstrado no exemplo seguinte. A menos que explicitamente alterados, todos os valores de propriedade para uma determinada instância permanecem os mesmos que estavam na operação de cópia em massa anterior.
Observação
Executar várias operações de cópia em massa usando a mesma instância de SQLServerBulkCopy geralmente é mais eficiente do que usar uma instância separada para cada operação.
Se você executar várias operações de cópia em massa usando o mesmo objeto SQLServerBulkCopy, não haverá restrições sobre se as informações de origem ou destino são iguais ou diferentes em cada operação. No entanto, deve garantir que as informações de associação de coluna sejam configuradas corretamente cada vez que escrever no servidor.
Importante
Este exemplo não será executado a menos que tenha criado as tabelas de trabalho conforme descrito na configuração de tabelas. Este código é fornecido para demonstrar a sintaxe apenas para uso SQLServerBulkCopy . Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, é mais fácil e rápido usar um Transact-SQL INSERT ... Instrução SELECT para copiar os dados.
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;
}
}
Transações e operações de cópia em massa
As operações de cópia em massa podem ser executadas como operações isoladas ou como parte de uma transação de várias etapas. Esta última opção permite-lhe realizar mais do que uma operação de cópia em massa dentro da mesma transação, e realizar outras operações na base de dados (como inserções, atualizações e eliminações), mantendo ainda assim a possibilidade de comprometer ou reverter toda a transação.
Por padrão, uma operação de cópia em massa é executada como uma operação isolada. A operação de cópia em massa ocorre de forma não transacionada, sem oportunidade de revertê-la. Se precisar de reverter total ou parcialmente a cópia em massa quando ocorrer um erro, pode usar uma SQLServerBulkCopytransação gerida ou realizar a operação de cópia em massa dentro de uma transação existente.
Cópia em Massa Estendida para Azure Data Warehouse
A versão do driver v8.4.1 adiciona uma nova propriedade de ligação, sendTemporalDataTypesAsStringForBulkCopy. Esta propriedade booleana é true por defeito.
Esta propriedade de ligação, quando definida para false, enviará os tipos de dados DATE,DATETIME, DATIMETIME2, DATETIMEOFFSET, SMALLDATETIME e TIME como os respetivos tipos em vez de os enviar como String.
Enviar os tipos de dados temporais como os seus respetivos tipos permite ao utilizador enviar dados para essas colunas para o Azure Synapse Analytics, o que antes não era possível devido ao driver converter os dados em String. Enviar dados de strings para colunas temporais funciona para o SQL Server porque o SQL Server faria conversão implícita para nós, mas não é o mesmo com o Azure Synapse Analytics.
Além disso, mesmo sem definir esta cadeia de ligação para 'false', a partir da v8.4.1 , os tipos de dados MONEY e SMALLMONEY serão enviados como tipos de dados MONEY / SMALLMONEY em vez de DECIMAL, o que também permite que esses tipos sejam copiados em massa para o Azure Synapse Analytics.
Limitações do Extended Bulk Copy para o Azure Data Warehouse
Atualmente, existem duas limitações:
Com esta propriedade de ligação definida para
false, o driver só aceitará o formato literal de string predefinido de cada tipo de dado temporal, por exemplo:DATE: YYYY-MM-DDDATETIME: 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:ssTIME: hh:mm:ss[.nnnnnnn]Com esta propriedade de ligação definida para
false, o tipo de coluna especificado para cópia em massa tem de respeitar a tabela de mapeamento de tipos de dados apresentada em Utilização de tipos de dados básicos. Por exemplo, anteriormente os utilizadores podiam especificarjava.sql.Types.TIMESTAMPcopiar dados em massa para umaDATEcoluna, mas com esta funcionalidade ativada, têm de especificarjava.sql.Types.DATEpara fazer o mesmo.
Realização de uma operação de cópia em massa não transacionada
A aplicação seguinte mostra o que acontece quando uma operação de cópia em massa não transacionada encontra um erro a meio da operação.
No exemplo, a tabela de origem e a tabela de destino incluem cada uma coluna de Identidade chamada ProductID. O código prepara primeiro a tabela de destino eliminando todas as linhas e depois inserindo uma única linha cuja ProductID existência é conhecida na tabela de origem. Por defeito, um novo valor para a coluna Identidade é gerado na tabela de destino para cada linha adicionada. Neste exemplo, uma opção é definida quando a ligação é aberta que força o processo de carregamento em massa a usar os valores de Identidade da tabela de origem em vez disso.
A operação de cópia em massa é executada com a BatchSize propriedade definida como 10. Quando a operação encontra a linha inválida, uma exceção é gerada. Neste primeiro exemplo, a operação de cópia em massa não é transacionada. Todos os lotes copiados até ao ponto do erro são confirmados; o lote que contém a chave duplicada é anulado e a operação de cópia em massa é interrompida antes de processar quaisquer outros lotes.
Observação
Este exemplo não será executado a menos que tenha criado as tabelas de trabalho conforme descrito na configuração de tabelas. Este código é fornecido para demonstrar a sintaxe apenas para uso SQLServerBulkCopy . Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, é mais fácil e rápido usar um Transact-SQL INSERT ... Instrução SELECT para copiar os dados.
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;
}
}
Realização de uma operação dedicada de cópia em massa numa transação
Por defeito, uma operação de cópia em massa não cria as transações por si só. Quando quiseres realizar uma operação dedicada de cópia em massa, cria uma nova instância de SQLServerBulkCopy com uma cadeia de ligação. Neste cenário, cada lote da operação de cópia em massa é implicitamente validado pela base de dados. Podes definir a opção UseInternalTransaction para true em SQLServerBulkCopyOptions para fazer com que a operação de cópia em massa crie transações, realizando um commit após cada lote.
SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
copyOptions.setKeepIdentity(true);
copyOptions.setBatchSize(10);
copyOptions.setUseInternalTransaction(true);
Utilização de transações existentes
Pode passar um Connection objeto que tenha transações ativadas como parâmetro num SQLServerBulkCopy construtor. Nesta situação, a operação de cópia em bloco é realizada numa transação existente e não se faz qualquer alteração ao estado da transação (ou seja, não é confirmada ou abortada). Isso permite que um aplicativo inclua a operação de cópia em massa em uma transação com outras operações de banco de dados. Se precisares de reverter toda a operação de cópia em massa porque ocorrer um erro, ou se a cópia em massa for executada como parte de um processo maior que possa ser revertido, podes realizar a reversão do Connection objeto em qualquer momento após a operação de cópia em massa.
A aplicação seguinte é semelhante a BulkCopyNonTransacted, com uma exceção: neste exemplo, a operação de cópia em massa está incluída numa transação externa maior. Quando ocorre o erro de violação de chave primária, toda a transação é revertida e nenhuma linha é adicionada à tabela de destino.
Observação
Este exemplo não será executado a menos que tenha criado as tabelas de trabalho conforme descrito na configuração de tabelas. Este código é fornecido para demonstrar a sintaxe apenas para uso SQLServerBulkCopy . Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, é mais fácil e rápido usar um Transact-SQL INSERT ... Instrução SELECT para copiar os dados.
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;
}
}
Cópia em massa a partir de um ficheiro CSV
A aplicação seguinte demonstra como carregar dados usando a SQLServerBulkCopy classe. Neste exemplo, um ficheiro CSV é usado para copiar dados exportados da tabela Production.Product na base de dados SQL Server AdventureWorks para uma tabela semelhante na base de dados.
Importante
Este exemplo não será executado a menos que tenha criado as tabelas de trabalho conforme descrito na configuração da tabela para o obter.
Abra o SQL Server Management Studio e ligue-se ao SQL Server com a base de dados AdventureWorks.
Expandir as bases de dados, clicar com o botão direito na base de dados AdventureWorks, selecionar Tarefas e Exportar Dados...
Para a fonte de dados, selecione a fonte de dados que lhe permite ligar ao seu SQL Server (por exemplo, SQL Server Native Client 11.0), verifique a configuração e depois Próximo
Para o Destino, selecione o Destino de Ficheiro Plano e insira um Nome de Ficheiro com um destino como
C:\Test\TestBulkCSVExample.csv. Verifica se o Formato está Delimitado, o qualificador de Texto é nenhum, ativa os nomes das Colunas na primeira linha de dados e depois seleciona SeguinteSelecione Escrever uma consulta para especificar os dados a transferir e Próximo. Introduza a sua Instrução SQL
SELECT ProductID, Name, ProductNumber FROM Production.Producte PróximoVerifique a configuração: pode deixar o delimitador de linhas como
{CR}{LF}e o delimitador de colunas como vírgula{,}. Selecione Editar Mapeamentos... e verifique se o Tipo de dado está correto para cada coluna (por exemplo, inteiro paraProductIDe cadeia Unicode para as outras).Avança para Terminar e executa a exportação.
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;
}
}
Usar um carácter regex como delimitador
Observação
Ao definir um delimitador personalizado, escape dele se for um carácter regex como '|'.
SQLServerBulkCSVFileRecord fileRecord = new SQLServerBulkCSVFileRecord(CSVFilePath, null, "\\|", true);
Cópia em massa com delimitadores como dados num ficheiro CSV
A versão 8.4.1 do driver adiciona uma nova API SQLServerBulkCSVFileRecord.setEscapeColumnDelimitersCSV(boolean). Quando definido como verdadeiro, aplicam-se as seguintes regras:
- Cada campo pode ou não estar incluído entre aspas duplas.
- Se os campos não estiverem incluídos com aspas duplas, então as aspas duplas podem não aparecer dentro dos campos.
- Os campos contendo aspas duplas e delimitadores devem estar incluídos entre aspas duplas.
- Se forem utilizadas aspas duplas para demarcar campos, então uma aspas dupla que aparece dentro de um campo deve ser precedida por outra aspas dupla para ser escapada.
Cópia em massa com colunas "Always Encrypted"
A partir do Microsoft JDBC Driver 6.0 para SQL Server, a cópia em massa é suportada com colunas Always Encrypted.
Dependendo das opções de cópia em massa e do tipo de encriptação das tabelas de origem e destino, o driver JDBC pode desencriptar e depois encriptar os dados de forma transparente, ou pode enviar os dados encriptados tal como estão. Por exemplo, ao copiar em massa dados de uma coluna encriptada para uma coluna não encriptada, o driver desencripta os dados de forma transparente antes de enviar para o SQL Server. De forma semelhante, ao copiar em massa dados de uma coluna não encriptada (ou de um ficheiro CSV) para uma coluna encriptada, o driver encripta os dados de forma transparente antes de os enviar para o SQL Server. Se tanto a origem como o destino estiverem encriptados, então, dependendo da allowEncryptedValueModifications opção de cópia em massa, o driver enviaria os dados tal como estão ou desencriptaria os dados e encriptá-los novamente antes de enviarem para o SQL Server.
Para mais informações, consulte a allowEncryptedValueModifications opção de cópia em massa abaixo e Usar Sempre Encriptado com o Driver JDBC.
Importante
Limitação do Microsoft JDBC Driver 6.0 para SQL Server, ao copiar em massa dados de um ficheiro CSV para colunas encriptadas:
Apenas o formato Transact-SQL padrão de string literal é suportado para os tipos de data e hora
Os tipos de dados DATETIME e SMALLDATETIME não são suportados
API de cópia em massa para driver JDBC
SQLServerBulkCopy
Permite-te carregar em massa uma tabela SQL Server de forma eficiente com dados de outra fonte.
O Microsoft SQL Server inclui uma popular utilidade de prompt de comandos chamada bcp para mover dados de uma tabela para outra, seja num único servidor ou entre servidores. A SQLServerBulkCopy classe permite-te escrever soluções de código em Java que oferecem funcionalidades semelhantes. Existem outras formas de carregar dados numa tabela SQL Server (instruções INSERT, por exemplo), mas SQLServerBulkCopy oferecem uma vantagem significativa de desempenho em relação a elas.
A SQLServerBulkCopy classe pode ser usada para gravar dados somente em tabelas do SQL Server. No entanto, a fonte de dados não se limita ao SQL Server; Qualquer fonte de dados pode ser utilizada, desde que os dados possam ser lidos com uma ResultSet instância ou ISQLServerBulkRecord implementação.
| Construtor | Description |
|---|---|
SQLServerBulkCopy(Connection connection) |
Inicializa uma nova instância da SQLServerBulkCopy classe usando a instância aberta especificada de SQLServerConnection. Se o Connection tiver transações ativadas, as operações de cópia serão realizadas dentro dessa transação. |
SQLServerBulkCopy(String connectionURL) |
Inicializa e abre uma nova instância de SQLServerConnection com base no connectionURL. O construtor usa o SQLServerConnection para inicializar uma nova instância da SQLServerBulkCopy classe. |
| Propriedade | Description |
|---|---|
String DestinationTableName |
Nome da tabela de destino no servidor. Se DestinationTableName não foi definido quando writeToServer é chamado, uma SQLServerException é lançada.DestinationTableName é um nome em três partes (<database>.<owningschema>.<name>). Pode qualificar o nome da tabela com a base de dados e o esquema proprietário, se quiser. No entanto, se o nome da tabela usar um sublinhado ("_") ou quaisquer outros caracteres especiais, deve sair do nome usando parênteses circundantes. Para obter mais informações, consulte Database Identifiers. |
ColumnMappings |
Os mapeamentos de colunas definem as relações entre as colunas da fonte de dados e as colunas do destino. Se os mapeamentos não estiverem definidos, as colunas são mapeadas implicitamente com base na posição ordinal. Para que isto funcione, os esquemas de origem e destino têm de coincidir. Se não o fizerem, será lançada uma exceção. Se o mapeamento não estiver vazio, nem todas as colunas presentes na fonte de dados têm de ser especificadas. Os que não estão mapeados são ignorados. Pode referir-se às colunas de origem e destino pelo nome ou ordinal. |
| Método | Description |
|---|---|
void addColumnMapping(int sourceColumn, int destinationColumn) |
Adiciona um novo mapeamento de colunas, usando ordinais para especificar tanto as colunas de origem como de destino. |
void addColumnMapping (int sourceColumn, String destinationColumn) |
Adiciona um novo mapeamento de colunas, usando um ordinal para a coluna de origem e um nome de coluna para a coluna de destino. |
void addColumnMapping (String sourceColumn, int destinationColumn) |
Adiciona um novo mapeamento de colunas, usando um nome de coluna para descrever a coluna de origem e um ordinal para especificar a coluna de destino. |
void addColumnMapping (String sourceColumn, String destinationColumn) |
Adiciona um novo mapeamento de colunas, usando nomes de colunas para especificar tanto as colunas de origem como de destino. |
void clearColumnMappings() |
Limpa o conteúdo dos mapeamentos das colunas. |
void close() |
Fecha a SQLServerBulkCopy instância. |
SQLServerBulkCopyOptions getBulkCopyOptions() |
Recupera o conjunto atual de SQLServerBulkCopyOptions. |
String getDestinationTableName() |
Recuperar o nome atual da tabela de destinos. |
void setBulkCopyOptions(SQLServerBulkCopyOptions copyOptions) |
Atualiza o comportamento da SQLServerBulkCopy instância de acordo com as opções fornecidas. |
void setDestinationTableName(String tableName) |
Define o nome da tabela de destino. |
void writeToServer(ResultSet sourceData) |
Copia todas as linhas do ResultSet fornecido para uma tabela de destino especificada pela propriedade DestinationTableName do objeto SQLServerBulkCopy. |
void writeToServer(RowSet sourceData) |
Copia todas as linhas fornecidas em RowSet para uma tabela de destino especificada pela propriedade DestinationTableName do objeto SQLServerBulkCopy. |
void writeToServer(ISQLServerBulkRecord sourceData) |
Copia todas as linhas da implementação fornecida ISQLServerBulkRecord para uma tabela de destino especificada pela DestinationTableName propriedade do SQLServerBulkCopy objeto. |
SQLServerBulkCopyOptions
Uma coleção de definições que controlam como os writeToServer métodos se comportam numa instância de SQLServerBulkCopy.
| Construtor | Description |
|---|---|
SQLServerBulkCopyOptions() |
Inicializa uma nova instância da SQLServerBulkCopyOptions classe usando os valores predefinidos para todas as definições. |
Existem getters e setters para as seguintes opções:
| Opção | Description | Predefinido |
|---|---|---|
boolean CheckConstraints |
Verifique as restrições enquanto os dados estão a ser inseridos. | Falso - as restrições não são verificadas |
boolean FireTriggers |
Fazer o servidor ativar os gatilhos de inserção para as linhas a serem inseridas na base de dados. | Falso - não são acionados gatilhos |
boolean KeepIdentity |
Preservar os valores de identidade de origem. | False - os valores de identidade são atribuídos pelo destino |
boolean KeepNulls |
Preserve os valores nulos na tabela de destino independentemente das definições para valores padrão. | Falso - os valores nulos são substituídos por valores padrão quando aplicável. |
boolean TableLock |
Obtenha um bloqueio de atualização em massa durante a operação de cópia em massa. | Falso - são usados bloqueios de fila. |
boolean UseInternalTransaction |
Quando definido para true, cada lote da operação de cópia em massa ocorrerá dentro de uma transação. Se SQLServerBulkCopy estiver a usar uma ligação existente (conforme especificado pelo construtor), ocorrerá um SQLServerException . Se SQLServerBulkCopy tiver criado uma ligação dedicada, uma transação será criada e confirmada para cada lote. |
Falso - sem transação |
int BatchSize |
Número de linhas em cada lote. No final de cada lote, as linhas do lote são enviadas para o servidor. Um lote é concluído quando BatchSize as linhas foram processadas ou não há mais linhas para enviar para a fonte de dados de destino. Se a SQLServerBulkCopy instância foi declarada com a UseInternalTransaction opção definida como false, as linhas são enviadas para o servidor BatchSize de uma vez, mas não é tomada nenhuma ação relacionada com transações. Se UseInternalTransaction for definido como true, cada lote de linhas é realizado dentro de uma transação explícita. |
0 - indica que cada writeToServer operação é um único lote |
int BulkCopyTimeout |
Número de segundos para concluir a operação antes de expirar. Um valor de 0 indica que não há limite; a cópia em massa esperará indefinidamente. | 60 segundos. |
boolean allowEncryptedValueModifications |
Esta opção está disponível com o Microsoft JDBC Driver 6.0 (ou superior) para SQL Server. Quando definido para true, allowEncryptedValueModifications permite a cópia em massa de dados encriptados entre tabelas ou bases de dados, sem descifrar os dados. Normalmente, uma aplicação selecionava dados de colunas encriptadas de uma tabela sem descifrar os dados (a aplicação ligava-se à base de dados com a palavra-chave de encriptação de coluna definida para desativada) e depois usava esta opção para inserir em massa os dados, que ainda estavam encriptados. Para mais informações, consulte Usar Sempre Encriptado com o Driver JDBC.Tenha cautela ao definir allowEncryptedValueModifications para, true pois isso pode levar a corromper a base de dados porque o driver não verifica se os dados estão realmente encriptados, ou se estão corretamente encriptados usando o mesmo tipo de encriptação, algoritmo e chave da coluna de destino. |
Lançadores e levantadores:
| Methods | Description |
|---|---|
boolean isCheckConstraints() |
Indica se as restrições devem ser verificadas enquanto os dados estão a ser inseridos ou não. |
void setCheckConstraints(boolean checkConstraints) |
Define se as restrições devem ser verificadas enquanto os dados estão a ser inseridos ou não. |
boolean isFireTriggers() |
Indica se o servidor deve ativar os gatilhos de inserção para as linhas inseridas na base de dados. |
void setFireTriggers(boolean fireTriggers) |
Define se o servidor deve ser configurado para disparar gatilhos para as linhas inseridas na base de dados. |
boolean isKeepIdentity() |
Indica se deve ou não preservar quaisquer valores de identidade de origem. |
void setKeepIdentity(boolean keepIdentity) |
Define se deve ou não preservar os valores de identidade. |
boolean isKeepNulls() |
Indica se deve preservar os valores nulos na tabela de destino independentemente das definições para valores predefinidos, ou se devem ser substituídos pelos valores predefinidos (quando aplicável). |
void setKeepNulls(boolean keepNulls) |
Definir se devem ser preservados os valores nulos na tabela de destino, independentemente das definições para valores por defeito, ou se devem ser substituídos pelos valores por defeito (quando aplicável). |
boolean isTableLock() |
Indica se SQLServerBulkCopy deve obter um bloqueio de atualização em massa durante a duração da operação de cópia em massa. |
void setTableLock(boolean tableLock) |
Define se SQLServerBulkCopy deve obter um bloqueio de atualização em massa durante a duração da operação de cópia em massa. |
boolean isUseInternalTransaction() |
Indica se cada lote da operação de cópia em massa ocorrerá dentro de uma transação. |
void setUseInternalTransaction(boolean useInternalTransaction) |
Define se cada lote das operações de cópia em massa ocorrerá dentro de uma transação ou não. |
int getBatchSize() |
Obtém o número de linhas em cada lote. No final de cada lote, as linhas do lote são enviadas para o servidor. |
void setBatchSize(int batchSize) |
Define o número de linhas em cada lote. No final de cada lote, as linhas do lote são enviadas para o servidor. |
int getBulkCopyTimeout() |
Obtém o número de segundos para concluir a operação antes de expirar. |
void setBulkCopyTimeout(int timeout) |
Define-se o número de segundos para a operação ser concluída antes de esgotar o tempo limite. |
boolean isAllowEncryptedValueModifications() |
Indica se allowEncryptedValueModifications a configuração está ativada ou desativada. |
void setAllowEncryptedValueModifications(boolean allowEncryptedValueModifications) |
Configura a allowEncryptedValueModifications configuração usada para cópia em massa com colunas Always Encrypted. |
ISQLServerBulkRecord
A ISQLServerBulkRecord interface pode ser usada para criar classes que leem dados de qualquer fonte (como um ficheiro) e permitem que uma SQLServerBulkCopy instância carregue em massa uma tabela SQL Server com esses dados.
| Métodos de Interface | Description |
|---|---|
set<Integer> getColumnOrdinals() |
Obtenha os ordinais de cada uma das colunas representadas neste registo de dados. |
String getColumnName(int column) |
Obtenha o nome da coluna dada. |
int getColumnType(int column) |
Obtenha o tipo de dado JDBC da coluna dada. |
int getPrecision(int column) |
Obtém a precisão para a dada coluna. |
object[] getRowData() |
Obtém os dados da linha atual como um array de Objetos. Cada Objeto deve corresponder ao Tipo de linguagem Java usado para representar o tipo de dado JDBC indicado para a coluna dada. Para mais informações, consulte Compreensão dos Tipos de Dados do Driver JDBC para os mapeamentos apropriados. |
int getScale(int column) |
Obtenha a escala da coluna dada. |
boolean isAutoIncrement(int column) |
Indica se a coluna representa uma coluna de identidade. |
boolean next() |
Avança para a próxima linha de dados. |
SQLServerBulkCSVFileRecord
Uma implementação simples da ISQLServerBulkRecord interface que pode ser usada para ler os tipos de dados Java básicos a partir de um ficheiro delimitado onde cada linha representa uma linha de dados.
Notas de Implementação e Limitações:
A quantidade máxima de dados permitida numa dada linha é limitada pela memória disponível porque os dados são lidos linha de cada vez.
O streaming de grandes tipos de dados como
varchar(max),varbinary(max),nvarchar(max),sqlxml, entextnão é suportado.O delimitador especificado para o ficheiro CSV não deve aparecer em nenhum lugar dos dados e deve ser devidamente escapado se for um caractere restrito nas expressões regulares Java.
Na implementação do ficheiro CSV, as aspas duplas são tratadas como parte dos dados. Por exemplo, a linha
hello,"world","hello,world"seria tratada como tendo quatro colunas com os valoreshello,"world","helloeworld"se o delimitador for uma vírgula.Caracteres de nova linha são usados como terminadores de linha e não são permitidos em nenhuma parte dos dados.
| Construtor | Description |
|---|---|
SQLServerBulkCSVFileRecord(String fileToParse, String encoding, String delimiter, boolean firstLineIsColumnNames) |
Inicializa uma nova instância da classe SQLServerBulkCSVFileRecord que irá analisar cada linha em fileToParse utilizando o delimitador e a codificação fornecidos. Se firstLineIsColumnNames estiver definido como Verdadeiro, a primeira linha do ficheiro será analisada como nomes de colunas. Se a codificação for NULL, será usada a codificação padrão. |
SQLServerBulkCSVFileRecord(String fileToParse, String encoding, boolean firstLineIsColumnNames) |
Inicializa uma nova instância da classe SQLServerBulkCSVFileRecord que irá analisar cada linha em fileToParse com uma vírgula como delimitador e a codificação fornecida. Se firstLineIsColumnNames estiver definido como Verdadeiro, a primeira linha do ficheiro será analisada como nomes de colunas. Se a codificação for NULL, será usada a codificação padrão. |
SQLServerBulkCSVFileRecord(String fileToParse, boolean firstLineIsColumnNames |
Inicializa uma nova instância da SQLServerBulkCSVFileRecord classe que irá analisar cada linha do fileToParse com uma vírgula como delimitador e codificação por defeito. Se firstLineIsColumnNames estiver definido como Verdadeiro, a primeira linha do ficheiro será analisada como nomes de colunas. |
| Método | Description |
|---|---|
void addColumnMetadata(int positionInFile, String columnName, int jdbcType, int precision, int scale) |
Adiciona metadados para a coluna dada no ficheiro. |
void close() |
Liberta quaisquer recursos associados ao leitor de ficheiros. |
void setTimestampWithTimezoneFormat(DateTimeFormatter dateTimeFormatter) |
Define o formato para analisar os dados de carimbo temporal do ficheiro como java.sql.Types.TIMESTAMP_WITH_TIMEZONE. |
void setTimestampWithTimezoneFormat(String dateTimeFormat) |
Define o formato para análise dos dados de tempo do ficheiro como java.sql.Types.TIME_WITH_TIMEZONE. |
void setTimeWithTimezoneFormat(DateTimeFormatter dateTimeFormatter) |
Define o formato para análise dos dados de tempo do ficheiro como java.sql.Types.TIME_WITH_TIMEZONE. |
void setTimeWithTimezoneFormat(String timeFormat) |
Define o formato para análise dos dados de tempo do ficheiro como java.sql.Types.TIME_WITH_TIMEZONE. |