2017-06-07 42 views
1

我需要把一些數據放入我的SQL Server數據庫使用VB.net窗體和VB語言。我得到一個錯誤,通過VB.Net插入數據到SQL Server

我已經有一個類似的SQL請求誰正在工作,但這次我瘋狂的錯誤。

這是誰在插入數據到數據庫的代碼:

Dim strIns As String = "INSERT INTO Entreprise (adresseClient, villeClient, cpClient, telClient, identClient, nomEntreprise, secteurEntreprise, dateCreationEntreprise) VALUES ('" 
     strIns &= txtAdresse.Text & ", " & txtVille.Text & ", " & txtCp.Text & ", " & txtNumero.Text & ", " & txtID.Text & ", " & txtNom.Text & ", " & txtSecteur.Text & ", " & txtDateCreation.Text & "')" 

Dim con As New SqlConnection 
Dim cmd As New SqlCommand 

Try 
    con.ConnectionString = "Data Source= DESKTOP - KBTD2C1 \ MYDATABASE;Initial Catalog=MyDatabse; Integrated Security=SSPI;" 
    con.Open() 

    cmd.Connection = con 
    cmd.CommandText = strIns 

    cmd.ExecuteNonQuery() 

Catch ex As Exception 
    MessageBox.Show("Error While inserting record On table..." & ex.Message, "Insert Records") 
Finally 
    con.Close() 
End Try 

我得到這個錯誤:

Error while inserting record on table: Syntax error near 'Infinite'

這是SQL命令我產生strIns:

SQL Command

我不明白哪裏是語法錯誤?

這裏是我的SQL Server數據庫表:

SQL Server

+3

*永遠不*連擊SQL與用戶提供的值。 https://www.owasp.org/index。php/SQL_Injection –

+0

你需要單引號圍繞每個文本值。目前您將您的值作爲一個逗號分隔的字符串傳遞。我強烈建議使用參數。 – Filburt

+1

請參見[如何從「Bobby Tables」XKCD漫畫工作](https://stackoverflow.com/q/332365/205233)SQL注入。 – Filburt

回答

3

它看起來像你不是在申請單引號「'」周圍的每個要傳遞的價值觀。您只是將文本框的值與查詢字符串連接起來。

隨着當前的代碼您的SQL查詢會變成這樣的事:

INSERT INTO Entreprise (adresseClient, villeClient) Values ('ABC, XYZ') 

但之後將「'」周圍的價值觀將成爲:

INSERT INTO Entreprise (adresseClient, villeClient) Values ('ABC', 'XYZ') 

這是正確的版本。

另外我會說不要連接SQL查詢作爲字符串作爲機智會導致SQL注入,請改用查詢參數。

您還可以在這裏分享錯誤的詳細信息,這將有助於我們分析錯誤

+0

我冒昧地在OPs代碼組成的實際查詢中進行編輯 - 對於值括號將單個引號括起來,並將其轉換爲逗號分隔的字符串而不是預期的單個值。 – Filburt

+0

謝謝@Filburt糾正我 –

1

有個在這裏,回覆/評論例如執行在此之前使用參數。

在整個代碼中都有評論,但有一些東西在先。

將用戶界面與數據操作分開是一個好主意,因此下面的代碼是一個以類的實例的形式創建的類,調用AddNewRecord並傳回新創建的記錄的主鍵。

請注意我如何創建SQL語句,比連接字符串好得多,這對於Framework 3.5或更高版本來說更好。

希望這會有所幫助。

Imports System.Data.SqlClient 
''' <summary> 
''' Created with Framework 4.5 under 
''' VS2015 
''' </summary> 
Public Class DataOperations 
    Private Server As String = "DESKTOP - KBTD2C1 \ MYDATABASE" 
    Private Catalog As String = "MyDatabse" 
    Private ConnectionString As String = "" 
    Private mException As Exception 
    ''' <summary> 
    ''' If AddNewRecord returns false check this for 
    ''' the exception thrown. 
    ''' </summary> 
    ''' <returns></returns> 
    Public ReadOnly Property Exception As Exception 
     Get 
      Return mException 
     End Get 
    End Property 
    ''' <summary> 
    ''' Setup the connection string 
    ''' </summary> 
    Public Sub New() 
     ConnectionString = $"Data Source={Server};Initial Catalog={Catalog};Integrated Security=True" 
    End Sub 
    ''' <summary> 
    ''' I don't know you data types for fields, last one 
    ''' seemed like a date so I cast the arguments in as string 
    ''' exception for the last one. 
    ''' 
    ''' Example call would be to pass in your values. Last argument 
    ''' pass in a defined Integer e.g. Dim Id As Integer = 0 
    ''' If this function returns true then the variable Id will contain 
    ''' the new primary key value for the newly created record. 
    ''' </summary> 
    ''' <param name="adresseClient"></param> 
    ''' <param name="villeClient"></param> 
    ''' <param name="cpClient"></param> 
    ''' <param name="telClient"></param> 
    ''' <param name="identClient"></param> 
    ''' <param name="nomEntreprise"></param> 
    ''' <param name="secteurEntreprise"></param> 
    ''' <param name="dateCreationEntreprise"></param> 
    ''' <param name="NewIdentifier"></param> 
    ''' <returns></returns> 
    Public Function AddNewRecord(
     ByVal adresseClient As String, 
     ByVal villeClient As String, 
     ByVal cpClient As String, 
     ByVal telClient As String, 
     ByVal identClient As String, 
     ByVal nomEntreprise As String, 
     ByVal secteurEntreprise As String, 
     ByVal dateCreationEntreprise As Date, 
     ByRef NewIdentifier As Integer) As Boolean 

     Using cn As New SqlConnection With {.ConnectionString = ConnectionString} 
      Using cmd As New SqlCommand With {.Connection = cn} 
       ' 
       ' INSERT record then get the record's newly generated primary key 
       ' (assuming the primary key is auto-incrementing int) 
       ' 
       cmd.CommandText = 
        <SQL> 
         INSERT INTO Entreprise 
         (
          adresseClient, 
          villeClient, 
          cpClient, 
          telClient, 
          identClient, 
          nomEntreprise, 
          secteurEntreprise, 
          dateCreationEntreprise 
         ) 
         VALUES 
         (
          @adresseClient, 
          @villeClient, 
          @cpClient, 
          @telClient, 
          @identClient, 
          @nomEntreprise, 
          @secteurEntreprise, 
          @dateCreationEntreprise 
         ); 
         SELECT CAST(scope_identity() AS int); 
        </SQL>.Value 

       cmd.Parameters.AddWithValue("@adresseClient", adresseClient) 
       cmd.Parameters.AddWithValue("@villeClient", villeClient) 
       cmd.Parameters.AddWithValue("@cpClient", cpClient) 
       cmd.Parameters.AddWithValue("@telClient", telClient) 
       cmd.Parameters.AddWithValue("@identClient", identClient) 
       cmd.Parameters.AddWithValue("@nomEntreprise", nomEntreprise) 
       cmd.Parameters.AddWithValue("@secteurEntreprise", secteurEntreprise) 
       cmd.Parameters.AddWithValue("@dateCreationEntreprise", dateCreationEntreprise) 

       Try 
        cn.Open() 
        NewIdentifier = CInt(cmd.ExecuteScalar) 
        Return True 
       Catch ex As Exception 
        mException = ex 
        Return False 
       End Try 
      End Using 
     End Using 
    End Function 
End Class 

編輯:模擬了使用

Public Class example 
    Private dt As DataTable 
    Public Sub New() 
     dt = New DataTable 
     dt.Columns.Add(New DataColumn With {.ColumnName = "id", .DataType = GetType(Integer), .AutoIncrement = True}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "adresseClient", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "villeClient", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "cpClient", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "telClient", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "identClient", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "nomEntreprise", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "secteurEntreprise", .DataType = GetType(String)}) 
     dt.Columns.Add(New DataColumn With {.ColumnName = "dateCreationEntreprise", .DataType = GetType(Date)}) 
    End Sub 
    Public Sub demo() 
     Dim ops As New DataOperations 
     Dim id As Integer = 0 
     If ops.AddNewRecord("sasas", "sdsd", "fgfgf", "wew", "asd", "cvb", "xv", Now, id) Then 
      dt.Rows.Add(New Object() {id, "sasas", "sdsd", "fgfgf", "wew", "asd", "cvb", "xv", Now}) 
     End If 
    End Sub 
End Class 
+0

如果你從不使用'NewIdentifier',是否有理由在這裏使用'cmd.ExecuteScalar'? Imho'cmd.ExecuteNonQuery()'是OP得到正確的少數事情之一,你應該解釋爲什麼他應該這樣做。 – Filburt

+0

關於cmd.ExecuteScalar,請參閱我的回覆標記爲EDIT –

+0

的最後一部分我的不好 - 我錯過了評論部分的用法。 VB.NET代碼着色在這裏做的很差。 – Filburt

相關問題