1

如何使用 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);
    }

如果我们对此有任何解决方案,请告诉我。

4

1 回答 1

0

如果我没记错的话,我已经使用SQLDescribeParam Function.

而且,如果我没记错的话,如果您只想传输您Transfer Octet LengthDisplay Size.

抱歉,我不记得细节了,但我很确定动态获取所需大小的入口点在这些页面上:

注意驱动程序作为结果代码返回的内容 - 一些数据库/驱动程序不支持提前计算这些值,因此您需要测试您想要支持的每个数据库/驱动程序。祝你好运

于 2020-06-09T14:08:59.367 回答