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의 큰 청크는 여전히 남아 있으므로 변경할 수 없습니다.
그냥 제안이지만, 제가 평소에 하는 일은 다음과 같습니다.
- 데이터베이스에서 읽거나 데이터베이스에 쓴 데이터를 포함하는 모든 변수는 null 값을 처리할 수 있어야 합니다.값 유형의 경우 Null(Of T)로 설정됩니다.참조 유형(String 및 Byte()의 경우 값을 Nothing(없음)으로 허용합니다.
- "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을 확인하고 문자열로 변환하는 가장 짧은 방법입니다.
- 셀 유효성 확인 이벤트를 생성하고 이 코드를 작성합니다.
- 변환하는 경우.ToString(dgv).현재 셀.값) = " " 그러면
- 현재 셀.값 = " "
- 종료할 경우
이것이 지금까지 변환하는 가장 쉬운 방법입니다.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: 만약sID
0과 같을 수 있고 당신은 다음과 같은 것을 하기를 원합니다.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
'programing' 카테고리의 다른 글
항목() 대신 반복 항목()을 사용해야 하는 경우는 언제입니까? (0) | 2023.05.19 |
---|---|
복제 세트 몽고 도커-구성 (0) | 2023.05.19 |
넷캣을 사용하는 최소 웹 서버 (0) | 2023.05.19 |
ListBox에서 세로 스크롤 막대를 가져오려면 어떻게 해야 합니까? (0) | 2023.05.19 |
j데이터 속성 값을 기반으로 요소를 찾는 방법을 쿼리합니까? (0) | 2023.05.19 |