0

我一直在使用 RFX_LongBinary 和 CLongBinary 变量从 SQL Server varbinary(max) 字段中移动数据。但是,现在 SQL Server 升级到 2019 版本,并且正在使用最新的 ODBC 驱动程序(MSODBCSQL17.dll,版本 17.6.1.1)。但是,这会导致最多可以写入 8000 个字节的问题。任何更大并且 CRecordSet::Update() 调用失败。

在网上阅读了很多资料让我确信我真的应该使用带有 CByteArray 变量的 RFX_Binary 来代替。所以我改变了它并让它工作 - 我可以将大量数据写入数据库。但是......现在,在 CFieldExchange::SetFieldNull 案例中,RFX_Binary 的代码将我的 CByteArray 中的第一个字节设置为 255(值 [0] = AFX_RFX_BYTE_PSEUDO_NULL)。它在调用 CRecordSet::AddNew() 时发生。在那次调用之后,我的 CByteArray 变量不再为空,而是 size = 1,并且第一个字节的值为 255。如果我用任何内容(例如我的真实有效负载数据)覆盖 CByteArray 中的第一个字节,则 CRecordSet::Update() 调用将失败并显示调试断言。

这是一个问题,因为以前在数据库字段中序列化/存储的数据没有将第一个字节设置为 255(使用 CLongBinary 时)。

dbrfx.cpp:

case CFieldExchange::SetFieldNull:
    if ((pFX->m_pvField == NULL &&
        pFX->m_nFieldType == CFieldExchange::outputColumn) ||
        pFX->m_pvField == &value)
    {
        if (pFX->m_bField)
        {
            // Mark fields null
            pFX->m_prs->SetNullFieldStatus(nField - 1);
            value.SetSize(1);
            value[0] = AFX_RFX_BYTE_PSEUDO_NULL;
            *plLength = SQL_NULL_DATA;
        }
        else
        {
            pFX->m_prs->ClearNullFieldStatus(nField - 1);
            *plLength = value.GetSize();
        } 
        ...
    }

我怎么能:

  1. 继续使用 CLongBinary 并将超过 8000 字节写入 SQL Server 中的 varbinary(max) 字段或
  2. 由于写入数据库的数据中包含额外字节(AFX_RFX_BYTE_PSEUDO_NULL == 255),使用 CByteArray 而不获得不同的序列化数据格式?

非常感谢任何帮助!

4

1 回答 1

0

多么有趣,在尝试了很多天之后 - 无法找到有效的解决方案 - 在上面发布我的问题 20 分钟后,我可能找到了答案!发布这个以防它可能对其他人有帮助:

我回到了 DoFieldExchange 方法中的 RFX_LongBinary。

在调用 set.Open(CRecordSet::dynaset, NULL, CRecordSet::none) 之后,我添加了以下内容:

set.m_rgODBCFieldInfos[1].m_nPrecision = INT_MAX;
set.m_rgODBCFieldInfos[1].m_nSQLType = SQL_LONGVARBINARY;

起初我已经设置:

set.m_rgODBCFieldInfos[1].m_nSQLType = SQL_BINARY;

这不起作用(给出 8000 字节的限制(超过 8000 字节会给出错误“字符串数据,右截断”),所以 SQL_LONGVARBINARY 似乎是解决这个问题的方法。m_rgODBCFieldInfos 索引中的数字“1”,指 varbinary(max) 字段的列索引。

另外,不设置

set.m_rgODBCFieldInfos[1].m_nSQLType

根本,也给出了“字符串数据,右截断”错误

于 2020-12-10T10:19:26.870 回答