programing

vb.net 에서 dbnull 데이터 처리

stoneblock 2023. 5. 19. 23:57

vb.net 에서 dbnull 데이터 처리

MS-Access 데이터베이스에서 검색하여 DataTable 개체/변수인 myDataTable에 저장된 데이터의 형식화된 출력을 생성하려고 합니다.그러나 myDataTable의 일부 필드에는 dbNull 데이터가 포함되어 있습니다.따라서 다음 VB.net 코드 스니펫은 필드, 이니셜 또는 sID 이 dbNull이면 오류를 제공합니다.

   dim myDataTable as DataTable
   dim tmpStr as String
   dim sID as Integer = 1

   ...
   myDataTable = myTableAdapter.GetData() ' Reads the data from MS-Access table
   ...

   For Each myItem As DataRow In myDataTable.Rows

    tmpStr = nameItem("lastname") + " " + nameItem("initials")

    If myItem("sID")=sID Then
        ' Do something
    End If

    ' print tmpStr

   Next

그렇다면, 이 질문에서와 같이 데이터가 dbNull인지 매번 확인할 필요 없이 필드에 dbNull이 포함될 수 있는 경우 위의 코드가 작동하려면 어떻게 해야 합니까?

제가 아는 유일한 방법은 테스트하는 것입니다. 쉽게 하려면 복합적으로 할 수 있습니다.

If NOT IsDbNull(myItem("sID")) AndAlso myItem("sID") = sId Then
   'Do success
ELSE
   'Failure
End If

당신이 언어를 섞었지만 필요해 보인다고 VB에 썼습니다.

편집

IsDbNull을 사용하여 읽기 쉽게 정리됨

저는 이 문제를 다루는 것이 지겨워서 저를 돕기 위해 NotNull() 함수를 작성했습니다.

Public Shared Function NotNull(Of T)(ByVal Value As T, ByVal DefaultValue As T) As T
        If Value Is Nothing OrElse IsDBNull(Value) Then
                Return DefaultValue
        Else
                Return Value
        End If
End Function

용도:

If NotNull(myItem("sID"), "") = sID Then
  ' Do something
End If

내 NotNull() 기능은 몇 년 동안 몇 번의 오버홀을 겪었습니다.Generics 이전에는 모든 것을 Object로 지정했습니다.하지만 저는 제네릭 버전을 훨씬 더 선호합니다.

변환기를 사용할 수도 있습니다.ToString() 및 변환합니다.DB null을 가진 항목을 효과적으로 변환하는 ToInteger() 메서드입니다.

Steve Wortham 코드의 변형으로, 명목상으로 사용됩니다.nullable선택사항:

Private Shared Function GetNullable(Of T)(dataobj As Object) As T
    If Convert.IsDBNull(dataobj) Then
        Return Nothing
    Else
        Return CType(dataobj, T)
    End If
End Function

예.

mynullable = GetNullable(Of Integer?)(myobj)

그런 다음 쿼리할 수 있습니다.mynullable (계속):mynullable.HasValue)

Microsoft는 데이터베이스 NULL을 나타내기 위해 .NET 1.0에서 DBNull을 고안했습니다.하지만 진가나 null을 저장할 강력한 형식의 변수를 만들 수 없기 때문에 뒤에서 사용하는 것이 번거롭습니다.Microsoft는 .NET 2.0에서 이 문제를 null 가능한 유형으로 해결했습니다.그러나 DBNull을 사용하는 API의 큰 청크는 여전히 남아 있으므로 변경할 수 없습니다.

그냥 제안이지만, 제가 평소에 하는 일은 다음과 같습니다.

  1. 데이터베이스에서 읽거나 데이터베이스에 쓴 데이터를 포함하는 모든 변수는 null 값을 처리할 수 있어야 합니다.값 유형의 경우 Null(Of T)로 설정됩니다.참조 유형(String 및 Byte()의 경우 값을 Nothing(없음)으로 허용합니다.
  2. "DBNull을 포함할 수 있는 개체"와 "nullable.NET 변수" 사이에서 앞뒤로 변환할 함수 집합을 작성합니다.이러한 함수에서 모든 호출을 DBNull 스타일 API로 래핑한 다음 DBNull이 없는 것으로 가장합니다.

IsDbNull 함수를 사용할 수 있습니다.

  If  IsDbNull(myItem("sID")) = False AndAlso myItem("sID")==sID Then
    // Do something
End If

BLL/DAL 설정을 사용하는 경우 DAL의 개체를 읽을 때 iif를 사용해 보십시오.

While reader.Read()
 colDropdownListNames.Add(New DDLItem( _
 CType(reader("rid"), Integer), _
 CType(reader("Item_Status"), String), _
 CType(reader("Text_Show"), String), _
 CType( IIf(IsDBNull(reader("Text_Use")), "", reader("Text_Use")) , String), _
 CType(reader("Text_SystemOnly"), String), _
 CType(reader("Parent_rid"), Integer)))
End While

문자열이 포함된 행의 경우 변경 시와 같이 문자열로 변환할 수 있습니다.

tmpStr = nameItem("lastname") + " " + nameItem("initials")

로.

tmpStr = myItem("lastname").toString + " " + myItem("intials").toString

if 문 myItem("sID")=sID의 비교를 위해 다음으로 변경해야 합니다.

myItem("sID").Equals(sID)

그러면 vbNull 데이터로 인한 런타임 오류 없이 코드가 실행됩니다.

   VB.Net
   ========
    Dim da As New SqlDataAdapter
    Dim dt As New DataTable
    Call conecDB()        'Connection to Database
    da.SelectCommand = New SqlCommand("select max(RefNo) from BaseData", connDB)

    da.Fill(dt)

    If dt.Rows.Count > 0 And Convert.ToString(dt.Rows(0).Item(0)) = "" Then
        MsgBox("datbase is null")

    ElseIf dt.Rows.Count > 0 And Convert.ToString(dt.Rows(0).Item(0)) <> "" Then
        MsgBox("datbase have value")

    End If

이것은 훨씬 더 사용하기 쉬울 것 같습니다.

테이블 이름에서 ISNULL(sum(필드), 0)을 선택합니다.

복사 위치: http://www.codeproject.com/Questions/736515/How-do-I-avoide-Conversion-from-type-DBNull-to-typ

안녕, 친구들

DataGrid에서 dbNull을 확인하고 문자열로 변환하는 가장 짧은 방법입니다.

  1. 셀 유효성 확인 이벤트를 생성하고 이 코드를 작성합니다.
  2. 변환하는 경우.ToString(dgv).현재 셀.값) = " " 그러면
  3. 현재 셀.값 = " "
  4. 종료할 경우

이것이 지금까지 변환하는 가장 쉬운 방법입니다.DBNull실타래로요령은 당신이 그것을 사용할 수 없다는 것입니다.TRIM데이터베이스에서 필드를 참조할 때 함수(초기 문제):

BEAPE(생산 오류 메시지):

Me.txtProvNum.Text = IIf(Convert.IsDBNull(TRIM(myReader("Prov_Num"))), "", TRIM(myReader("Prov_Num")))

AFTER (더 이상 오류 없음 msg :-):

Me.txtProvNum.Text = IIf(Convert.IsDBNull(myReader("Prov_Num")), "", myReader("Prov_Num"))

간단하지만 명확하지는 않습니다.

DbNull.Value.Equals(myValue)

저는 VB.NET이 싫어요.

문제의 경우 다음과 같은 특수 해결 방법 코드를 사용할 수 있습니다.VB.Net.

Dim nId As Integer = dr("id") + "0"

이 코드가 대체됩니다.DBNull포함된 가치id열에 정수 0을 입력합니다.

이 식을 다음과 같은 경우에도 사용해야 하므로 허용되는 기본값은 "0"뿐입니다.dr("id")NULL이 아닙니다!

그래서, 이 기술을 사용하면,

   Dim myDataTable as DataTable
   Dim s as String
   Dim sID as Integer = 1

   ...
   myDataTable = myTableAdapter.GetData() ' Reads the data from MS-Access table
   ...

   For Each myItem As DataRow In myDataTable.Rows
       s = nameItem("lastname") + " " + nameItem("initials")
       If myItem("sID") + "0" = sID Then
           ' Do something
       End If
   Next

이 솔루션을 테스트해 본 결과 Visual Studio 2022의 PC에서 작동합니다.

PS: 만약sID0과 같을 수 있고 당신은 다음과 같은 것을 하기를 원합니다.dr("sID")값이 NULL입니다. 또한 프로그램을 잘 처리하고 사용해야 합니다.Extension이 답변의 끝에서 제안한 바와 같이.

다음 문장을 테스트했습니다.

Dim iNo1 As Integer = dr("numero") + "0"
Dim iNo2 As Integer = dr("numero") & "0" '-> iNo = 10 when dr() = 1
Dim iNo3 As Integer = dr("numero") + "4" '-> iNo = 5  when dr() = 1
Dim iNo4 As Integer = dr("numero") & "4" '-> iNo = 14 when dr() = 1
Dim iNo5 As Integer = dr("numero") + "" -> System.InvalidCastException : 'La conversion de la chaîne "" en type 'Integer' n'est pas valide.'
Dim iNo6 As Integer = dr("numero") & "" -> System.InvalidCastException : 'La conversion de la chaîne "" en type 'Integer' n'est pas valide.'
Dim iNo7 As Integer = "" + dr("numero") -> System.InvalidCastException : 'La conversion de la chaîne "" en type 'Integer' n'est pas valide.'
Dim iNo8 As Integer = "" & dr("numero") -> System.InvalidCastException : 'La conversion de la chaîne "" en type 'Integer' n'est pas valide.'
Dim iNo9 As Integer = "0" + dr("numero")
Dim iNo0 As Integer = "0" & dr("numero")

다음 문도 올바르게 작동합니다.

Dim iNo9 As Integer = "0" + dr("numero")
Dim iNo0 As Integer = "0" & dr("numero")

저는 그것이 조금 까다롭다는 것을 알고 있습니다.

속임수가 당신의 팁이 아니라면, 당신은 또한 정의할 수 있습니다.Extension다음 코드가 작동하도록 합니다.

Dim iNo = dr.GetInteger("numero",0)

여기서 GetInteger() 코드는 다음과 같을 수 있습니다.

Module Extension
    '***********************************************************************
    '* GetString()
    '***********************************************************************

    <Extension()>
    Public Function GetString(ByRef rd As SqlDataReader, ByRef sName As String, Optional ByVal sDefault As String = "") As String
        Return GetString(rd, rd.GetOrdinal(sName), sDefault)
    End Function

    <Extension()>
    Public Function GetString(ByRef rd As SqlDataReader, ByVal iCol As Integer, Optional ByVal sDefault As String = "") As String
        If rd.IsDBNull(iCol) Then
            Return sDefault
        Else
            Return rd.Item(iCol).ToString()
        End If
    End Function

    '***********************************************************************
    '* GetInteger()
    '***********************************************************************

    <Extension()>
    Public Function GetInteger(ByRef rd As SqlDataReader, ByRef sName As String, Optional ByVal iDefault As Integer = -1) As Integer
        Return GetInteger(rd, rd.GetOrdinal(sName), iDefault)
    End Function

    <Extension()>
    Public Function GetInteger(ByRef rd As SqlDataReader, ByVal iCol As Integer, Optional ByVal iDefault As Integer = -1) As Integer
        If rd.IsDBNull(iCol) Then
            Return iDefault
        Else
            Return rd.Item(iCol)
        End If
    End Function

End Module

이러한 방법은 더 명확하고 덜 까다롭습니다.

또한 ZERO 이외의 기본값과 특정 버전을 다음과 같이 정의할 수 있습니다.GetBoolean()또는GetDate()기타...

또 다른 가능성은 다음을 사용하여 SQL 명령에서 SQL 기본 변환을 보고하는 것입니다.COALESCE 명령어SQL 명어령!

언급URL : https://stackoverflow.com/questions/222834/handling-dbnull-data-in-vb-net