String.IsNullOrEmpty使用IIF和IF ELSE时验证VS IsDBNull

时间:2015-10-13 02:21:24

标签: sql vb.net if-statement null iif

这对我来说并不清楚,所以如果有人能详细解释VB的两个函数( IsDBNull String.IsNullOrEmpty )的区别是什么。净。

下面是我的情况,为什么我问这个,我的表中有Company列,其值为NULL,然后我使用vb.net的IIF函数验证是否是NULL然后分配空字符串(“”),否则分配来自数据表

的值

情境:

  1. 下面是使用 String.IsNullOrEmpty ,我收到转换错误:

      

    从“DBNULL”类型到“String”的转换无效。

    txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))
    
  2. 但是当我用 IsDBNull 替换String.IsNullOrEmpty时,验证工作正常。

    txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))
    
  3. 修改

    这很令人困惑,因为如果我使用IF ELSE条件(参见下面的示例代码)使用String.IsNullOrEmpty进行验证,则可以正常工作。

        If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then
            txtCompany.Text = ""
        Else
            txtCompany.Text = dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString
        End If
    

    令人困惑的部分是当我使用IIF(String.IsNullOrEmpty...etc)时它会返回错误。但是当我使用普通IF String.IsNullOrEmpty(dtSample.Rows....etc) = True时,它可以正常工作。

    任何解释都会非常感激。感谢

4 个答案:

答案 0 :(得分:4)

<强> TL; DR

  • String.IsNullOrEmpty()仅检查空([blank]''"")或Null检查{ {1}},如果来自数据库的任何字段的值为DBNull,则会引发错误。
  • DBNull检查IsDBNull()(与DBNull不同)
  • Null会将.ToString转换为空字符串,即DBNull

<强>详情
请考虑以下SQL表示例(使用SQL Server作为基础)

表格结构:

''

INSERT语句:

Column_Name        Type and Size   Other Properties
----------------   -------------   ----------------------
Company_ID         int             IDENTITY(1,1) NOT NULL
Company_Name       nvarchar (50)                 NOT NULL   
Company_Address    nvarchar (50)                     NULL

表数据:

INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('ABC', 'QWERT')
INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('ASD', ' ')
INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('XYZ', '')
INSERT [tbl_company] ([Company_Name])                    VALUES ('PQR')

使用SqlDataReader(r)使用IsNullOrEmpty()和IsDBNull()测试Company_Address:

Company_ID    Company_Name      Company_Address
-----------   ----------------  ---------------
1             ABC               QWERT
2             ASD               [SPACE]
3             XYZ               [BLANK]
4             PQR               NULL

现在特定于问题
OP在这里尝试的是,让我们逐一考虑所有陈述

带有IsNullOrEmpty的IIF声明(错误

Company_ID IsNullOrEmpty(r("Company_Address")) IsDBNull(r("Company_Address"))
---------- ----------------------------------- ------------------------------
1          False                               False
2          False                               False
3          True                                False
4          ERROR                               True

在此声明中,OP正在访问txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company")) 的值,并使用dtSample.Rows(grdInfo.SelectedIndex).Item("Company")进行检查,然后使用IsNullOrEmpty()将{Is}的IsNullOrEmpty结果转换为字符串,即.ToString。如果值为DBNull,则始终返回错误。使用它的正确方法是

IsNullOrEmpty(value).ToString()

查看上一部分IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) vs Company")).ToString,只是MISPLACED案例“)”

第二个(带有IsDBNull的IIF)和第三个(带有IsNullOrEmpty的IF)语句是正确的

Company").ToString)

关于第二个语句,OP正确地排序参数,即使用txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company")) If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then txtCompany.Text = "" Else txtCompany.Text = dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString End If 将第一个Company字段转换为字符串。这会将任何DBNull转换为Empty字符串,然后检查dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString。现在,由于该值已经转换为EmptyString,因此不会出现任何错误。

与OP的旧讨论

您的文字中的区别很明显。你的第一个陈述是:

IsNullOrEmpty

,第二个是

txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSpecifierRebate.Rows(grdInfo.SelectedIndex).Item("Company"))

现在将它们分开,首先声明(IIF)

If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then

第二部分(IF)

String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString
'Item("Company")).ToString

发现有什么不同吗?
在第一个语句中,您将IsNullOrEmpty 的结果转换为String
在第二个中,您转换.Item(“公司”)ToString ,然后进行比较。

如果String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) 'Item("Company").ToString) 返回DBNull
然后IsNullOrEmpty失败,因为.Item(“Company”)返回类型 DBNull ,而IsNullOrEmpty检查 null
IsDBNull工作,因为它检查 DBNull

错位括号的所有点“)”这是一个错字

关于你对这些陈述的使用:
如果和IIF需要将结果检查为布尔值而不是字符串
最好建议删除语句的ToString部分

答案 1 :(得分:2)

您不能混用String.IsNullOrEmptyIsDBNull,因为它们可以处理两种不同的事情。第一个是字符串,第二个是从数据库中读取的数据项。

但其中一个非常重要的因素是您的代码无效。无论是&#34;场景&#34;代码段在Option Strict下编译。如果你让VB猜测你的意思,你会得到令人困惑的结果。

摘录1:

txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

简化为:

Dim foo = IIf(String.IsNullOrEmpty(zDT.Rows(23).Item("Name")).ToString,
                "", zDT.Rows(23).Item("Name"))

这是非法的,因为zDT.Rows(23).Item("Name")是一个对象,但String.IsNullOrEmpty需要一个字符串。您的ToString放错地方了 - 它没有转换db项,它正在转换整个IIF bool expresion!

编译器警告您Option Strict On

转换会抛出异常,因为VB必须将db Object项(zDT.Rows(23).Item("Name"))转换为字符串。当db数据为DBNull时,它的执行方式会导致错误。

摘录2:

txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

简化为:

foo = IIf(IsDBNull(zDT.Rows(23).Item("Name")).ToString, 
               "", zDT.Rows(23).Item("Name"))

这稍微好一点,但直到使用字符串代替布尔表达式。修复后,您有:

IsDBNull(zDT.Rows(23).Item("Name"))

IsDBNull正在测试数据库项(Object)以查看它是否有数据。它会工作。不应使用IsNullOrEmpty来测试DBNull,而不能使用Option Strict来测试。您必须先将dbItem转换为字符串,然后它才会起作用,具体取决于您的转换方式。

' cant use string method to test an object
String.IsNullOrEmpty(zDT.Rows(23).Item("Name"))

' this will work:
String.IsNullOrEmpty(zDT.Rows(23).Item("Name").ToString)

' this will not:
String.IsNullOrEmpty(CStr(zDT.Rows(23).Item("Name")))

对数据对象使用DBNull测试,对字符串使用IsNullOrEmpty

此外,如果您使用较新的If运算符代替旧的IIf函数,则可以避免其他问题。操作员允许短路,语法相同:

Dim foo = If(bool expr, True result, False result)

答案 2 :(得分:1)

IsNullOrEmpty函数检查字符串是空还是空。 DBNull不为null(Nothing),而是一个表示数据库中的值不存在的类。 IsDbNull检查值是否等于DBNull。

你可能没有在引用的代码行中的问题中提到错误,因为这对我来说运行得很好:

        strTest = IIf(String.IsNullOrEmpty(DBNull.Value.ToString), "", DBNull.Value)

答案 3 :(得分:1)

IsDBNull功能:

返回一个布尔值,指示表达式是否计算为System.DBNull类。

如果Expression的数据类型求值为DBNull类型,则IsDBNull返回True;否则,IsDBNull返回False。 System.DBNull值指示Object表示缺少数据或不存在数据。 DBNull与Nothing不同,后者表示尚未初始化变量。 DBNull也与零长度字符串(&#34;&#34;)不同,有时也称为空字符串。

示例:

 Dim testVar As Object 
   Dim nullCheck As Boolean
      nullCheck = IsDBNull(testVar)
     testVar = ""
     nullCheck = IsDBNull(testVar)
     testVar = System.DBNull.Value
    nullCheck = IsDBNull(testVar)
     '  The first two calls to IsDBNull return False; the third returns True..

String.IsNullOrEmpty:

指示指定的字符串是null还是空字符串。 IsNullOrEmpty是一种便捷方法,使您可以同时测试String是否为null或其值是否为空。

示例:

    Class Sample
   Public Shared Sub Main()
  Dim s1 As String = "abcd"
  Dim s2 As String = ""
  Dim s3 As String = Nothing

  Console.WriteLine("String s1 {0}.", Test(s1))
  Console.WriteLine("String s2 {0}.", Test(s2))
  Console.WriteLine("String s3 {0}.", Test(s3))
   End Sub

   Public Shared Function Test(s As String) As String
     If String.IsNullOrEmpty(s) Then
     Return "is null or empty"
    Else
     Return String.Format("(""{0}"") is neither null nor empty", s)
    End If
   End Function 
 End Class  
     'The example displays the following output:
    'String s1 ("abcd") is neither null nor empty.
     'String s2 is null or empty.
      'String s3 is null or empty.