我有一个使用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" = ?;
然后我绑定(bind)这样的参数:
// 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);
第一个和第二个绑定(bind)参数是新值,它们都只是“55”,然后第三个将是“person”,第四个将是“man”。
然后执行语句只是对
SQLExecute()
的调用:SQLExecute(statement);
对
SQLExecute()
的调用失败,然后生成错误,并且还有更多代码输出错误消息。据我所知,这一切都应该工作得很好。我有另一个使用Oracle的数据库,该数据库使用完全相同的设置和代码,并且可以正常工作,没有任何问题,只是出于某种原因而被SQL Server拒绝。我想念的地方明显有问题吗? SQL Server是否有一些需要添加到某些地方的怪异规则? 最佳答案
传递给SQLLEN pcbValue(SQL_NTS);
的SQLBindParameter()
变量在绑定(bind)参数和执行语句之间超出范围,这意味着在参数绑定(bind)中指向了一些垃圾数据。我还意识到,您不需要指定最后一个参数。您可以只传递NULL,它就好像是一个以nul终止的字符串一样。
因此,解决方法是删除SQLLEN pcbValue(SQL_NTS);
变量,而只是将NULL
传递给SQLBindParameter()
作为最后一个参数。
愚蠢的错误,但我想值得注意。
关于c++ - SQL Server数据库的ODBC错误 “String data, right truncation State code: 22001”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21998517/