Php MySQL:从INSERT SELECT获取返回结果

Php MySQL:从INSERT SELECT获取返回结果,php,mysql,insert,Php,Mysql,Insert,我有一个同时插入显式值和SELECTd内容的查询。我也在做基本的递增运算 INSERT INTO `table` (`myID`, `myVal1`, `myVal2`) SELECT `myID` + 1, 'explValHere', 'otherValThere') FROM `table` ORDER BY `myID` DESC LIMIT 0,1 我这样做是因为表有多个id,并且在特定列中递增。所以我不能,正如你首先说的,使用自动递增和插入id 当然,问题是insert不会返回se

我有一个同时插入显式值和SELECTd内容的查询。我也在做基本的递增运算

INSERT INTO `table` (`myID`, `myVal1`, `myVal2`) SELECT `myID` + 1, 'explValHere', 'otherValThere')
FROM `table` ORDER BY `myID` DESC LIMIT 0,1
我这样做是因为表有多个id,并且在特定列中递增。所以我不能,正如你首先说的,使用自动递增和插入id


当然,问题是insert不会返回select,但它可以吗?有没有办法运行此insert查询并返回任何结果?

您可以(在事务中)先读取值,然后执行insert语句。

在正常插入后尝试这样做

INSERT INTO `table` (`myID`, `myVal1`, `myVal2`) values ('xxx','xxxx','xxxx');
然后使用

$id=mysql_insert_id();
然后更新插入的行,如下所示

mysql_query("update table set myid=$id where id=$id");

因为您的查询有一个
限制1
,所以您可以将“结果”存储在一个数据库中。仍然有两个查询,但可重入;每个连接都是它自己的会话

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setup($pdo);

$query = "
    INSERT INTO tbl1 (myID, myVal1, myVal2)
    SELECT @foo:=myID+1, 'val1', 'val2' FROM tbl2 WHERE x=0 LIMIT 1
";
$pdo->exec($query);
foreach( $pdo->query('SELECT @foo as foo') as $row ) {
    echo $row['foo'];
}


function setup($pdo) {
    $pdo->exec('CREATE TEMPORARY TABLE tbl1 (myID int, myVal1 varchar(16), myVal2 varchar(16))');
    $pdo->exec('CREATE TEMPORARY TABLE tbl2 (myID int, x int)');
    $pdo->exec('INSERT INTO tbl2 (myID, x) VALUES (1,1),(2,1),(3,0),(4,0),(5,1)');
}

sqlserver有一个
OUTPUT
子句,非常适合这个问题。有一个关于在上面模拟的讨论。interest@ta.speot.is-shume:/如果您想返回插入的值,请编写一个查询以获取最后使用相同id插入的记录,这依赖于使用自动增量生成id,我声明此字段未使用该id。除非你想用一个自动递增的id来链接这两者。这对于另一个更新来说是非常混乱的。行为在很大程度上取决于事务隔离级别。选择了错误的等级,你就有了一个很好的比赛条件。我添加了事务要求只是为了确保没有其他选择/插入介于两者之间。当然,如果您是唯一一个不需要的用户,那么在运行topicstarters查询之前,假设innoDB引擎并使用
设置会话事务隔离级别SERIALIZABLE
,就可以了,因为这样可以停止批处理中的幻影读取->
按myID DESC LIMIT 0,1进行读取,我认为@0xCAFEBABE的意思是他的评论->“行为高度依赖于事务隔离级别。选择错误的级别,您就有了一个很好的竞争条件。”请注意,因为它不能完全确定在MySQL中如何实现
设置会话事务隔离级别可序列化
,可能会为topicstarters查询创建一个整表锁,因为没有限制
的范围,所以所有表记录都可以匹配
选择
…SQL语言从定义上讲是无序的对于表和/或结果集,使用
LIMIT
匹配“第一个”匹配记录而不使用
ORDER BY
几乎毫无意义。。SQL语言中的分页或批处理需要使用确定性的
ORDER BY
,这意味着
ORDER BY
子句中至少需要有一列具有
PRIMARY
UNIQUE
键。因此
插入tbl1(myID,myVal1,myVal2)选择@foo:=myID+1,“val1”,tbl2中的“val2”,其中x=0限制1
应该是
插入tbl1(myID,myVal1,myVal2)从tbl2中选择@foo:=myID+1,'val1',val2',其中x=0按id限制1排序
假设id列具有
主键
。。