OLE DB 大容量复制操作始终将 true 加载到位列中

OLE DB Bulk Copy Operation Always Loads True into Bit Columns

本文关键字:加载 true 大容量 DB 复制 操作 OLE      更新时间:2023-10-16

我正在对 SQL Server 数据库使用 OLE DB 大容量复制操作,但在将数据加载到bit列时遇到问题 - 它们总是填充true

我从 Microsoft 的示例代码中创建了一个简单的复制程序,其中包含我在下面调整的代码段。 我的程序包含一个用于创建目标表的小 SQL 脚本。 我必须下载并安装 x64 版本的 SQL Server OLE DB 驱动程序才能构建此驱动程序。

// Set up custom bindings.  
oneBinding.dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
oneBinding.iOrdinal = 1;
oneBinding.pTypeInfo = NULL;
oneBinding.obValue = ulOffset + offsetof(COLUMNDATA, bData);
oneBinding.obLength = ulOffset + offsetof(COLUMNDATA, dwLength);
oneBinding.obStatus = ulOffset + offsetof(COLUMNDATA, dwStatus);
oneBinding.cbMaxLen = 1;   // Size of varchar column.  
oneBinding.pTypeInfo = NULL;
oneBinding.pObject = NULL;
oneBinding.pBindExt = NULL;
oneBinding.dwFlags = 0;
oneBinding.eParamIO = DBPARAMIO_NOTPARAM;
oneBinding.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
oneBinding.bPrecision = 0;
oneBinding.bScale = 0;
oneBinding.wType = DBTYPE_BOOL;
ulOffset = oneBinding.cbMaxLen + offsetof(COLUMNDATA, bData);
ulOffset = ROUND_UP(ulOffset, COLUMN_ALIGNVAL);
if (FAILED(hr =
pIFastLoad->QueryInterface(IID_IAccessor, (void**)&pIAccessor)))
return hr;
if (FAILED(hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
1,
&oneBinding,
ulOffset,
&hAccessor,
&oneStatus)))
return hr;
// Set up memory buffer.  
pData = new BYTE[40];
if (!(pData /* = new BYTE[40]*/)) {
hr = E_FAIL;
goto cleanup;
}
pcolData = (COLUMNDATA*)pData;
pcolData->dwLength = 1;
pcolData->dwStatus = 0;
for (i = 0; i < 10; i++)
{
if (i % 2 == 0)
{
pcolData->bData[0] = 0x00;
}
else
{
pcolData->bData[0] = 0xFF;
}

if (FAILED(hr = pIFastLoad->InsertRow(hAccessor, pData)))
goto cleanup;
}

我完全有可能将错误的值放入缓冲区,或者其他一些常量值不正确。 我确实找到了一篇描述各种数据类型转换安全性的文章,看起来字节到布尔值是安全的......但是,如果缓冲区只是一个字节数组,它怎么知道我在那里放了什么样的数据?

想通了这一点,我没有正确地将演示从加载字符串切换到固定宽度的值。 对于字符串,数据 blob 获取指向值的 1 宽度指针,而固定宽度的值获取实际数据。

所以我的COLUMNDATA结构现在看起来像这样:

// How to lay out each column in memory.  
struct COLUMNDATA {
DBLENGTH dwLength;   // Length of data (not space allocated).  
DWORD dwStatus;   // Status of column.  
VARIANT_BOOL bData; // Value, or if a string, a pointer to the value.
};

在此处进行相关的长度修复:

pcolData = (COLUMNDATA*)pData;
pcolData->dwLength = sizeof(VARIANT_BOOL); // using a short.. make it two
pcolData->dwStatus = DBSTATUS_S_OK; // Indicates that the data value is to be used, not null

循环的小值设置如下所示:

for (i = 0; i < 10; i++)
{
if (i % 2 == 0)
{
pcolData->bData = VARIANT_TRUE;
}
else
{
pcolData->bData = VARIANT_FALSE;
}
if (FAILED(hr = pIFastLoad->InsertRow(hAccessor, pData)))
goto cleanup;
}

我已经用工作代码更新了存储库。 在阅读了obValue属性的文档后,我受到启发进行了此更改。