如何在调用SQLGetData之前知道数据的大小

问题描述 投票:2回答:3

在调用SQLGetData函数之前,我想知道表中可用数据的确切大小。目前我遵循下面列出的代码,这对我有用,但我不确定它是否安全。

谁能帮我?

char*ptr = new char[0];


        if (retcode = SQLGetData(hstmt, 31, SQL_C_BINARY, ptr,0,&cbfdata) != SQL_NO_DATA)
        {
            delete[] ptr;
            vector<char> vec(cbfdata);

            SQLGetData(hstmt, 31, SQL_C_BINARY, &vec[0],cbfdata,&cbfdata);

            ofstream fout;
            fout.open(file,ios::binary);
            fout.write(&vec[0],cbfdata);
            fout.close();
            vec.clear();
        }
c++ odbc
3个回答
0
投票

你不能只在没有数据ptr的情况下调用SQLGetData,并且设置StrLen_or_IndPtr,驱动程序会将大小写入StrLen_or_IndPtr。


0
投票

你不能。

至少不是安全,通用的方式。 Microsoft documentation说:

长度/指示符缓冲区中返回的值在每次调用中减少前一次调用中返回的字节数,尽管驱动程序通常无法发现可用数据量并返回字节长度为SQL_NO_TOTAL。

(强调我的)


让我给你举个例子:

  1. 我们假设您的字段在结果集中的类型为NVARCHAR
  2. 您的目标缓冲区是C字符串。
  3. 因此,ODBC驱动程序必须从宽字符转换为窄字符。
  4. 驱动程序可以选择在“动态”执行SQLGetData转换,同时将数据从其获取缓冲区复制到目标缓冲区。
  5. 一个宽字符(在驱动程序的提取缓冲区中)可以在目标缓冲区中占用1,2,3或4个字节。除非数据实际已被转换,否则无法判断。如果一步完成转换和复制,那么......

-1
投票

调用没有指针的SQLGetData(NULL)在cbfdata中返回7,这不是实际大小。

我尝试创建0大小的指针,并在其他小项目中删除它。它没有失败。

但是没有冒险,我通过在结尾放置删除和增加大小来改善代码

到1个字节。

        char*ptr = new char[1];

        if (retcode = SQLGetData(hstmt, 31, SQL_C_BINARY, ptr,0,&cbfdata) != SQL_NO_DATA)
        {
            vector<char> vec(cbfdata);
            SQLGetData(hstmt, 31, SQL_C_BINARY, &vec[0],cbfdata,&cbfdata);

            ofstream fout;
            fout.open(file,ios::binary);
            fout.write(&vec[0],cbfdata);
            fout.close();
            vec.clear();
        }
        delete[] ptr;
© www.soinside.com 2019 - 2024. All rights reserved.