保存数据的同时获取数据的id
Saving data and retrieving the id of the data at the same time
我刚开始 sql 有一个问题我已经处理了好几天了。
我有两个数据table。第一是书,第二是作者。本书的字段table:
图书
图书 ID (PK)
作者ID
书名
...
作者
作者 ID (PK)
作者姓名
我想在这里做的是在图书注册时为作者创建数据库。
1-书名,作者姓名将写在 Windows 表单应用程序的文本框中,然后单击保存按钮。作者名会先保存在'author'table中,然后创建id作为自动pk密钥
2-文本框上写的'author name'和作者table中对应的id会被取走
3-最后会在“书”中记录书名和作者idtable.
举个例子:
到 Windows 表单应用程序中的文本框:
书名:IT
作者姓名:斯蒂芬·金
点击保存按钮。
作者table
AuthorID:97(自动分配)
作者姓名:斯蒂芬·金
图书table
图书编号:11
作者编号:97
书名:IT
简而言之,单击一下,同时有作者和图书记录和数据库。
我试过很多方法,但我无法保存我取的作者ID。
string sqlcom1 = "INSERT INTO author (authorName) VALUES(@Pauthor)";
commandObject = new SqlCommand(sqlcom1, connectionObject );
commandObject.Parameters.AddWithValue("@Pauthor", textBoxauthorName.Text);
string sqlcom2 = "SELECT authorID FROM author WHERE authorName='" + textBoxauthorName.Text + "'");
commandObject = new SqlCommand(sqlcom2 , connectionObject );
string sqlcom3 = "INSERT INTO book (bookName,authorID) VALUES(@PbookName,@PauthorID)";
commandObject = new SqlCommand(sqlcom3, connectionObject);
commandObject.Parameters.AddWithValue("@PbookName", textBoxbookName.Text);
commandObject.Parameters.AddWithValue("@PauthorID", sqlcom2);
connectionObject.Open();
commandObject.ExecuteNonQuery();
connectionObject.Close();
错误:
'将 nvarchar 值 'SELECT authorID FROM author WHERE authorName='author30'' 转换为数据类型 int 时转换失败。'
author30 --> 我在作者姓名文本框中输入的值。
注意:我可以看到,通过向作者table注册,名称会自动分配id。作者 table 的注册正在进行中。
作者ID与书中的作者ID相关联table。
解决方案
connectionObject.Open();
string sqlcom1 = "INSERT INTO author (authorName) VALUES(@Pauthor); SELECT SCOPE_IDENTITY()";
commandObject= new SqlCommand(sqlcom1, connectionObject);
commandObject.Parameters.AddWithValue("@Pauthor", textBoxauthorName.Text);
string SolutionVariable = commandObject.ExecuteScalar().ToString();
string sqlcom3 = "INSERT INTO book (bookName,authorID) VALUES(@PbookName,@PauthorID)";
commandObject = new SqlCommand(sqlcom3, connectionObject);
commandObject.Parameters.AddWithValue("@PbookName", textBoxbookName.Text);
commandObject.Parameters.AddWithValue("@PauthorID", SolutionVariable);
commandObject.ExecuteNonQuery();
connectionObject.Close();
SQLServer 支持一个名为 OUTPUT 的子句(除其他外)INSERT 语句,它允许您为所有插入的值检索一组行。这比选择 SCOPE_IDENTITY 更有用,因为它允许您检索多个值;您可以插入 N 行,并为每个插入的行检索 O 列,例如
INSERT INTO T(CreateDate,A,B,C) --imagine that T has a PK int autonumber
OUTPUT inserted.PK,inserted.CreateDate
VALUES (GetUtcDate(),'A','BB','CCC'),(GetUtcDate(),'A2','BB2','CCC2')
ExecuteReader()
ing 这个(而不是 NonQuery)将以插入值的 2x2 结果集作为响应 - PK 和数据库计算的日期。您当然也可以在 1x1 模式下使用它(并执行标量),但通常对于 SQL,我们的目标应该是处理数据集
您需要使用SCOPE_IDENTITY()
获取插入的ID,并将其传递给另一个table。在一个命令中执行此操作。
您的代码还有许多其他问题:
- SQL注入风险
- 你没有正确配置连接
- 您应该为
varchar
个参数使用正确的长度
我将演示如何正确执行此操作
const string query = @"
INSERT INTO author (authorName)
VALUES(@Pauthor);
INSERT INTO book (bookName, authorID)
VALUES(@PbookName, SCOPE_IDENTITY());
";
using(var connectionObject = new SqlConnection(connString))
using(var commandObject = new SqlCommand(query, connectionObject))
{
commandObject.Parameters.Add("@Pauthor", SqlDbType.VarChar, 100).Value = textBoxauthorName.Text;
commandObject.Parameters.Add("@PbookName", SqlDbType.VarChar, 100).Value = textBoxbookName.Text;
connectionObject.Open();
commandObject.ExecuteNonQuery();
}
如果有多行,则需要使用 OUTPUT
子句。同样,您可以在单个批处理命令中执行此操作,只需先将其发送到 table 变量即可。
我刚开始 sql 有一个问题我已经处理了好几天了。
我有两个数据table。第一是书,第二是作者。本书的字段table:
图书
图书 ID (PK)
作者ID
书名
...
作者
作者 ID (PK)
作者姓名
我想在这里做的是在图书注册时为作者创建数据库。
1-书名,作者姓名将写在 Windows 表单应用程序的文本框中,然后单击保存按钮。作者名会先保存在'author'table中,然后创建id作为自动pk密钥
2-文本框上写的'author name'和作者table中对应的id会被取走
3-最后会在“书”中记录书名和作者idtable.
举个例子:
到 Windows 表单应用程序中的文本框:
书名:IT
作者姓名:斯蒂芬·金
点击保存按钮。
作者table
AuthorID:97(自动分配)
作者姓名:斯蒂芬·金
图书table
图书编号:11
作者编号:97
书名:IT
简而言之,单击一下,同时有作者和图书记录和数据库。
我试过很多方法,但我无法保存我取的作者ID。
string sqlcom1 = "INSERT INTO author (authorName) VALUES(@Pauthor)";
commandObject = new SqlCommand(sqlcom1, connectionObject );
commandObject.Parameters.AddWithValue("@Pauthor", textBoxauthorName.Text);
string sqlcom2 = "SELECT authorID FROM author WHERE authorName='" + textBoxauthorName.Text + "'");
commandObject = new SqlCommand(sqlcom2 , connectionObject );
string sqlcom3 = "INSERT INTO book (bookName,authorID) VALUES(@PbookName,@PauthorID)";
commandObject = new SqlCommand(sqlcom3, connectionObject);
commandObject.Parameters.AddWithValue("@PbookName", textBoxbookName.Text);
commandObject.Parameters.AddWithValue("@PauthorID", sqlcom2);
connectionObject.Open();
commandObject.ExecuteNonQuery();
connectionObject.Close();
错误: '将 nvarchar 值 'SELECT authorID FROM author WHERE authorName='author30'' 转换为数据类型 int 时转换失败。'
author30 --> 我在作者姓名文本框中输入的值。
注意:我可以看到,通过向作者table注册,名称会自动分配id。作者 table 的注册正在进行中。
作者ID与书中的作者ID相关联table。
解决方案
connectionObject.Open();
string sqlcom1 = "INSERT INTO author (authorName) VALUES(@Pauthor); SELECT SCOPE_IDENTITY()";
commandObject= new SqlCommand(sqlcom1, connectionObject);
commandObject.Parameters.AddWithValue("@Pauthor", textBoxauthorName.Text);
string SolutionVariable = commandObject.ExecuteScalar().ToString();
string sqlcom3 = "INSERT INTO book (bookName,authorID) VALUES(@PbookName,@PauthorID)";
commandObject = new SqlCommand(sqlcom3, connectionObject);
commandObject.Parameters.AddWithValue("@PbookName", textBoxbookName.Text);
commandObject.Parameters.AddWithValue("@PauthorID", SolutionVariable);
commandObject.ExecuteNonQuery();
connectionObject.Close();
SQLServer 支持一个名为 OUTPUT 的子句(除其他外)INSERT 语句,它允许您为所有插入的值检索一组行。这比选择 SCOPE_IDENTITY 更有用,因为它允许您检索多个值;您可以插入 N 行,并为每个插入的行检索 O 列,例如
INSERT INTO T(CreateDate,A,B,C) --imagine that T has a PK int autonumber
OUTPUT inserted.PK,inserted.CreateDate
VALUES (GetUtcDate(),'A','BB','CCC'),(GetUtcDate(),'A2','BB2','CCC2')
ExecuteReader()
ing 这个(而不是 NonQuery)将以插入值的 2x2 结果集作为响应 - PK 和数据库计算的日期。您当然也可以在 1x1 模式下使用它(并执行标量),但通常对于 SQL,我们的目标应该是处理数据集
您需要使用SCOPE_IDENTITY()
获取插入的ID,并将其传递给另一个table。在一个命令中执行此操作。
您的代码还有许多其他问题:
- SQL注入风险
- 你没有正确配置连接
- 您应该为
varchar
个参数使用正确的长度
我将演示如何正确执行此操作
const string query = @"
INSERT INTO author (authorName)
VALUES(@Pauthor);
INSERT INTO book (bookName, authorID)
VALUES(@PbookName, SCOPE_IDENTITY());
";
using(var connectionObject = new SqlConnection(connString))
using(var commandObject = new SqlCommand(query, connectionObject))
{
commandObject.Parameters.Add("@Pauthor", SqlDbType.VarChar, 100).Value = textBoxauthorName.Text;
commandObject.Parameters.Add("@PbookName", SqlDbType.VarChar, 100).Value = textBoxbookName.Text;
connectionObject.Open();
commandObject.ExecuteNonQuery();
}
如果有多行,则需要使用 OUTPUT
子句。同样,您可以在单个批处理命令中执行此操作,只需先将其发送到 table 变量即可。