我有一个使用Microsoft SQL Server的测试表,其定义如下:
CREATE TABLE [dbo].[Table] (
[FirstName] NVARCHAR (255) NULL,
[LastName] NVARCHAR (255) NULL
);
表中只有一行的值分别为“person”和“man”。
我正在尝试添加一个更新该行值的函数,但我一直在遇到这个“[Microsoft] [ODBC SQL Server驱动程序]字符串数据,右截断状态代码:22001”错误,我无法想象问题是什么。我环顾四周,有人说它是由于数据太长而不适合列,但这是不可能的,因为我试图更新的字符串只有两个字符,正如你在表定义中看到的那样它有足够的空间。
我正在使用预准备语句进行优化,创建它的代码如下所示:
const tString query("UPDATE \"" + tableName + "\" SET " + setClause + " WHERE " + whereClause + ";");
SQLHSTMT statement;
SQLAllocHandle(SQL_HANDLE_STMT, fSQLConnection, &statement);
SQLPrepareW(statement, (SQLWCHAR *) query.mWideStr(), SQL_NTS);`
查询字符串如下所示:
UPDATE "Table" SET "FirstName" = ?, "LastName" = ? WHERE "FirstName" = ? AND "LastName" = ?;
然后我绑定了这样的参数:
// We have our own string class that we use, which is where the mWideStr() and mGetStrSize()
// come from. mWideStr() returns a pointer to a UCS-2 buffer and mGetStrSize() returns the
// size in bytes.
SQLLEN pcbValue(SQL_NTS);
SQLUSMALLINT paramIndex(1);
// Call this for each parameter in the correct order they need to be bound, incrementing the
// index each time.
SQLBindParameter(statement, paramIndex++, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_VARCHAR, 255, 0, (SQLPOINTER) paramValue.mWideStr(), paramValue.mGetStrSize(), &pcbValue);
第一个和第二个绑定参数是新值,它们都只是“55”,第三个是“人”,第四个是“人”。
然后执行语句只需调用SQLExecute()
:
SQLExecute(statement);
对SQLExecute()
的调用失败,然后生成错误,还有一些代码输出错误消息。据我所知,这一切都应该完美无缺。我有另一个使用Oracle的数据库,它使用完全相同的设置和代码,它没有任何问题,它只是由于某种原因而被禁止的SQL Server。这里有什么明显的错误我错过了吗? SQL Server是否有一些我需要在某处添加的奇怪规则?
答案 0 :(得分:3)
传递给SQLLEN pcbValue(SQL_NTS);
的{{1}}变量在绑定参数和执行语句之间超出了范围,这意味着在参数绑定中指向了一些垃圾数据。我也意识到你不需要指定最后一个参数。你可以只传递NULL,它就像是一个以空字符结尾的字符串。
因此,修复方法是删除SQLBindParameter()
变量,并将SQLLEN pcbValue(SQL_NTS);
传递给NULL
代替最后一个参数。
愚蠢的错误,但值得注意的是我想。