如何解决Visual Studio 2019 .NET VB Web应用程序SQL语法错误
我想使用文本框中的两个用户输入来执行查询搜索,并在Viewgrid上显示结果,但是我想在查询中插入的参数存在问题,并且出现以下错误:
ExecQuery错误:
第1行:“。”附近的语法不正确。
必须声明变量“ @H”。
我实现了不正确的功能,还是我以错误的方式执行此操作,还是我只是试图错误地填充视图网格?如果有人能指出我正确的方向,我将不胜感激。
这是我的SQLControl
代码:
Public Class SQLControl
ReadOnly DBCon As New SqlConnection()
Private DBCmd As SqlCommand
'DB Data
Public DBDA As SqlDataAdapter
Public DBDT As DataTable
'Query Parameters
Public Params As New List(Of SqlParameter)
'Query Statistics
Public RecordCount As Integer
Public Exception As String
'This generates a blank sqlclient class with the deafult connection string
Public Sub New()
End Sub
'Allow connection string override
Public Sub New(connectionString As String)
DBCon = New SqlConnection(connectionString)
End Sub
'Execute Query Sub
Public Sub ExecQuery(query As String)
'Reset Query Stats
RecordCount = 0
Exception = ""
Try
DBCon.Open()
'Create DB Command
DBCmd = New SqlCommand(query,DBCon)
'Load Params Into DB Command
Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))
'Clear Param List
Params.Clear()
'Execute Command & Fill Dataset
DBDT = New DataTable
DBDA = New SqlDataAdapter(DBCmd)
RecordCount = DBDA.Fill(DBDT)
Catch ex As Exception
'Capture Error
Exception = "ExecQuery Error: " & vbNewLine & ex.Message
Finally
'Close Connection
If DBCon.State = ConnectionState.Open Then DBCon.Close()
End Try
End Sub
'Add Params
Public Sub AddParam(Name As String,Value As Object)
Dim NewParam As New SqlParameter(Name,Value)
Params.Add(NewParam)
End Sub
'Error Checking
Public Function HasException(Optional Report As Boolean = False) As Boolean
If String.IsNullOrEmpty(Exception) Then Return False
If Report = True Then MsgBox(Exception,MsgBoxStyle.Critical,"Exception:")
Return True
End Function
End Class
这是我执行查询的按钮:
Protected Sub ExecuteButton_Click(sender As Object,e As EventArgs) Handles ExecuteButton.Click
If StoreIDTextbox.Text.Length <= 0 Then
MsgBox("Invalid input. Please enter both Store ID and Transaction ID.")
End If
If TransactionIDTextbox.Text.Length <= 0 Then
MsgBox("Invalid input. Please enter both Store ID and Transaction ID.")
End If
SQL.AddParam("@H.Str_ID",Integer.Parse(StoreIDTextbox.Text))
SQL.AddParam("@H.Tran_ID",Integer.Parse(TransactionIDTextbox.Text))
SQL.ExecQuery("SELECT H.Emp_ID,H.Cust_ID,D.*
FROM Transaction_Header H
INNER JOIN LN_Detail L ON (H.Str_ID = L.Str_ID AND H.Rgst_ID = L.Rgst_ID AND H.Tran_ID = L.Tran_ID)
INNER Join LN_Discount D ON (L.Str_ID = D.Str_ID AND L.Rgst_ID = D.Rgst_ID AND L.Tran_ID = D.Tran_ID AND L.Tran_LN_Num = D.Tran_LN_Num)
WHERE H.Str_ID = @H.Str_ID AND H.Tran_ID = @H.Tran_ID")
If SQL.HasException(True) Then Exit Sub
GridView1.DataSource = SQL.DBDT
End Sub
解决方法
在您的课程中:
我已将您的数据库对象移至使用它们的方法,以便可以关闭和处置它们。 Using...End Using
块为您做到了。
如果您需要记录计数,可以从DataTable.Rows.Count
如果您不打算在类中处理异常,请不要在其中放置Try...End Try
。拥有数据访问类的要点之一是将用户界面与数据源分开。在您的数据访问类中显示一个消息框,对进入用户界面的链接进行硬编码。您的班级不应绑定到Windows中可以显示消息框的桌面应用程序。假设您想在网络应用中使用您的课程。您将不得不重写该类。我将Try...End Try
放在了按钮事件(用户界面代码)中,您可以在其中显示消息框。
我不理会参数处理,因为它确实保护了您的数据库免于Sql注入。但是,这不是处理Sql Server参数的最佳方法。 ADO.net必须猜测数据类型,并且可能会猜错。例如,ADO.net将字符串视为参数的值。它将NVarChar
分配为数据类型,但是数据库中的字段实际上可能是VarChar
。现在,Sql Server必须暂时将字段扩展为NVarChar
来搜索您的参数。您会看到效率低下。然后考虑数字值为6。它是整数还是某种浮点数?
在按钮代码中,我使用了Integer.TryParse
来验证用户输入,并添加了Exit Sub
以允许用户纠正错误。
显然,真正的问题是@Andrew Morton评论的。我更改了参数的名称。很多时候,联接都是从主键到外键的,但也许您有复合键。
数据访问类
Public Class SQLControl
Private ConStr As String = "Your connection string"
'Query Parameters
Public Params As New List(Of SqlParameter)
'This generates a blank sqlclient class with the deafult connection string
Public Sub New()
End Sub
'Allow connection string override
Public Sub New(connectionString As String)
ConStr = connectionString
End Sub
'Execute Query Sub
Public Function ExecQuery(query As String) As DataTable
'Params.Clear()
Dim DBDT = New DataTable
Using DBCon As New SqlConnection(ConStr),DBCmd As New SqlCommand(query,DBCon)
Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))
Params.Clear()
DBCon.Open()
DBDT.Load(DBCmd.ExecuteReader)
End Using
Return DBDT
End Function
'Add Params
Public Sub AddParam(Name As String,Value As Object)
Dim NewParam As New SqlParameter(Name,Value)
Params.Add(NewParam)
End Sub
End Class
用户界面代码
Private Sql As New SQLControl("Your connection string")
Protected Sub ExecuteButton_Click(sender As Object,e As EventArgs) Handles ExecuteButton.Click
Dim StoreID As Integer
Dim TransID As Integer
If Not Integer.TryParse(StoreIDTextbox.Text,StoreID) Then
MsgBox("Invalid input. Please enter both Store ID and Transaction ID.")
Exit Sub
End If
If Not Integer.TryParse(TransactionIDTextbox.Text,TransID) Then
MsgBox("Invalid input. Please enter both Store ID and Transaction ID.")
Exit Sub
End If
Sql.AddParam("@Str_ID",StoreID)
Sql.AddParam("@Tran_ID",TransID)
Dim dt As DataTable
Try
dt = Sql.ExecQuery("SELECT H.Emp_ID,H.Cust_ID,D.*
FROM Transaction_Header H
INNER JOIN LN_Detail L ON (H.Str_ID = L.Str_ID AND H.Rgst_ID = L.Rgst_ID AND H.Tran_ID = L.Tran_ID)
INNER Join LN_Discount D ON (L.Str_ID = D.Str_ID AND L.Rgst_ID = D.Rgst_ID AND L.Tran_ID = D.Tran_ID AND L.Tran_LN_Num = D.Tran_LN_Num)
WHERE H.Str_ID = @Str_ID AND H.Tran_ID = @Tran_ID")
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
GridView1.DataSource = dt
End Sub
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。