bcp_init
Инициализирует операцию массового копирования.
Синтаксис
RETCODE bcp_init (
HDBC
hdbc
,
LPCTSTR
szTable
,
LPCTSTR
szDataFile
,
LPCTSTR
szErrorFile
,
INT
eDirection
);
Аргументы
hdbc
Дескриптор соединения ODBC с поддержкой массового копирования.
szTable
Имя таблицы базы данных, в которую (или из которой) выполняется копирование. Это имя также может включать имя базы данных или владельца. Например, pubs.gracie.titles, pubs.. titles, gracie.titles и titles — это легальные имена таблиц.
Если eDirection DB_OUT, szTable также может быть именем представления базы данных.
Если параметр eDirection DB_OUT и инструкция SELECT указана с помощью bcp_control перед вызовом bcp_exec , bcp_initszTable необходимо задать значение NULL.
szDataFile
Имя пользовательского файла, в который или из которого выполняется копирование. Если данные копируются непосредственно из переменных с помощью bcp_sendrow, задайте для szDataFile значение NULL.
szErrorFile
Имя файла ошибок, заполняемого сообщениями о ходе работы, сообщениями об ошибках и копиями строк, которые по каким-либо причинам не могут быть скопированы из пользовательского файла в таблицу. Если значение NULL передается как szErrorFile, файл ошибки не используется.
eDirection
Направление копирования (DB_IN или DB_OUT). Значение DB_IN указывает на копирование из переменных программы или пользовательского файла в таблицу. Значение DB_OUT указывает на копирование из таблицы базы данных в пользовательский файл. Если используется значение DB_OUT, необходимо указать имя пользовательского файла.
Возвращаемое значение
SUCCEED или FAIL.
Комментарии
Вызовите bcp_init перед вызовом любой другой функции массового копирования. bcp_init выполняет необходимые инициализации для массового копирования данных между рабочей станцией и SQL Server.
Функция bcp_init должна быть предоставлена с дескриптором подключения ODBC, включенным для использования с функциями массового копирования. Чтобы включить дескриптор, используйте SQLSetConnectAttr с SQL_COPT_SS_BCP для SQL_BCP_ON выделенного, но не подключенного дескриптора подключения. Попытка назначения атрибута для подключенного дескриптора приведет к ошибке.
При указании файла данных bcp_init проверяет структуру источника базы данных или целевой таблицы, а не файла данных. bcp_init задает значения формата данных для файла данных на основе каждого столбца в таблице базы данных, представлении или результирующем наборе SELECT. Эта спецификация включает тип данных каждого столбца, присутствие или отсутствие длины и допустимости значений NULL и строки байтов признака конца, а также ширину для типов данных с фиксированной длиной. bcp_init задает эти значения следующим образом:
Указанный тип данных представляет собой тип данных столбца в таблице базы данных, представлении или результирующем наборе SELECT. Тип данных перечисляется SQL Server собственными типами данных, указанными в sqlncli.h. Сами данные представляются в машинной форме. То есть данные из столбца целочисленного типа данных представлены четырехбайтовой последовательностью, которая является большим или маленьким эндианом на основе компьютера, создавшего файл данных.
Если тип данных базы данных имеет фиксированную длину, то для данных файла данных также задается фиксированная длина. Функции массового копирования, обрабатывающие данные (например, bcp_exec), анализируют строки данных, ожидая, что длина данных в файле данных будет идентична длине данных, указанной в таблице базы данных, представлении или списке столбцов SELECT. Например, данные для столбца базы данных, определенного как char(13), должны быть представлены 13 символами для каждой строки данных в файле. Данные фиксированной длины могут быть обозначены префиксом с признаком значения NULL, если столбец базы данных допускает значения NULL.
После определения последовательности байт, служащей признаком конца, ее длина устанавливается в значение 0.
При копировании в SQL Server файл данных должен содержать данные для каждого столбца в таблице базы данных. При копировании из SQL Server данные из всех столбцов в таблице базы данных, представлении или результирующем наборе SELECT копируются в файл данных.
При копировании в SQL Server порядковый номер столбца в файле данных должен быть идентичен порядковой позиции столбца в таблице базы данных. При копировании из SQL Server bcp_exec помещает данные на основе порядкового положения столбца в таблице базы данных.
Если тип данных базы данных имеет переменную длину (например, varbinary(22)) или столбец базы данных может содержать значения NULL, данные в файле данных префиксируются индикатором длины или null. Ширина признака изменяется в зависимости от типа данных и версии массового копирования.
Чтобы изменить значения формата данных, указанные для файла данных, вызовите bcp_columns и bcp_colfmt.
Массовые копии в SQL Server можно оптимизировать для таблиц, не содержащих индексов, задав для модели восстановления базы данных значение SIMPLE или BULK_LOGGED. Дополнительные сведения см. в разделе Предварительные требования для минимального ведения журнала при массовом импорте и ALTER DATABASE.
Если файл данных не используется, необходимо вызвать bcp_bind, чтобы указать формат и расположение в памяти каждого столбца данных, а затем скопировать строки данных в SQL Server с помощью bcp_sendrow.
Пример
В этом образце демонстрируется использование функции ODBC bcp_init с файлом форматирования.
Перед компиляцией и выполнением кода на С++ необходимо выполнить следующие действия.
Создайте источник данных ODBC с именем Test. Его можно сопоставить с любой базой данных.
Выполните следующий код Transact-SQL в базе данных:
CREATE TABLE BCPDate (cola int, colb datetime);
В каталог, где будет запускаться приложение, добавьте файл Bcpfmt.fmt и добавьте в этот файл следующик код:
8.0 2 1SQLCHAR04"\t"1colaSQL_Latin1_General_Cp437_Bin 2SQLCHAR08"\r\n"2colbSQL_Latin1_General_Cp437_Bin
В каталог, где будет запускаться приложение, добавьте файл Bcpodbc.bcp и добавьте в этот файл следующик код:
1 2
Теперь все готово к компиляции и выполнению кода на C++.
// compile with: odbc32.lib sqlncli11.lib
#include <stdio.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC;
void Cleanup() {
if (hdbc1 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
int main() {
RETCODE retcode;
SDWORD cRows;
// 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 BCP 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 SQL Server DSN using Windows NT authentication.
retcode = SQLConnect(hdbc1, (UCHAR*)"Test", 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, "BCPDate", "BCPODBC.bcp", NULL, DB_IN);
if ( (retcode != SUCCEED) ) {
printf("bcp_init(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Read the format file.
retcode = bcp_readfmt(hdbc1, "BCPFMT.fmt");
if ( (retcode != SUCCEED) ) {
printf("bcp_readfmt(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Execute the bulk copy.
retcode = bcp_exec(hdbc1, &cRows);
if ( (retcode != SUCCEED) ) {
printf("bcp_exec(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
printf("Number of rows bulk copied in = %d.\n", cRows);
// Cleanup
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}