1

我使用vb.net的功能。我是查詢sql到datagridview並從datagridview插入數據到Databse按功能。如何使用函數VB.NET插入數據庫?

但功能錯誤:在此上下文中不允許使用名稱'EXHBK13004'。這裏只允許常量,表達式或變量。列名不被允許。

我想用插入到數據庫的函數。

表CLOTHER

Name  Type 
No (PK) int 
Code  nvarchar(12) 
RClother int 
CIDetail int 
PO  nvarchar(50) 

代碼(按鈕保存)

Private Sub btSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSave.Click 

    For i As Integer = 0 To DgvItem.Rows.Count - 1 
     sendPDTStatus = FInsertClother(CStr(DgvItem.Rows(i).Cells(0).Value), CInt(DgvItem.Rows(i).Cells(1).Value), CInt(DgvItem.Rows(i).Cells(2).Value), _ 
     DgvItem.Rows(i).Cells(3).Value) 
    Next 

End Sub 

代碼功能

Public Function FInsertClother(ByVal Code As String, ByVal RClother As Integer, ByVal CIDetail As Integer, ByVal PO As String)  
      Dim Tr As SqlTransaction 
      Dim sqlCom As New SqlCommand 

      Dim sqlInsert As String 
      Dim ReturnValue As Integer 

      Tr = Conn.BeginTransaction 
      sqlCom.Connection = Conn 

      sqlInsert = "INSERT INTO Clother " 
      sqlInsert &= "(Code,RClother,CIDetail,PO) " 
      sqlInsert &= "VALUES(" & Code & "," & RClother & "," & CIDetail & "," & PO & ")" 

      sqlCom.Transaction = Tr 
      sqlCom.CommandText = sqlInsert 
      sqlCom.CommandType = CommandType.Text 

      ReturnValue = sqlCom.ExecuteScalar << Line Error 
      If ReturnValue = 0 Then 
       Tr.Commit() 
      Else 
       Tr.Rollback() 
      End If 
    Return ReturnValue  
End Function 

我嘗試調試這個結果

Name     Value 
sqlCom.CommandText "INSERT INTO Clother (Code,RClother,CIDetail,PO) VALUES(050030543003,5022,30543,EXHBK13004/3)" 

sqlInsert   "INSERT INTO Clother (Code,RClother,CIDetail,PO) VALUES(050030543003,5022,30543,EXHBK13004/3)" 

只有場「PO」不插入到數據庫。

謝謝你的時間。 :))

回答

1

關閉連接。您需要將字符串值放在引號中。

sqlInsert &= "VALUES('" & Code & "'," & RClother & "," & CIDetail & ",'" & PO & "')" 

也就是說,你不應該使用連接來建立一個查詢字符串。這使您的查詢受到SQL注入攻擊。相反,你應該使用參數化查詢。 (正如史蒂夫在他的回答中所表明的)。

2

首先,我會刪除字符串連接,並使用參數化查詢,以避免解析問題和Sql注入(在您的代碼中,您已經傳遞了兩個字符串而不使用引號,這肯定會導致插入失敗,因爲字符串字段需要一個引號分隔符)

然後我也刪除事務,因爲現在循環執行並確認每行的單個命令。

此外,您似乎有一個全局連接對象,這是一個不好的做法,您應該打開連接並儘快關閉它,而不會在應用程序的整個生命週期中保持打開狀態。

Public Function FInsertClother(ByVal Code As String, ByVal RClother As Integer, ByVal CIDetail As Integer, ByVal PO As String)  

    Dim sqlInsert As String 
    Dim ReturnValue As Integer 

    sqlInsert = "INSERT INTO Clother " & _ 
       "(Code,RClother,CIDetail,PO) " & _ 
       "VALUES(@code, @clot, @id, @po)" 

    Using sqlCom = new SqlCommand(sqlInsert, conn) 
     sqlCom.Connection = Conn 
     sqlCom.Parameters.AddWithValue("@code",Code) 
     sqlCom.Parameters.AddWithValue("@clot", RClother) 
     sqlCom.Parameters.AddWithValue("@id",CIDetail) 
     sqlCom.Parameters.AddWithValue("@po",PO) 
     ReturnValue = sqlCom.ExecuteNonQuery 
     Return ReturnValue  
    End Using 
End Function 

一個非常有用的增強功能是打開按鈕單擊連接並將其傳遞給此函數。因此,當您完成循環遍歷行時,您可以通過Using Statement

+1

不錯的快速編碼。 – jfrankcarr

相關問題