使用C ++代码,我试图使用存储过程将大型二进制blob插入到MS SQL服务器中。我要插入的表有5列,类型:
int
varchar
datetime
varbinary(max)
datetime
存储过程需要4个参数:
PROCEDURE [dbo].[spr_fff]
@act AS INT
,@id AS VARCHAR(255)
,@timestamp AS DATETIME
,@blob AS VARBINARY(MAX)
我设置了我的声明(检查了我没有显示的返回值):
const std::string queryString("{Call [spr_fff](?,?,?,?)}");
SQLHSTMT handle = NULL;
SQLAllocHandle(SQL_HANDLE_STMT, m_hConn, &handle);
SQLPrepare(handle, (SQLCHAR *)queryString.c_str(), SQL_NTS);
我绑定前三个参数没有问题,但我似乎无法弄清楚如何绑定第四个参数。代码基本上是:
std::string sData; getData(sData); //fills sData with the binary data
SQLLEN len1 = ???;
SQLBindParameter( handle, (SQLUSMALLINT)4, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, len1, 0, (SQLCHAR*)&sData.c_str(), (SQLLEN)sData.size(), NULL);
并且诀窍似乎在弄清楚len1应该是什么。如果sData.size() < 8000
,那么len1 = sData.size()
工作正常。但如果sData.size() > 8000
,似乎没有任何效果。如果我设置len1 = sData.size()
或len1 = 2147483647
,则对SQLBindParameter
的调用会导致错误代码&#34;无效的精度值&#34;。如果我将len1 = 0
设置为某些(可怕的)文档似乎建议,对SQLBindParameter
的调用有效(对于2008本机驱动程序),但执行该语句会产生一个大小为2的blob,即两个默认的0字节,所有输入blob数据都截断为0字节。我已经尝试了所有这些组合与下面列出的所有客户端驱动程序,都无济于事。我做错了什么?????
环境
客户端操作系统:Windows XP sp3
SQL Server是
Microsoft SQL Server 09.00.3042
SQL客户端尝试过:
Microsoft SQL Server Native Client版本10.00.5500(sqlncli10.dll,2007.100.5500.00)
Microsoft SQL Native Client版本09.00.5000(sqlncli.dll,2005.90.5000.00)
Microsoft SQL Server ODBC驱动程序版本03.85.1132(sqlsrv32.dll 2000.85.1132.0)
答案 0 :(得分:3)
好的,我的问题的答案实际上是我搞砸了SQLBindParameter
的电话。如果你查看我上面的代码,我的最后一个参数为NULL。仔细阅读文档 - 相信我,需要仔细阅读! - 显示如果最终参数为NULL,则将数据视为零终止。 (the documentation for SQLBindParameter
说“如果StrLen_or_IndPtr是空指针,则驱动程序假定所有输入参数值都是非NULL ,并且该字符和二进制数据是以空值终止的。” - 强调我的并且,由于不幸的巧合,我提供的数据的第二个或第三个字节为零,因此实际存储的blob只有1或2个字节。不确定为什么它的尺寸小于8000 - 可能有一些尺寸&lt; 8000和各种驱动程序版本的相互作用,但我还没有花时间去挑逗它。
此外,在上面的代码中我说“如果我设置len1 = 0
,因为某些(可怕的)文档似乎暗示,”。事实上,这是正确的事情。
因此正确的代码
SQLLEN len1 = 0;
SQLLEN nThisLen = (SQLLEN)sData.size();
SQLBindParameter( handle, (SQLUSMALLINT)4, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, len1, 0, (SQLCHAR*)&sData.c_str(), nThisLen, &nThisLen );
答案 1 :(得分:0)
Jeff O走在正确的轨道上。尝试将你的sproc改为......
PROCEDURE [dbo].[spr_fff]
@act AS INT
,@id AS VARCHAR(255)
,@timestamp AS DATETIME
,@preblob AS nvarchar(MAX)
DECLARE @blob varbinary(MAX) = CAST(@preblob as varbinary(MAX))
/* Continue using varbinary blob as before */
请注意您的sproc参数数据类型的更改以及随后的转换为varbinary。
干杯。