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

时间:2012-11-11 12:05:16

标签: c++ odbc

我想在调用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();
        }

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

你不能。

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

  

长度/指示符缓冲区中返回的值在每个   通过上一次调用返回的字节数进行调用,尽管   驾驶员无法发现   可用数据并返回SQL_NO_TOTAL的字节长度

(重点是我的)


让我给你举个例子:

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

答案 2 :(得分:-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;