保存数据的同时获取数据的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 变量即可。