我想在if else代码块中使用多个连接但是当我在Messagebox中签入时它会出现以下错误:
“参数提示无法转换为字符串”
这是我的代码:
Try
Conn.Open()
Com.CommandText = "Select * FROM Table1 WHERE ID=" & txtID.Text & " AND DOR=#01/01/1900# AND Paid = '0' ORDER BY DOI"
Dr = Com.ExecuteReader
If Dr.Read = True Then
txtInstNo.Text = Dr(2)
txtInstAmount.Text = Dr(4)
Else
If MsgBox("Wait! You're not allowed to do it. Do you still want to continue ? ", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "Alert") = MsgBoxResult.Yes Then
Try
Dim Con As New OleDbConnection
Dim Comm As New OleDbCommand
Dim Dr2 As OleDbDataReader
Con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database.accdb"
Con.Open()
Comm.Connection = Con
Comm.CommandText = "Select * FROM Table1 WHERE ID=" & txtID.Text & " AND DOR=#01/01/1900# AND Paid = '0' ORDER BY DOI"
Comm.CommandType = CommandType.Text
Dr2 = Comm.ExecuteReader
MsgBox(Dr2) <-- Here I got that error
If Dr.Read = True Then
txtInstNo.Text = Dr(2)
txtInstAmount.Text = Dr(4)
Else
MsgBox("Sorry, no record found",MsgBoxStyle.Exclamation, "Alert")
End If
Dr2.Close()
Con.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End If
Dr.Close()
Conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
答案 0 :(得分:0)
您的查询可能会返回整个行,对象,小部件或其他任何内容。正如@Andrew Morton指出的那样,它是一个数据阅读器。它不会隐式转换您的结果。您必须操纵读者结果并将其转换为字符串以执行任何有用的操作。如果你的DataReader返回一个null结果,你也必须处理,当转换时应该是一个空字符串。
如果您只想查看Dr2包含的内容,可以尝试使用MsgBox(CStr(Dr2))。如果它抛出异常,则不进行错误处理。
答案 1 :(得分:0)
在您的代码中可以修改一些内容,使其更短,更容易找到不起作用的内容。如果您使用最少量的代码来显示问题,则更容易隔离问题:How to create a Minimal, Complete, and Verifiable example。
我会在新表单上显示最少量代码的建议,这可以帮助您缩小问题所在的范围,然后我会解释为什么我这样编写它可能会出错
Option Strict On
Option Infer On
Imports System.Data.OleDb
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database.accdb"
Dim sql = "SELECT InstNo, InstAmount FROM Table1 WHERE ID = ? AND DOR = #01/01/1900# AND PAID='0' ORDER BY DOI"
' lists to hold the retrieved data
Dim instNos As New List(Of String)
Dim instAmounts As New List(Of String)
' get the data
Using conn As New OleDbConnection(connStr)
Using cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add(New OleDbParameter With {.ParameterName = "@ID",
.DbType = DbType.String,
.Value = txtID.Text})
conn.Open()
Dim rdr = cmd.ExecuteReader()
While rdr.Read
instNos.Add(rdr.GetString(0))
instAmounts.Add(rdr.GetString(1))
End While
End Using
End Using
' act on the data
If instNos.Count = 0 Then
MsgBox(String.Format("No records were found for ID ""{0}"".", txtID.Text))
Else
txtInstNo.Text = String.Join(vbCrLf, instNos)
txtInstAmount.Text = String.Join(vbCrLf, instAmounts)
End If
End Sub
End Class
代码。
我从Option Strict On
开始,以确保所有数据类型都匹配,我没有做任何其他愚蠢的事情,Visual Studio可以向我指出。
我使用Option Infer On
,这样当编译器可以推断它们是什么时,我不必输入变量的类型。
我在表单上只使用了一个Button以及三个命名的文本框,因为我们要使用最少的代码。
我设置了两个字符串,这些字符串将在sub的顶部的一个位置使用,因为这样更容易维护代码。通常,您可以在变量用于最小化其范围之前声明变量。
我确切地从数据库中指定了我想要的列。没有必要使用*
检索所有这些内容。我不得不猜测列的名称是什么 - 如果它们不同,你需要输入实际名称。
对数据库的查询结果可能有多条记录,因此我首先为数据初始化List。 (您的查询有ORDER BY
,所以我假设可能有多条记录。)
Using statement确保资源在干净的情况下得到释放。
对于OleDb,参数通常由?
表示。 (如果有多个,它们都用问号表示,参数必须按照它们放入查询的顺序添加。)我不得不猜测ID列的数据类型 - 请放入正确的类型。创建参数时,即使计算机忽略该参数,您仍然可以使用有意义的名称。
接下来,读取数据(如果有的话)。此时我什么都不做,除了读取数据以保持快速和整洁。我假设要检索的数据是字符串,因此是GetString。如果需要,您应该调整它,以及要匹配的列表类型。
既然数据已被读取,我就会采取行动。如果没有数据,则显示相应的消息,如果有数据,则将其放入多行文本框中以显示它。请注意,我写了多行:如果它是单行文本框,那么只有最后一行是可见的。显示它的其他方式可能更有用,例如DataGridView - 在这种情况下,我可能已将数据读入DataTable或某些类的列表。
可能出现什么问题。
在您的查询中,您有AND DOR = #01/01/1900#
- 这是正确的吗?
在您的查询中,您有AND PAID = '0'
- PAID
实际上是字符串吗?如果是数字则应为AND PAID = 0
。 (DB应该将字符串“0”转换为数字0,但为什么要使它做额外的工作?)
现在您已经为结果提供了多行文本框,您可以看到是否恰好发现最后找到的记录是空白的,并且在单行文本框中根本看不到。
最后,您确定是否正在使用正确的数据库文件?