1

我在 vb.net 中使用函数。我正在查询 sql 到 datagridview 并将数据从 datagridview 插入到 Databse By 函数。

但功能错误:在此上下文中不允许使用名称“EXHBK13004”。此处仅允许使用常量、表达式或变量。不允许使用列名。

我想使用插入数据库的函数。

桌布

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”不插入数据库。

谢谢你的时间。:))

4

2 回答 2

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 语句关闭连接

于 2013-07-19T10:54:25.257 回答
1

您需要将字符串值放在引号中。

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

也就是说,您不应该使用串联构建查询字符串。这会使您的查询受到 SQL 注入攻击。相反,您应该使用参数化查询。(正如史蒂夫在他的回答中显示的那样)。

于 2013-07-19T10:55:14.143 回答