不知道长度时如何在SQL Server中存储varbinary(max)和varchar(max)数据(使用C ++ ODBC)

问题描述 投票:1回答: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);
    }

请让我知道我们是否对此有任何解决方案。

c++ sql-server odbc large-data sqlbindparameter
1个回答
0
投票

如果我没记错的话,我已经使用SQLDescribeParam Function从数据源中动态查询了该信息。

[而且,如果我没记错的话,如果您只想传输对Transfer Octet Length感兴趣的二进制值,而如果要以字符串形式获取结果,则可能要获取Display Size

抱歉,我不记得详细信息,但是我很确定在这里的那些页面上可以动态获取所需的尺寸作为切入点:

请注意驱动程序返回的结果代码是什么-一些数据库/驱动程序不支持预先计算这些值,因此您需要对要支持的每个数据库/驱动程序进行测试。祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.