在调用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();
}
你不能只在没有数据ptr的情况下调用SQLGetData,并且设置StrLen_or_IndPtr,驱动程序会将大小写入StrLen_or_IndPtr。
你不能。
至少不是安全,通用的方式。 Microsoft documentation说:
长度/指示符缓冲区中返回的值在每次调用中减少前一次调用中返回的字节数,尽管驱动程序通常无法发现可用数据量并返回字节长度为SQL_NO_TOTAL。
(强调我的)
让我给你举个例子:
NVARCHAR
。SQLGetData
转换,同时将数据从其获取缓冲区复制到目标缓冲区。调用没有指针的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;