2014-04-29 63 views
0

我創建了一個功能,用於執行我的數據錯誤`您必須聲明標量變量「@ ....」'

Public Function Excuter(ByVal Query As String) 
    If cn.State = ConnectionState.Open Then cn.Close() 

    cn.Open() 
    Try 

     cmd.CommandText = (Query) 
     cmd.ExecuteNonQuery() 
     cn.Close() 
    Catch ex As Exception 

     cn.Close() 
     MsgBox(ex.ToString()) 

    End Try 

End Function 

,這是我的插入代碼

Excuter("INSERT INTO Table_PatientDetail (Patient_ID , Patient_Name , Age,Sex , Phone_Number , Address, Check_In_ID, Check_Out_ID , Service , Transfer , Patient_Result) VALUES (@Patient_ID , @Patient_Name , @Age, @Sex , @Phone_Number , @Address, @Check_In_ID , @Check_Out_ID , @Service , @Transfer , @Patient_Result)") 
cmd.Parameters.AddWithValue("@Patient_ID", .PatientIDPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Patient_Name", .PatientNamePatientInformation.Text) 
cmd.Parameters.AddWithValue("@Age", .AgePatientInformation.Text) 
cmd.Parameters.AddWithValue("@Sex", .ComboBox1.Text) 
cmd.Parameters.AddWithValue("@Phone_Number", .PhoneNumPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Address", .AddressPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Check_In_ID", .CIID.Text) 
cmd.Parameters.AddWithValue("@Check_Out_ID", .COID.Text) 
cmd.Parameters.AddWithValue("@Service", .Cboservice.SelectedValue) 
cmd.Parameters.AddWithValue("@Transfer", .TransferPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Patient_Result", .ComboBox3.Text) 

當我測試它,它顯示此錯誤Must Declare Scalar Variable"@Patient_Name";我不明白。

+0

你認爲這個錯誤的含義是什麼?你熟悉sql服務器還是任何編程語言變量? –

+0

你是否在調用'Executer'之後設置Param值**?在片段中看起來如此。 – Plutonix

+0

所以你有一個全局變量來執行叫做cmd的命令。 (而且這足以讓我發抖),但是你可以調用Excuter方法,在設置參數集之前傳遞一個填充參數的字符串。不要驚訝,如果sqlserver大吼你。 – Steve

回答

4

問題是,您的Excuter函數接受查詢字符串並在您實際將參數添加到cmd對象之前執行它。一個快速和骯髒的解決辦法是打電話Excuter,這樣才簡單地填充Parameters集合:

cmd.Parameters.Clear() 'Remove any parameters left over from the previous call 
cmd.Parameters.AddWithValue("@Patient_ID", .PatientIDPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Patient_Name", .PatientNamePatientInformation.Text) 
cmd.Parameters.AddWithValue("@Age", .AgePatientInformation.Text) 
cmd.Parameters.AddWithValue("@Sex", .ComboBox1.Text) 
cmd.Parameters.AddWithValue("@Phone_Number", .PhoneNumPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Address", .AddressPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Check_In_ID", .CIID.Text) 
cmd.Parameters.AddWithValue("@Check_Out_ID", .COID.Text) 
cmd.Parameters.AddWithValue("@Service", .Cboservice.SelectedValue) 
cmd.Parameters.AddWithValue("@Transfer", .TransferPatientInformation.Text) 
cmd.Parameters.AddWithValue("@Patient_Result", .ComboBox3.Text) 
Excuter("INSERT INTO Table_PatientDetail (Patient_ID , Patient_Name , Age,Sex , Phone_Number , Address, Check_In_ID, Check_Out_ID , Service , Transfer , Patient_Result) VALUES (@Patient_ID , @Patient_Name , @Age, @Sex , @Phone_Number , @Address, @Check_In_ID , @Check_Out_ID , @Service , @Transfer , @Patient_Result)") 

然而,因爲這段代碼重用多次調用連接和命令,似乎很脆弱。例如,您每次打電話時都必須記得清除Parameters集合,否則最終會出現非常奇怪的錯誤。我會建議重構你的代碼,以便每個數據庫調用都是更獨立的。

1

您正在調用Executer執行查詢,並且一旦查詢執行完,您將添加參數;但是,這太遲了。您必須在cmd.ExecuteNonQuery()之前致電cmd.Parameters.AddWith(...)

將參數添加到Executer Sub,允許您將可變數量的參數傳遞給您的查詢。既然你不能輕易地在同一時間傳遞的參數名稱,只是名稱參數@0@1@2,...

Public Sub Executer(query As String, ParamArray parameters As Object()) 
    Using cn = New SqlConnection(ConnectionString) 
     Using cmd = New SqlCommand(query, cn) 
      For i As Integer = 0 To parameters.Length - 1 
       cmd.Parameters.AddWithValue("@" & i, parameters(i)) 
      Next 
      cn.Open() 
      Try 
       cmd.ExecuteNonQuery() 
      Catch ex As Exception 
       Interaction.MsgBox(ex.ToString()) 
      End Try 
     End Using 
    End Using 
End Sub 

注意Using語句後自動關閉連接。即使發生異常,也是如此。還要注意我已經在方法中聲明瞭連接和命令對象。這樣你就不必在多次通話中追蹤他們的狀態。現在

,你可以這樣調用執行者(我縮短了查詢了一下):

Const InsertPatientDetailSql As String = _ 
    "INSERT INTO Table_PatientDetail (ID, Name, Age) VALUES (@0, @1, @2)" 
Executer(InsertPatientDetailSql, 42, "John Doe", 35) 

這是Executer的使用真正的簡化,比起你的方法。