我们目前正在将我们的数据库从SQL Server Native Client v11 (SQL Server 2012)迁移datetime
到包括在内。datetime2
数据库更新很容易完成,但问题出现在我们想要使用的新 SQL Server Native Client 11 上。
一般来说,我们的 CRUD 操作有带有“COLUMN_ENTRY*”访问器的 OLE DB 消费者。对于datetime2
列,成员的类型为DBTIMESTAMP
。使用SQLNCLI
提供者,小数部分DBTIMESTAMP
被默默地截断为支持的值。使用SQLNCLI11
带有太精确分数的插入会导致此错误:
DB_E_ERRORSOCCURRED Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
根据此链接,如果将太多数据插入到字段中,则会返回此错误。由此我假设 DBDATETIME 成员的小数部分太精确而无法插入。根据此链接,新的 Native Client 版本(10 和 11)不会截断,但会因错误而失败。以我们想要实现的这个简化示例为例:
class CMyTableStruct
{
public:
CMyTableStruct();
LONG m_lID;
DBTIMESTAMP m_dtLogTime;
};
class CMyTableStruct_InsertAccessor : public CMyTableStruct
{
public:
BEGIN_PARAM_MAP(CMyTableStruct_InsertAccessor)
COLUMN_ENTRY(1, m_dtLogTime)
END_PARAM_MAP()
};
在代码的某些部分,我将时间戳初始化为 2015-08-10 07:47:49.986149999 并且插入失败。如果我将分数重置为 0,则插入有效;0 以外的任何值都失败。我尝试使用COLUMN_ENTRY_PS
各种值提供日期时间精度和比例,但插入总是失败。
我们如何强制 Native Client 简单地接受该值并截断它?很明显,我们不能手动将所有值截断为支持的 DB 精度。我找不到任何关于如何在新的 Native Client 中使用 datetime2 的适当文档。我们是否缺少正确处理 datetime2 的任何转换或设置?
这是测试设置:
- 视窗 7 64 位
- SQL Server 本机客户端 11 (SQLNCLI11)
- SQL Server 2012
- DBPROP_INIT_LCID=2055
- DBPROP_INIT_PROMPT=4
- DBPROP_INIT_DATASOURCE=本地主机
- DBPROP_AUTH_INTEGRATED=SSPI
对于SQLNCLI
提供者,相同的代码可以工作。
[EDIT#1]:我使用转储了更多错误信息AtlTraceErrorRecords
,这证实了与链接的 Microsoft Connect 报告中相同的错误:
Row #: 0 Source: "Microsoft SQL Server Native Client 11.0" Description: "The fractional part of the provided time value overflows the scale of the corresponding SQL Server parameter or column. Increase bScale in DBPARAMBINDINFO or column scale to correct this error." Help File: "(null)" Help Context: 0 GUID: {0C733A63-2A1C-11CE-ADE5-00AA0044773D}
[EDIT#2]:根据我的进一步研究,这似乎是新 Native Client 的定义和接受的行为。请参阅更严格的 SQL_C_TYPE _TIMESTAMP 和 DBTYPE_DBTIMESTAMP 参数验证以供参考。但是如果没有任何文档说明如何正确使用 datetime2,微软就无法认真对待这一变化。他们真的需要开发人员自己在将 DBTIMESTAMP 插入数据库之前对其进行四舍五入吗?在某些情况下,由于某些浮点精度错误,舍入甚至不起作用。以上面的示例时间戳为例,您将看到典型的 .9999 精度错误。有人应该如何让这种奇怪的行为起作用?使用此错误消息,您甚至无法在不使用 SQL 函数的情况下将当前时间戳保存到数据库now()
因为您通常会在这些溢出中运行。