System.Data.SqlClient.SqlException:违反主键

时间:2019-07-27 15:43:19

标签: sql vb.net

我创建了一个SQL Server数据库,我想在该数据库的特定表中添加一些数据。我使用一些文本框输入数据,并使用添加按钮完成操作。但是,当我点击按钮时,整个过程停止了,并在DBSQL模块中指出了错误,如下所示。

这是我的代码:

Imports System.Data
Imports System.Data.SqlClient

Module DBSQLServer
    Public con As New SqlConnection("Data Source=JOYALXDESKTOP\SQLEXPRESS;Initial Catalog=SaleInventory;Integrated Security=True")
    Public cmd As New SqlCommand
    Public da As New SqlDataAdapter
    Public ds As New DataSet
    Public dt As DataTable
    Public qr As String
    Public i As Integer

    Public Function searchdata(ByVal qr As String) As DataSet
        da = New SqlDataAdapter(qr, con)
        ds = New DataSet
        da.Fill(ds)
        Return ds

    End Function

    Public Function insertdata(ByVal qr As String) As Integer

        cmd = New SqlCommand(qr, con)
        con.Open()
        i = cmd.ExecuteNonQuery()
        con.Close()
        Return i

    End Function
End Module

此行发生错误:

i = cmd.ExecuteNonQuery()

在表中,我有5列:

ProID, ProName, ProDesc, ProPrice, ProStock

ProID是我的主键。

这是我的添加按钮代码,用于将数据添加到数据库中:

Private Sub Add_Click(sender As Object, e As EventArgs) Handles add.Click
        If (isformvalid()) Then
            qr = "Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values('" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')"
            Dim logincorrect As Boolean = Convert.ToBoolean(insertdata(qr))
            If (logincorrect) Then
                MsgBox("Stock Added Successfully ...", MsgBoxStyle.Information)
            Else
                MsgBox("Something Wrong. Record Not Saved. Please Check and Try Again...", MsgBoxStyle.Critical)
            End If
        End If
    End Sub

当我的查询是:

qr = "Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values('" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')"

错误如下:

  

System.Data.SqlClient.SqlException:'无法将值NULL插入表'SaleInventory.dbo.tblProductInfo'的列'ProID'中;列不允许为空。 INSERT失败。

当我的查询是:

qr = "Insert into tblProductInfo (ProID, ProName, ProDesc, ProPrice, ProStock) Values('" & idtext.Text & "','" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')"  `

然后错误是:

  

System.Data.SqlClient.SqlException:'违反了主键约束'PK_tblProductInfo'。无法在对象“ dbo.tblProductInfo”中插入重复的密钥。重复的键值为(1)。

2 个答案:

答案 0 :(得分:0)

这是因为在tblProductInfo中有一行ProID = 1。您应该进行编码,以避免重复,例如,您可以首先运行脚本以在表中查找最大的ProID(“从tblProductInfo中选择MAX(ProID)”),然后使用MAX(ProID)+1运行查询。

答案 1 :(得分:0)

假设您已更正数据库,使ProdID成为身份字段。

请注意,所有与用户界面的交互均在表单代码中执行。与数据库的所有交互都在模块中执行。尽管您仍然需要导入System.Data(用于DataTable类型),但不必在Form中导入System.Data.SqlClient。所有验证均在表单中完成。

在模块代码中,Using ... EndUsing块可确保即使发生错误也可以关闭并处置数据库对象。我已经演示了如何使用参数来避免Sql注入,但是我不得不猜测数据类型。检查数据库中的实际数据类型,并相应地调整SqlDbType以及表单中的参数类型和验证代码。

连接是宝贵的资源。请注意,连接在最后一分钟打开,并由End Using关闭并由和使用后立即释放。Execute...

Module DBSQLServer
    Private conString As String = "Data Source=JOYALXDESKTOP\SQLEXPRESS;Initial Catalog=SaleInventory;Integrated Security=True"

    'Example of how your search function might look.
    Public Function searchdata(Name As String) As DataTable
        Dim dt As New DataTable
        Using cn As New SqlConnection()
            Using cmd As New SqlCommand("Select * From tblProductInfo Where Name = @Name", cn)
                cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name
                cn.Open()
                dt.Load(cmd.ExecuteReader)
            End Using
        End Using
        Return dt
    End Function

    Public Function insertdata(Name As String, Description As String, Price As Decimal, Stock As Integer) As Integer
        Dim i As Integer
        Using cn As New SqlConnection(conString)
            Using cmd As New SqlCommand("Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values(@Name,@Description, @Price, @Stock", cn)
                With cmd.Parameters
                    .Add("@Name", SqlDbType.VarChar).Value = Name
                    .Add("@Description", SqlDbType.VarChar).Value = Description
                    .Add("@Price", SqlDbType.Decimal).Value = Price
                    .Add("@Stock", SqlDbType.Int).Value = Stock
                End With
                cn.Open()
                i = cmd.ExecuteNonQuery
            End Using
        End Using
        Return i
    End Function
End Module

并以格式

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'First check that  text boxes for string parameters are filled in
    If nametext.Text = "" OrElse descriptiontext.Text = "" Then
        MessageBox.Show("Please fill in all text boxes.")
        Return
    End If
    'Next check for valid numeric values
    Dim price As Decimal
    If Not Decimal.TryParse(pricetext.Text, price) Then
        MessageBox.Show("The price must be a number.")
        Return
    End If
    Dim stock As Integer
    If Not Integer.TryParse(stocktext.Text, stock) Then
        MessageBox.Show("Stock must be a whole number")
        Return
    End If
    Dim retVal As Integer = DBSQLServer.insertdata(nametext.Text, descriptiontext.Text, price, stock)
    If retVal = 1 Then
        MessageBox.Show("Product successfully added.")
    End If
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim dt = DBSQLServer.searchdata(txtSearch.Text)
    DataGridView1.DataSource = dt
End Sub