我试图通过一个SQL查询(对于MySQL)来实现以下目标:
我想将一行从一个表移到另一个表,同时更改其两个值。
我可以在一个查询中实现这一目标吗? 我现在有的PHP代码:
$value1a = "Old value for this column";
$value1b = "New value for this column";
$value2 = "value2";
$sql = "INSERT INTO table2 (date, value1b, value2, value3, value4)
SELECT (date, value1a, value2, value3, value4)
FROM table1
WHERE value1a=? AND value2=?
DELETE FROM table1
WHERE value1a=? AND value2=?";
$stmt = $DB->prepare($sql);
$stmt->execute(array($value1a, $value2, $value1a, $value2));
value2,value3和value4保持不变。 '日期'应该更改为当前日期(我之前使用过SQL函数' NOW()')。 ' value1b'是一个全新的值,具有不同的列名但具有相同的数据类型。
这可能是答案吗?
$sql = "INSERT INTO table2 (date, value1b, value2, value3)
SELECT (value3, value4)
FROM table1
WHERE value1a=? AND value2=?
VALUES (NOW(), ?, value2, value3, value4)
DELETE FROM table1
WHERE value1a=? AND value2=?";
$stmt = $DB->prepare($sql);
$stmt->execute(array($value1a, $value2, $value1b, $value1a, $value2));
答案 0 :(得分:2)
您的第一次尝试非常接近,但您只想略微更改SELECT部分。您可以选择值的函数而不仅仅是原始值,因此SELECT部分可以看起来像
SELECT (NOW(), value1a, value2, value3, value4) FROM table1 ...
但这仍然不是一个单独的SQL语句,因为DELETE行是一个单独的语句。你不能一次性完成INSERT和DELETE。
为什么你想在一个声明中做到这一点?是因为你想要同时发生这两件事吗?如果是这样,您应该查看交易:这是他们的目的。开始交易;做你的INSERT;做你的删除;然后提交交易。看到数据库的任何其他东西都会看到整个事情是以原子方式完成的(换句话说,没有任何东西会看到数据库插入行但另一行没有被删除)。
答案 1 :(得分:1)
执行INSERT INTO ...SELECT FROM
语句时,您可以直接在SELECT
列表中使用静态值,以及函数调用(如NOW()
)。然后,您可以构造SELECT
语句,以便一次性包含所有最终需要的值:
INSERT INTO table2 (date, value1b, value2, value3, value4)
SELECT
/* call NOW() in SELECT */
NOW(),
/* Use a static string for the value1b column */
/* (the alias 'AS value1b' isn't really needed) */
'New value for this column' AS value1b,
/* These don't change, and are the actual column values from table1 */
value2,
value3,
value4
FROM table1
WHERE value1a = ? AND value2 = ?
现在执行语句时,您将只有2个参数。您还可以使用参数而不是value1b
的静态字符串。如果此值是从用户输入派生的,那么您肯定希望这样做。
INSERT INTO table2 (date, value1b, value2, value3, value4)
SELECT
/* call NOW() in SELECT */
NOW(),
/* parameter here instead of static string.... */
?,
value2,
value3,
value4
FROM table1
WHERE value1a = ? AND value2 = ?
...然后使用3个参数的数组调用execute()
。
$stmt->execute(array($value1b, $value1a, $value2));
成功执行INSERT
后,删除语句必须作为单独的语句执行。假设您想要保持这些之间的原子性(您希望将它们作为一个查询的原因),请将它们包装在事务中:
$DB->beginTransaction();
// Perform the INSERT
// On success, perform the DELETE
// And finally commit the transaction.
$DB->commit();