我正在开发一个使用CDatabase和CRecordset类进行数据库访问的MFC应用程序。数据库不会动态绑定到基于MFC的表单或窗口。
我在检测记录的特定字段何时为NULL时遇到问题。
我的大多数代码都运行正常。连接数据库,发出查询和回读记录没有问题。但是,有几个字段我正在获取垃圾字符串,当我检查数据库时,它向我显示有问题的字段为NULL。
NULL在某些情况下是合理的,所以我需要我的代码才能正确处理它,而不是阻止它。但是, GetFieldValue 为相关字段返回的值为 NOT null。我得到一些不是有效指针的随机值。显然我需要做一些不仅仅检查指针值的NULL测试。
CRecordset 类中有一个名为 IsFieldNull 的方法,但它似乎无法正常工作,或者我没有正确调用它。我没有在网上找到关于如何使用这种方法的好例子。文档说它需要一个参数,一个指向“字段数据成员”的void指针,但没有定义应该是什么。我已经看到了传递从零开始的字段索引的示例,以及传递带字段名称的字符串常量的示例。我已经尝试了这两种想法,似乎都没有效果。
事实上,调用CRecordset :: IsFieldNull()总是会让我的代码飞到永不落地的地方。
还有一个名为 IsFieldStatusNull 的CRecordset成员据称应该采用字段索引,但我发现调用它也失败了。
最后,我的问题是,如何检查CRecordset中的特定字段是否为NULL?
我真的不认为现有的代码与问题相关,但是因为它已被请求,所以(简化为删除try / catch块):
CDBVariant v;
CRecordset theRecordSet(&theDB); // Pointer to my CDatabase object
query.Format("SELECT B.*, B.photographerWebsite AS website FROM gbm_shootphotographers AS A INNER JOIN gbm_photographers AS B ON A.photographerID=B.photographerID WHERE A.shootID=%d;", shootID );
BOOL result = theRecordSet.Open(AFX_DB_USE_DEFAULT_TYPE, query );
memset(&v,0,sizeof(CDBVariant)); // Zero it out before retrieving field
// 1
theRecordSet.GetFieldValue("website", v);
// 2
CString website = *v.m_pstring;
对于“网站”字段包含数据的记录,检索得很好。字符串完全符合预期。但是,对于“website”为NULL的记录,我得到一个带有垃圾的非空字符串,甚至更糟糕的是,一个错误的字符串指针。坦率地说,我不明白为什么它输出任何对于NULL字段的CDBVariant对象,但其中存在问题。
我尝试在位置#1和位置#2调用 IsFieldNull 和 IsFieldStatusNull 。无论如何都要进入杂草。
答案 0 :(得分:3)
在访问CDBVariant
中的数据之前,您必须检查其m_dwType
成员。
m_pstring
仅对类型为DBVT_STRING
DBVT_NULL
且没有成员对访问有效 CDBVariant是union
,这意味着从技术上讲,您可以随时阅读任何成员,阅读您不应阅读的成员会导致未定义的行为。在你的情况下,你得到的随机指针可以打印到垃圾桶,或立即崩溃。