【问题标题】:How to write to a varchar(max) column using ODBC如何使用 ODBC 写入 varchar(max) 列
【发布时间】:2009-07-02 13:45:50
【问题描述】:

总结:我正在尝试使用 ODBC 和 SQL Server 2005 将文本字符串写入 varchar(max) 类型的列。如果字符串的长度大于 8000,则会失败。求助!

我有一些使用 ODBC (SQL Native Client) 将文本字符串写入表的 C++ 代码。如果我将列从 varchar(100) 更改为 varchar(max) 并尝试写入长度大于 8000 的字符串,则写入失败并出现以下错误

[微软][ODBC SQL Server Driver]字符串数据,右截断

那么,谁能告诉我这是否可以做到,以及如何做到?

显示我正在尝试做的一些示例(不是生产)代码:

SQLHENV hEnv = NULL;
SQLRETURN iError = SQLAllocEnv(&hEnv);

HDBC hDbc = NULL;
SQLAllocConnect(hEnv, &hDbc);

const char* pszConnStr = "Driver={SQL Server};Server=127.0.0.1;Database=MyTestDB";
UCHAR szConnectOut[SQL_MAX_MESSAGE_LENGTH];
SWORD iConnectOutLen = 0;
iError = SQLDriverConnect(hDbc, NULL, (unsigned char*)pszConnStr,
                      SQL_NTS, szConnectOut,
                      (SQL_MAX_MESSAGE_LENGTH-1), &iConnectOutLen,
                      SQL_DRIVER_COMPLETE);

HSTMT hStmt = NULL;
iError = SQLAllocStmt(hDbc, &hStmt);

const char* pszSQL = "INSERT INTO MyTestTable (LongStr) VALUES (?)";
iError = SQLPrepare(hStmt, (SQLCHAR*)pszSQL, SQL_NTS);

char* pszBigString = AllocBigString(8001);
iError = SQLSetParam(hStmt, 1, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLPOINTER)pszBigString, NULL);

iError = SQLExecute(hStmt);  // Returns SQL_ERROR if pszBigString len > 8000

表 MyTestTable 包含一个定义为 varchar(max) 的列。 AllocBigString 函数(未显示)创建任意长度的字符串。

我知道以前版本的 SQL Server 对 varchars 有 8000 个字符的限制,但不知道为什么在 SQL 2005 中会发生这种情况?

谢谢, 安迪

【问题讨论】:

    标签: c++ sql-server sql-server-2005 odbc


    【解决方案1】:

    您确定加载的是 2005 版的 SQL Native Driver,而不是 2000 版的旧版驱动程序?本机驱动程序名称是 {SQL Server Native Client 10.0} 用于 2k8 或 {SQL Native Client} 用于 2k5

    错误消息ODBC SQL Server Driver 似乎表明旧的2k 驱动程序(我可能错了,10 年没有接触过ODBC)。

    【讨论】:

    • 谢谢你莱姆斯!你是对的,我使用了错误的驱动程序。当我改变它时,它起作用了。作为记录,我使用了以下连接字符串:Driver={SQL Native Client};服务器=127.0.0.1;数据库=MyTestDB;这与您提供的驱动程序名称不太一样,但是您的建议使我找到了答案。再次感谢 - 非常感谢。安迪
    • 显然我无法超越从 MSDN 复制粘贴名称到答案的挑战,哈哈。对,名字是 {SQL Native Client},我也会修复我的帖子,为了其他 google 的缘故。
    【解决方案2】:

    事实证明,虽然该修复适用于 SQLSetParam,但它不适用于 SQLBindParameter。

    例如:

    int iLength = 18001;
    char* pszBigString = new char[iLength + 1];
    memset(pszBigString, 'a', iLength);
    pszBigString[iLength] = 0;
    LONG_PTR lLength = SQL_NTS;
    ::SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT,
                    SQL_C_CHAR,
                    SQL_VARCHAR,
                    iLength, 0, pszBigString, iLength * sizeof(TCHAR),
                    &lLength);
    

    无论使用哪个驱动程序,都会导致相同的 22001“字符串数据,右截断”错误。

    事实上,我的实验表明您确实不需要实际需要安装版本 10 的客户端驱动程序。相反,如果您希望字符串的长度超过 8000 个字符,则应该使用 SQL_LONGVARCHAR 而不是 SQL_VARCHAR。您可能会执行大规模查找和替换,但使用 SQL_LONGVARCHAR 可能会招致某种惩罚(尽管这纯粹是推测;它是一种“扩展数据类型”)。

    我已经在 Windows XP 上使用这两个驱动程序成功地测试了这一点:

    • {SQL Server} 2000.85.1117.00 (04/08/2004)
    • {SQL Server Native Client 10.0} 2007.100.1600.22 (10/07/2008)

    【讨论】:

      猜你喜欢
      • 2022-10-14
      • 2020-05-27
      • 1970-01-01
      • 2011-12-09
      • 2020-09-20
      • 2013-06-17
      • 2016-02-25
      • 2010-12-13
      • 2012-12-30
      相关资源
      最近更新 更多