【问题标题】:A question about SQL insert statement!一个关于SQL插入语句的问题!
【发布时间】:2011-05-30 08:26:29
【问题描述】:

我有两张桌子:

Threads
*******
ThreadID
UserID
TopicsID
Date
ThreadTitle
ThreadParagraph
ThreadClosed

Topics
******
TopicID
Theme
Topics
Date

我需要插入两条语句并在它们之间连接! 这是第一句话:

string insertCommand = 
    "INSERT INTO Users (UserID,TopicID,Date,ThreadTitle,ThreadParagraph) " +
     "VALUES ('CONVERT(uniqueidentifier, '" + giveMeGuidID() + 
     "),TopicID,dateTime,questionTitle,subTopic)";

我需要为主题表添加另一个声明:

string insertCommand = 
    "INSERT INTO Topics (UserID,TopicID,Date,ThreadTitle,ThreadParagraph) " +
    "VALUES ('Theme, Topics, Date')";

问题是我在 TopicsID(线程表)和 TopicsID 之间建立了连接 (主题表)。两者都是增量整数,所以我如何插入相同的 TopicID 他们两个,所以他们得到相同的价值?

【问题讨论】:

  • 您能否更详细地说明您是如何调用这些插入命令的。就个人而言,我会创建一个存储过程 - 这将能够使用 @@identity 返回创建的 ID
  • 这是@guagland 建议的链接:msdn.microsoft.com/en-us/library/ms187342.aspx
  • 不完全符合您的要求,但我更喜欢使用自动处理此问题的数据访问层,例如linq-to-sql。
  • 我宁愿忽略 linq 的整个想法

标签: c# asp.net sql


【解决方案1】:

如果你使用MS SQL server,你可以通过@@Identity 获取自增值。

string insertCommand = 
    "INSERT INTO Users (UserID,TopicID,Date,ThreadTitle,ThreadParagraph) " +
    "VALUES ('CONVERT(uniqueidentifier, '" + giveMeGuidID() +
    "),TopicID,dateTime,questionTitle,subTopic); SELECT @@Identity";

然后,将此命令作为 ExecuteScalar 运行并获取您的值

【讨论】:

  • 或创建一个在事务中一次插入 2 行的存储过程
  • @@Identity 获取最后插入的身份。 SQL Server 可以同时为许多应用程序提供服务,因此@@Identity 可能会返回其他人正在执行的操作的标识,如果他们设法在您的 INSERT 和 SELECT 之间获取他们的 INSERT 语句。请改用 SCOPE_IDENTITY()。
  • 所以你使用@@Select 来获取身份。身份是一个“int”,我可以将其输入另一个 sql insert 语句,该语句将在 Topic 表中插入 TopicID。我如何处理 Select @@identity
【解决方案2】:

您可以使用TransactionScope 维护Transaction,并使用SCOPE_IDENTITY() 从第一个查询中获取插入的Id。

 // Create the TransactionScope
using (TransactionScope oTranScope = new TransactionScope())
{
   Int32 TopicID;
    // Open a connection 
    using (SqlConnection oCn1 = new SqlConnection(this.sCn1))
    {
        SqlCommand oCmd1 = new SqlCommand("INSERT INTO Users (UserID,TopicID,Date,ThreadTitle,ThreadParagraph) " +
"VALUES ('CONVERT(uniqueidentifier, '" + giveMeGuidID() +
"),TopicID,dateTime,questionTitle,subTopic); SELECT SCOPE_IDENTITY()";, oCn1);

        oCmd1.Parameters.Add ... Better to use parameter to save SQL Injection Attack

        oCn1.Open();
        // At this point, the connection is in the transaction scope, 
        // which is a lightweight transaction.
        TopicID = Convert.ToInt32 oCmd1.ExecuteScaler()); // as you want to get Id
        oCn1.Close();
    }
    // Open a connection 
    using (SqlConnection oCn2 = new SqlConnection(this.sCn2))
    {
        SqlCommand oCmd2 = new SqlCommand("SQLQuery", oCn2);
        //use return TopicID from last inserted query
        oCn2.Open();
        // The connection is enlisted in the transaction scope, 
        // which is now promoted to a distributed transaction
        // controlled by MSDTC
        oCmd2.ExecuteNonQuery();
        oCn2.Close();
    }
    // Tell the transaction scope to commit when ready 
    oTranScope.Consistent = true;
    // The following bracket completes and disposes the transaction
}

【讨论】:

  • 你用topicID做什么,不应该有2条sql语句。另一个插入带有 topicParagraph、topicTitle 和 Date 的 TopicID 的 sql 语句?
【解决方案3】:

如果您正在寻找可靠的东西,您需要使用 Transactions。

请参阅Managing Transactions in SQL Server Stored Procedures 了解一下。

另外,看看Controlling Transactions (Database Engine) 和SQL Server Transaction Isolation Models。

您还需要使用最后插入的标识值@@Identity。

【讨论】:

    【解决方案4】:

    您的代码示例与所提供的其余信息的相关性不高。但是,如果没有代码,您的帖子似乎足够一致,所以我倾向于认为这些 sn-ps 完全是错误的。

    不管怎样,你的想法似乎很清楚。在 SQL Server 2005+ 中,您可以使用这样的 INSERT 语句解决您的问题:

    string insertCommand = 
        "INSERT INTO Topics (Theme, Topics, Date) " +
          "OUTPUT 'CONVERT(uniqueidentifier, '" + giveMeGuidID() +
          "'), INSERTED.TopicID, @dateTime, @questionTitle, @subTopic " +
          "INTO Threads (UserID, TopicID, Date, ThreadTitle, ThreadParagraph) " +
        "VALUES (@Theme, @Topics, @Date)";
    

    虽然这是一条语句,但它对不同的表执行了两次插入操作。 'main' 插入被放入Topics 表中。 Threads 中的“次要”是由OUTPUT...INTO 子句定义的。基本上,OUTPUT 子句允许您引用正在插入的数据并将它们作为行集返回给客户端,或者(与INTO 结合使用时)将它们引导到现有表中,就像您可以看到它在这里完成的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 1970-01-01
      • 2010-12-09
      相关资源
      最近更新 更多