【问题标题】:How to return inserted row from INSERT statement with php, SQL SERVER 2005?如何使用 php、SQL SERVER 2005 从 INSERT 语句返回插入的行?
【发布时间】:2011-09-16 20:53:25
【问题描述】:

在 INSERT 语句之后插入整个行的最简单/最有效的方法是什么?

我很确定我可以这样做:

$aQuery = "INSERT into myTable (a, b, c) VALUES (1, 'Hello', 'Goodbye')";
//the IDENTITY coloumn in myTable is named id
$result = sqlsrv_query($myConn, $aQuery );
if ($result) {
    $res = sqlsrv_query('SELECT LAST_INSERT_ID()');
    $row = sqlsrv_fetch_array($res);
    $lastInsertId = $row[0];
    $subQuery = "SELECT * FROM myTable where id = {$lastInsertId}";
    $subResult = sqlsrv_query($myConn, $subQuery);
    if ($subResult) {
        while($subrow = sqlsrv_fetch_array($subResult)) {
            echo($subrow ['id'] . ', '.
                 $subrow ['a'] . ', '.
                 $subrow ['b']);  //etc...
        }
     }
}

但是,我担心 another 插入发生在我的 SELECT LAST_INSERT_ID() 之前的可能性,从而扰乱了我的启动逻辑。我如何确定最后插入的 id 确实是我之前调用的 INSERT,而不是其他地方发生的事情?

有没有更合适的方法,也许是一个完整的 SQL 解决方案(这样查询会自动返回行而不是使用 PHP)?

更新:myTable DOES 有一个明确定义(且自动递增)的标识列,名为 id

【问题讨论】:

  • 你的担心很不现实。
  • 然而由于糟糕的设计每天都在发生。如果您有 1 个人使用该系统,则永远不会发生。但是当你有 100 个人同时使用同一个系统时,几率会突然急剧增加。 OP 是正确的,让它成为一个关注点并提前思考。
  • @Andrey - 我的想法完全正确。感谢您的备份。
  • @stevether 他们并非不切实际,恰恰相反。我支持一个只有几个用户(大约 40 个)的系统,并且仅仅因为 @@identity 被多次使用,错误的记录最终被更新。

标签: php sql-server sql-server-2005


【解决方案1】:

这将起作用:

"INSERT into myTable (a, b, c) OUTPUT Inserted.a, Inserted.b, Inserted.c VALUES (1, 'Hello', 'Goodbye')

【讨论】:

  • 您是如何向我的收件箱发送消息的,但这里没有您的评论?
  • 哦,呵呵。我想也许我缺少一个功能。
  • 我遇到的一个挑战是插入后,如何获得插入的结果?这就是我现在卡住的地方。
【解决方案2】:

在 Sql Server 中,您将使用 select @lastID=SCOPE_IDENTITY()

@LastID 将插入当前作用域的最后一个 id;因此,如果中间有另一个插入,您仍然会在您的选择中获得正确的记录。

切勿为此使用@@Identity,否则您可能会遇到您所描述的情况。

【讨论】:

  • 如果字段不是身份,这会起作用吗?我不认为 OP 正在使用身份字段。
  • @Andrey 好点。不,我怀疑它会起作用,但如果 OP 没有使用身份字段,他可能应该运行并添加一个;)
  • 我们不知道他在使用什么以及如何使用 ID。他可能不希望它增加 1。
  • 比你的插入语句应该是 VALUES ('Hello', 'Goodbye')
  • @Andrey,是否增量无关紧要。只要它是 PK 并且它是一个整数,我相信 SCOPE_IDENTITY() 会返回它。如果需要,可以生成 ID(实际上,在企业环境中使用手动生成的 ID 来促进复制)。但是,您的观点仍然有效,因为 PK 可能根本不是整数。它很可能是一个 GUID 或者你有什么,我认为 SCOPE_IDENTITY 在那种情况下不会起作用。我必须进行测试以确认行为,但会在今晚晚些时候,因为我现在不在了。
【解决方案3】:

如果您要使用身份字段(也许您应该这样做),有一个名为 SCOPE_IDENTIY() 的命令,您可以在此处找到该信息: http://msdn.microsoft.com/en-us/library/ms190315.aspx

由于你不使用它,你不必选择最新的数据,因为你插入时有它,所以只需使用相同的数据而不是选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 2011-05-22
    相关资源
    最近更新 更多