首页 > 解决方案 > VB.NET 和 SQL Server 从 maint 表中获取 PK ID 并发送到依赖表中的 FK

问题描述

我想寻求一些帮助,我是 VB 和 SQL 的初学者,我目前正在做一些学校活动,我在如何获取我的主表的自动递增 PK 时遇到了麻烦,主表是 tbl_personalinfo,PK“PID”我想在我的 Personalinfo 表中插入数据后获取我的主表的 PK ID 并将其值发送到具有 FK PID 的相应依赖表?我需要从主表中获取 PK ID 的值并将其发送到具有 FK PID 的相关表,我不知道我是否清楚或可以理解我的问题,但如果有人可以提供帮助。我会非常感激。

Dim insertquery As String = "insert into tbl_PersonalInfo (FirstName, LastName, MiddleName, DateOfBirth, PlaceOfBirth, TinNo, GsisNo, PagIbigNo, PhilhealthNo, SSSNo, AgencyEmployeeNo, Citizenship, Height, Weight, Sex, CStatus) values (@FirstName,@LastName, @MiddleName, @DateOfBirth, @PlaceOfBirth, @TinNo, @GsisNo, @PagibigNo, @PhilhealthNo, @SSSNo, @AgencyEmployeeNo, @Citizenship, @Height, @Weight, @Sex, @CStatus)" 
execquery(insertquery)
 Public Sub execquery(ByVal query As String)
    Dim cmd As New SqlCommand(query, connection)
    cmd.Parameters.AddWithValue("@FirstName", txtboxFN.Text)
    cmd.Parameters.AddWithValue("@LastName", txtboxSN.Text)
    cmd.Parameters.AddWithValue("@MiddleName", txtboxMN.Text)
    cmd.Parameters.AddWithValue("@DateOfBirth", DateTimePicker1.Value)
    cmd.Parameters.AddWithValue("@PlaceOfBirth", txtboxPOB.Text)
    cmd.Parameters.AddWithValue("@TinNo", txtboxTIN.Text)
    cmd.Parameters.AddWithValue("@GsisNo", txtboxGSIS.Text)
    cmd.Parameters.AddWithValue("@PagIbigNo", txtboxPagibig.Text)
    cmd.Parameters.AddWithValue("@PhilhealthNo", txtboxPhilhealth.Text)
    cmd.Parameters.AddWithValue("@SSSNo", txtboxSSS.Text)
    cmd.Parameters.AddWithValue("@AgencyEmployeeNo", txtboxAgency.Text)
    cmd.Parameters.AddWithValue("@Citizenship", CboxCitizenship.Text)
    cmd.Parameters.AddWithValue("@Height", txtboxHeight.Text)
    cmd.Parameters.AddWithValue("@Weight", txtBoxWeight.Text)
    cmd.Parameters.AddWithValue("@Sex", CboxSex.Text)
    cmd.Parameters.AddWithValue("@CStatus", CboxStatus.Text)
    connection.Open()
    cmd.ExecuteNonQuery()
    connection.Close()

这是我的插入代码,我应该在哪里添加查询以获取最后插入的 ID?顺便说一句,它指的是PID吗?我的PK是哪个?我真正想做的是在将数据插入主表之后,我想获取最后插入的 ID,以便我将数据插入到具有 FK PID 的相关表中。我不知道如何准确地解释我想要什么对不起>。<我只是希望有人能理解我想要什么。

标签: sql-servervb.net

解决方案


@@IDENTITYSQL Server 通过全局字段和SCOPE_IDENTITY仅限于当前范围的函数公开最后自动生成的 ID 。插入记录时,您可以立即查询其中一个以获取新记录的自动生成 ID。可以将其检索到您的 VB 应用程序中并使用它是适当的。

通常,您将有一个DataSet与多个DataTablesDataRelation它们之间的一个。您可以配置将DataRelation更新从父表传播到子表。发生的情况是,当您将行添加到您的 时DataTables,会生成临时 ID。您可以使用父行中的临时 ID 作为子行中的外键值。当您将父数据保存到数据库时,数据库生成的最终 ID 将被检索回父数据DataTable以替换临时值,并将DataRelation这些更改传播给子数据DataTable。然后使用正确的数据库外键值保存子数据。

如果您不使用 aDataTable那么您可以在用于保存父记录的命令对象上使用输出参数来检索自动生成的 ID 并在您的子记录中使用它。

Dim data As New DataSet

Dim parentTable = data.Tables.Add("Parent")
Dim childTable = data.Tables.Add("Child")

Dim parentIdColumn = parentTable.Columns.Add("ParentId", GetType(Integer))
parentTable.Columns.Add("ParentName", GetType(String))

'Configure auto-generated temporary primary key values to easily distinguish them from final values.
With parentIdColumn
    .AutoIncrement = True
    .AutoIncrementSeed = -1
    .AutoIncrementStep = -1
End With

parentTable.PrimaryKey = {parentIdColumn}

Dim childIdColumn = childTable.Columns.Add("ChildId", GetType(Integer))
childTable.Columns.Add("ChildName", GetType(String))
Dim foreignKeyColumn = childTable.Columns.Add("ParentId", GetType(Integer))

'Configure auto-generated temporary primary key values to easily distinguish them from final values.
With childIdColumn
    .AutoIncrement = True
    .AutoIncrementSeed = -1
    .AutoIncrementStep = -1
End With

childTable.PrimaryKey = {childIdColumn}

Dim parentChildRelation = data.Relations.Add("ParentChild", parentIdColumn, foreignKeyColumn)

'Propagate changes to parent IDs from the parent table to the child.
parentChildRelation.ChildKeyConstraint.UpdateRule = Rule.Cascade

Dim connection As New SqlConnection("connection string here")

Dim parentAdapter As New SqlDataAdapter("SELECT * FROM Parent", connection)
Dim childAdapter As New SqlDataAdapter("SELECT * FROM Child", connection)

'Include a query on insert to retrieve the auto-generated ID.
Dim parentInsertCommand As New SqlCommand("INSERT INTO Parent (ParentName) VALUES (@ParentName); SELECT ParentId = SCOPE_IDENTITY();", connection)

parentInsertCommand.Parameters.Add("@ParentName", SqlDbType.VarChar, 50, "ParentName")
parentAdapter.InsertCommand = parentInsertCommand

'Include a query on insert to retrieve the auto-generated ID.
Dim childInsertCommand As New SqlCommand("INSERT INTO Child (ChildName, ParentId) VALUES (@ChildName, @ParentId); SELECT ChildId = SCOPE_IDENTITY();", connection)

childInsertCommand.Parameters.Add("@ChildName", SqlDbType.VarChar, 50, "ChildName")
childInsertCommand.Parameters.Add("@ParentId", SqlDbType.Int, 0, "ParentId")
childAdapter.InsertCommand = childInsertCommand

'Retrieve existing data.
connection.Open()
parentAdapter.Fill(parentTable)
childAdapter.Fill(childTable)
connection.Close()

'Add new data.

Dim parentRow = parentTable.NewRow()

parentRow("ParentName") = "New Parent"
parentTable.Rows.Add(parentRow)

Dim parentId = parentRow(parentIdColumn)

Dim childRow = childTable.NewRow()

childRow("ChildName") = "New Child 1"
childRow(foreignKeyColumn) = parentId
childTable.Rows.Add(childRow)

childRow = childTable.NewRow()

childRow("ChildName") = "New Child 2"
childRow(foreignKeyColumn) = parentId
childTable.Rows.Add(childRow)

'View the IDs.
Console.WriteLine("Before save:")
Console.WriteLine("ParentId: {0}", parentId)

For Each childRow In childTable.Rows
    Console.WriteLine("ChildId: {0}; ParentId: {1}", childRow(childIdColumn), childRow(foreignKeyColumn))
Next

'Save the parent changes.
parentAdapter.Update(parentTable)

'View the IDs.
Console.WriteLine("During save:")
Console.WriteLine("ParentId: {0}", parentId)

For Each childRow In childTable.Rows
    Console.WriteLine("ChildId: {0}; ParentId: {1}", childRow(childIdColumn), childRow(foreignKeyColumn))
Next

'Save the child changes.
parentAdapter.Update(parentTable)

'View the IDs.
Console.WriteLine("After save:")
Console.WriteLine("ParentId: {0}", parentId)

For Each childRow In childTable.Rows
    Console.WriteLine("ChildId: {0}; ParentId: {1}", childRow(childIdColumn), childRow(foreignKeyColumn))
Next

我实际上并没有明确地测试过该代码,而且我现在不能正确,但我以前做过这些东西,并且相当有信心这是正确的。我会尽快对其进行正确测试并进行可能需要的任何更改。

需要注意的最重要的一点是InsertCommand属性中的 SQL 代码和DataRelation.

这是一个使用示例ExecuteNonQuery

Dim connection As New SqlConnection("connection string here")

'Include a query on insert to retrieve the auto-generated ID.
Dim parentInsertCommand As New SqlCommand("INSERT INTO Parent (ParentName) VALUES (@ParentName); SELECT @ParentId = SCOPE_IDENTITY();", connection)

parentInsertCommand.Parameters.Add("@ParentName", SqlDbType.VarChar, 50).Value = "New Parent"

Dim parentIdParameter = parentInsertCommand.Parameters.Add("@ParentId", SqlDbType.Int)

parentIdParameter.Direction = ParameterDirection.InputOutput

connection.Open()
parentInsertCommand.ExecuteNonQuery()
connection.Close()

Dim parentId = CInt(parentIdParameter.Value)

从理论上讲,该参数Direction应该是Output,但根据我的经验,这不起作用,您需要使用InputOutput. 另请注意,您应该能够在没有参数和调用的情况下ExecuteScalar通过结果集获取值。不过,我从来没有专门尝试过。


推荐阅读