Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este exemplo mostra como usar funções de cópia em massa para copiar dados em massa de variáveis de programa para o SQL Server usando bcp_bind e bcp_sendrow. (O código de verificação de erros é removido para simplificar este exemplo.)
Este exemplo foi desenvolvido para o ODBC versão 3.0 ou posterior.
Observação de segurança Quando possível, use a Autenticação do Windows. Se a Autenticação do Windows não estiver disponível, solicite que os usuários insiram suas credenciais em tempo de execução. Evite armazenar credenciais em um arquivo. Se você precisar persistir as credenciais, deverá criptografá-las com a cryptoAPI do Win32.
Para usar funções de cópia em massa diretamente em variáveis de programa
Aloque um identificador de ambiente e um identificador de conexão.
Defina SQL_COPT_SS_BCP e SQL_BCP_ON para habilitar operações de cópia em massa.
Conecte-se ao SQL Server.
Chame bcp_init para definir as seguintes informações:
O nome da tabela ou exibição para copiar em massa de ou para.
Especifique NULL para o nome do arquivo de dados.
O nome de um arquivo de dados para receber mensagens de erro de cópia em massa (especifique NULL se você não quiser um arquivo de mensagem).
A direção da cópia: DB_IN do aplicativo para a exibição ou tabela ou DB_OUT para o aplicativo da tabela ou exibição.
Chame bcp_bind para cada coluna na cópia em massa para associar a coluna a uma variável de programa.
Preencha as variáveis de programa com dados e chame bcp_sendrow para enviar uma linha de dados.
Depois que várias linhas tiverem sido enviadas, chame bcp_batch para verificar as linhas já enviadas. É uma boa prática chamar bcp_batch pelo menos uma vez por 1000 linhas.
Depois que todas as linhas tiverem sido enviadas, chame bcp_done para concluir a operação.
Você pode variar o local e o comprimento das variáveis de programa durante uma operação de cópia em massa chamando bcp_colptr e bcp_collen. Use bcp_control para definir várias opções de cópia em massa. Use bcp_moretext para enviar texte ntextimage dados em segmentos para o servidor.
Exemplo
Este exemplo não tem suporte em IA64.
Você precisará de uma fonte de dados ODBC chamada AdventureWorks, cujo banco de dados padrão é o banco de dados de exemplo adventureworks. (Você pode baixar o banco de dados de exemplo adventureworks na home page de Exemplos do Microsoft SQL Server e Projetos da Comunidade .) Essa fonte de dados deve ser baseada no driver ODBC fornecido pelo sistema operacional (o nome do driver é "SQL Server"). Se você criar e executar este exemplo como um aplicativo de 32 bits em um sistema operacional de 64 bits, deverá criar a fonte de dados ODBC com o Administrador ODBC no %windir%\SysWOW64\odbcad32.exe.
Este exemplo se conecta à instância padrão do SQL Server do computador. Para se conectar a uma instância nomeada, altere a definição da fonte de dados ODBC para especificar a instância usando o seguinte formato: servidor\namedinstance. Por padrão, o SQL Server Express é instalado em uma instância nomeada.
Execute a primeira listagem de código (Transact-SQL) para criar tabelas que o exemplo usará.
Compile a segunda listagem de código (C++) com odbc32.lib e odbcbcp.lib. Se você criou com MSBuild.exe, copie Bcpfmt.fmt e Bcpodbc.bcp do diretório do projeto para o diretório com o .exe e invoque o .exe.
Execute a terceira listagem de código (Transact-SQL) para excluir as tabelas usadas pelo exemplo.
// compile with: odbc32.lib odbcbcp.lib
use AdventureWorks
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'BCPSource')
DROP TABLE BCPSource
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'BCPTarget')
DROP TABLE BCPTarget
GO
CREATE TABLE BCPSource (cola int PRIMARY KEY, colb CHAR(10) NULL)
INSERT INTO BCPSource (cola, colb) VALUES (1, 'aaa')
INSERT INTO BCPSource (cola, colb) VALUES (2, 'bbb')
CREATE TABLE BCPTarget (cola int PRIMARY KEY, colb CHAR(10) NULL)
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC;
SQLHSTMT hstmt2 = SQL_NULL_HSTMT;
void Cleanup() {
if (hstmt2 != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
if (hdbc1 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
}
if (hdbc2 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
int main() {
RETCODE retcode;
// BCP variables.
char *terminator = "\0";
// bcp_done takes a different format return code because it returns number of rows bulk copied
// after the last bcp_batch call.
DBINT cRowsDone = 0;
// Set up separate return code for bcp_sendrow so it is not using the same retcode as SQLFetch.
RETCODE SendRet;
// Column variables. cbCola and cbColb must be defined right before Cola and szColb because
// they are used as bulk copy indicator variables.
struct ColaData {
int cbCola;
SQLINTEGER Cola;
} ColaInst;
struct ColbData {
int cbColb;
SQLCHAR szColb[11];
} ColbInst;
// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(Env) Failed\n\n");
Cleanup();
return(9);
}
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
Cleanup();
return(9);
}
// Allocate ODBC connection handle, set bulk copy mode, and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetConnectAttr(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// sample uses Integrated Security, create the SQL Server DSN using Windows NT authentication
retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"", SQL_NTS, (UCHAR*)"", SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLConnect() Failed\n\n");
Cleanup();
return(9);
}
// Initialize the bulk copy.
retcode = bcp_init(hdbc1, "AdventureWorks..BCPTarget", NULL, NULL, DB_IN);
if ( (retcode != SUCCEED) ) {
printf("bcp_init(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Bind the program variables for the bulk copy.
retcode = bcp_bind(hdbc1, (BYTE *)&ColaInst.cbCola, 4, SQL_VARLEN_DATA, NULL, (INT)NULL, SQLINT4, 1);
if ( (retcode != SUCCEED) ) {
printf("bcp_bind(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Could normally use strlen to calculate the bcp_bind cbTerm parameter, but this terminator
// is a null byte (\0), which gives strlen a value of 0. Explicitly give cbTerm a value of 1.
retcode = bcp_bind(hdbc1, (BYTE *)&ColbInst.cbColb, 4, 11, (UCHAR*)terminator, 1, SQLCHARACTER, 2);
if ( (retcode != SUCCEED) ) {
printf("bcp_bind(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Allocate second ODBC connection handle so bulk copy and cursor operations do not conflict.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc2);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hdbc2) Failed\n\n");
Cleanup();
return(9);
}
// Sample uses Integrated Security, create SQL Server DSN using Windows NT authentication.
retcode = SQLConnect(hdbc2, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"", SQL_NTS, (UCHAR*)"", SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLConnect() Failed\n\n");
Cleanup();
return(9);
}
// Allocate ODBC statement handle.
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc2, &hstmt2);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hstmt2) Failed\n\n");
Cleanup();
return(9);
}
SQLLEN lDataLengthA;
SQLLEN lDataLengthB;
// Bind the SELECT statement to the same program variables bound to the bulk copy operation.
retcode = SQLBindCol(hstmt2, 1, SQL_C_SLONG, &ColaInst.Cola, 0, &lDataLengthA);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLBindCol(hstmt2) Failed\n\n");
Cleanup();
return(9);
}
retcode = SQLBindCol(hstmt2, 2, SQL_C_CHAR, &ColbInst.szColb, 11, &lDataLengthB);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLBindCol(hstmt2) Failed\n\n");
Cleanup();
return(9);
}
// Execute SELECT statement to build a cursor containing data to be bulk copied to new table.
retcode = SQLExecDirect(hstmt2, (UCHAR*)"SELECT * FROM BCPSource", SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLExecDirect Failed\n\n");
Cleanup();
return(9);
}
// Go into a loop fetching rows from the cursor until each row is fetched. Because the
// bcp_bind calls and SQLBindCol calls each reference the same variables, each fetch fills
// the variables used by bcp_sendrow, so all you have to do to send the data to SQL Server is
// to call bcp_sendrow.
while ( (retcode = SQLFetch(hstmt2) ) != SQL_NO_DATA) {
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLFetch Failed\n\n");
Cleanup();
return(9);
}
ColaInst.cbCola = (int)lDataLengthA;
ColbInst.cbColb = (int)lDataLengthB;
if ( (SendRet = bcp_sendrow(hdbc1) ) != SUCCEED ) {
printf("bcp_sendrow(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
}
// Signal the end of the bulk copy operation.
cRowsDone = bcp_done(hdbc1);
if ( (cRowsDone == -1) ) {
printf("bcp_done(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
printf("Number of rows bulk copied after last bcp_batch call = %d.\n", cRowsDone);
// Cleanup.
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
use AdventureWorks
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'BCPSource')
DROP TABLE BCPSource
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'BCPTarget')
DROP TABLE BCPTarget
GO
Consulte Também
Cópia em massa com os Tópicos de Instruções do Driver ODBC do SQL Server (ODBC)
Cópia em massa de variáveis de programa