如何使用 C++ ODBC API 存储varbinary(max)
和varchar(max)
列。这里有什么建议吗?
我正在使用 SQL Server 本机客户端。
我正在使用按列绑定绑定参数数组。这里的目的是一次准备语句并一次插入/更新多行以提高性能。我从这个链接获得了一个示例代码, https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/binding-arrays-of-parameters?view=sql-server-ver15
还找到了这个链接,其中给出了 SQLPutData 的使用。 https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlputdata-function?view=sql-server-ver15 但在此链接中,示例是使用SQL_LEN_DATA_AT_EXEC给出的,即列的长度在编译时间。当数据长度未知之前或同一列的数据长度每行都发生变化时,解决方案应该是什么。在这种情况下我们应该如何绑定这些列?
我尝试将SQL_SS_LENGTH_UNLIMITED作为columnsize 参数传递给SQLBindPatameter,但这甚至无法编译。
我还尝试将 0 作为 columnSize 参数传递给 SQLBindParameter,希望它能以某种方式工作,但这也不起作用。
我有一个名为“Parts”的表,其中 2 列中有 5 列,varchar(MAX)
我正在尝试插入 3 行。下面是我的代码。我将TEXTSIZE 定义为 12000。由于我的示例应用程序数据长度不会超过 12000,因此我暂时使用此值。但在实际应用程序中,数据可能比这更大。
示例应用程序代码
SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
PartIDArray, 0, PartIDIndArray);
SQLBindParameter(hstmt1, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
DescArray, DESC_LEN, DescLenOrIndArray);
SQLBindParameter(hstmt1, 3, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 7, 0,
PriceArray, 0, PriceIndArray);
retcode = SQLBindParameter(hstmt1, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, TEXTSIZE, 0,
(VOID *)4, 0, cbTextSize);
retcode = SQLBindParameter(hstmt1, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, TEXTSIZE, 0,
(VOID *)5, 0, cbTextSize1);
for (i = 0; i < ARRAY_SIZE; i++) {
//GetNewValues(&PartIDArray[i], DescArray[i], &PriceArray[i]);
std::cout << "Enter the value for PartID(integer)" << std::endl;
std::cin >> PartIDArray[i];
std::cout<< std::endl;
std::cout << "Enter the value for description(string)" << std::endl;
std::cin >> DescArray[i];
std::cout << std::endl;
std::cout << "Enter the value for price(integer)" << std::endl;
std::cin >> PriceArray[i];
std::cout << std::endl;
PartIDIndArray[i] = 0;
DescLenOrIndArray[i] = SQL_NTS;
PriceIndArray[i] = 0;
cbTextSize[i] = SQL_DATA_AT_EXEC;
cbTextSize1[i] = SQL_DATA_AT_EXEC;
}
retcode = SQLPrepare(hstmt1, (SQLCHAR*)TEXT("INSERT INTO Parts (PartID, Description, Price, memo, memo1) VALUES (?, ?, ?, ?, ?)"), SQL_NTS);
// Execute the statement.
retcode = SQLExecute(hstmt1);
if ((retcode != SQL_SUCCESS) && (retcode != SQL_NEED_DATA) && (retcode != SQL_SUCCESS_WITH_INFO)) {
printf("SQLExecDirect Failed\n\n");
Cleanup();
return(9);
}
PTR pParmID;
int index1 = -1;
for (i = 0; i < 6; i++)
{
if (i % 2 == 0)
index1++;
retcode = SQLParamData(hstmt1, &pParmID);
size_t index = ((size_t)pParmID) - 4;
char* data = Data[index][index1];
lbytes = strlen(data);
if (retcode == SQL_NEED_DATA) {
while (lbytes > 256) {
retcode = SQLPutData(hstmt1, (SQLPOINTER)data, 256);
lbytes -= 256;
}
// Put final batch.
retcode = SQLPutData(hstmt1, (SQLPOINTER)data, lbytes);
}
if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) {
printf("SQLParamData Failed\n\n");
Cleanup();
return(9);
}
}
// Make final SQLParamData call.
retcode = SQLParamData(hstmt1, &pParmID);
if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) {
printf("Final SQLParamData Failed\n\n");
Cleanup();
return(9);
}
如果我们对此有任何解决方案,请告诉我。