当使用Str()和Null Recordset字段时,“Null的使用无效”,但Str(空)可以正常工作

当使用Str()和Null Recordset字段时,“Null的使用无效”,但Str(空)可以正常工作

问题描述:

我正在用头撞墙。我看着写在VB6一些旧的数据库报告代码和跨越这条线进来(代码从“源”数据库将数据移动到报告数据库):当使用Str()和Null Recordset字段时,“Null的使用无效”,但Str(空)可以正常工作

rsTarget!VehYear = Trim(Str(rsSource!VehYear)) 

rsSource!VehYearNull,上面的行生成“无效使用Null”运行时错误。如果我在上述行中断开并在“即时”窗格中键入以下内容:

?rsSource!VehYear 

它输出Null。好吧,这很有道理。接下来,我尝试重现该错误:

?Str(rsSource!VehYear) 

我收到“无效使用空值”错误。

但是,如果我键入以下到即时窗口:

?Str(Null) 

我没有得到一个错误。它只是输出Null

如果我用Trim()而不是Str()重复同样的实验,一切正常。 ?Trim(rsSource!VehYear)返回Null,与?Trim(Null)一样。没有运行时错误。

所以,我的问题是,如何才能Str(rsSource!VehYear)可能抛出一个“无效使用的Null”错误时Str(Null)不,当我知道rsSource!VehYear等于Null


更新:如果我键入立即窗口下面,它按预期工作(没有发生错误):

?Str(rsSource!VehYear.Value) 

此输出Null。现在,我知道rsSource!VehYear实际上是一个ADODB.Field实例,但Value是它的默认属性,所以Str应该在Value属性(即Null)上运行。即使是错误消息(“无效使用空值”),也表明Str正在接收Null参数,但是如何在一种情况下对待Null而不是另一种呢?

我唯一的猜测是Str()的内部实现在某种程度上无法获得默认属性,并且“无效的Null使用”错误是由于其他原因而发生的(参数之外的其他原因导致“Invalid use of空“,也许当它试图从Field对象中检索默认属性时)。

有没有人对这里实际发生的事情有更详细的技术解释?

简而言之:

?Str(rsSource!VehYear) 

抛出 “无效使用Null” 错误时rsSource!VehYearNull,但

?Str(rsSource!VehYear.Value) 

返回Null

然而,Trim(rsSource!VehYear)Trim(rsSource!VehYear.Value)都返回Null

Str函数将专门检查是否传递一个Null值并相应地处理它。当你传入一个对象时,它会尝试将默认方法的结果转换为一个String。默认方法的结果不会传递到Str方法,但是Field对象是,所以检查初始Null将失败。 Str函数将继续检查它支持的数据类型的参数类型,当它意识到它具有一个对象时,它将尝试检索默认值。它不会重新尝试处理默认值,因为它与传入的参数一样,所以尝试返回Null作为字符串将失败。似乎MS并没有预期默认值为Str或任何其他无效值。例如Str不支持空字符串。

+0

这清除了一切。顺便说一下,感谢SimplyVBUnit;) – 2010-05-11 15:10:20

从内存中,空数据库字段为Nothing(或可能为vbNull),它们没有应用于它们的相同规则作为Null。你应该能够做到快速检查:

If (rsSource!VehYear Is Nothing) Then 
    ' Null 
Else 
    ' Not null 
End If 
+0

很好的建议,但该领域绝对是等于'Null'。我通过将它悬停在IDE中进行检查,并将其打印到立即窗口中。 – 2010-05-06 22:52:43

这是我的解决方法在VB6天:

rsTarget!VehYear = Trim(Str(rsSource!VehYear & "")) 

&“”将确保有百达至少空串来处理。

+0

我知道我可以解决这个问题,在这种情况下,我实际上可以完全删除对“Trim”和“Str”的调用,因为数据库字段实际上是一个数字字段。我更关心为什么问题中的代码无法按预期工作的技术原因。 – 2010-05-07 14:29:23

如果你需要比一个字符串的值,请尝试使用ISNULL代替:

rsTarget!VehYear = IIf(IsNull(rsSource!VehYear), 0, rsSource!VehYear) 

'注意0是默认值