sql-server - 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 的相关表中。我不知道如何准确地解释我想要什么对不起>。<我只是希望有人能理解我想要什么。
解决方案
@@IDENTITY
SQL Server 通过全局字段和SCOPE_IDENTITY
仅限于当前范围的函数公开最后自动生成的 ID 。插入记录时,您可以立即查询其中一个以获取新记录的自动生成 ID。可以将其检索到您的 VB 应用程序中并使用它是适当的。
通常,您将有一个DataSet
与多个DataTables
和DataRelation
它们之间的一个。您可以配置将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
通过结果集获取值。不过,我从来没有专门尝试过。
推荐阅读
- django - 在 Django 中过滤左外连接,可以通过 values() 访问相关模型,而不是其字段
- c# - F# 返回函数
- r - 为现有数据帧中具有连续序列的每对行创建一个新数据帧
- python - 如何等待列表元素被销毁?
- laravel - 为什么在 MenaraSolutions/geographer 插件中我无法获得有关美国首都的信息?
- influxdb - Telegraf 为我的时间戳添加随机 +1 到 +10 纳秒
- sql - 在 SQL Server 中以动态范围显示计数
- c# - 如何将字符串转换为数组并对其进行解码
- openid-connect - SAML 2.0 到 OpenID Connect 缺少 SUB 声明
- typescript - 如何声明具有与枚举相同键的泛型类型?