【问题标题】:mysql update column then select updated valuemysql更新列然后选择更新的值
【发布时间】:2014-09-01 17:10:45
【问题描述】:

我有一张这样的桌子

tbl_user

id
user_id
amount

首先我想根据 id 更新一行

$amount = 123; // dyanamic value
$sql = "UPDATE tbl_user SET amount=amount-'$amount' WHERE id='$id' LIMIT 1 ";

现在我想获取已应用此 sql 的金额列的更新值

$sql = "SELECT amount FROM tbl_user  WHERE id='$id'  LIMIT 1 ";

我的问题是我可以结合以上 sql 或任何单个查询来完成上述任务吗?

【问题讨论】:

  • 你是想在mysql还是用任何前端框架?
  • @Sadikhasan 我只想要 sql 查询
  • 你想在单个查询中做什么?
  • 更新和选择。首先更新列并减少一些动态值,然后选择新值
  • 我认为在单个查询中是不可能的。

标签: mysql sql


【解决方案1】:

您可以模仿的最好方法是使用两行查询,可能使用如下变量:

 UPDATE tbl_user SET
     amount = @amount := amount-'$amount'
 WHERE id='$id' LIMIT 1;

 SELECT @amount;

那么你能做的最好的事情就是创建一个Stored Procedure,比如:

 DELIMITER //

 CREATE PROCEDURE `return_amount` ()
 BEGIN
    UPDATE tbl_user SET
     amount = @amount := amount-'$amount'
    WHERE id='$id' LIMIT 1;

    SELECT @amount;
 END //

然后在您的PHP 中添加call Stored Procedure

注意:PostgreSQL 有这种使用 RETURNING 语句的选项,如下所示:

 UPDATE tbl_user SET amount=amount-'$amount' 
 WHERE id='$id' LIMIT 1
 RETURNING amount

here

【讨论】:

  • 我采用了第一个解决方案(使用@var 和 SELECT @var 进行更新),它仅比问题中公开的 2 个请求快 2-5%。所以我不确定使用这种改进是否很好,因为您的 SQL 变得非标准......
  • @fred727 那么,您如何根据OP的确切要求提出改进,即将两行查询合二为一?
  • 你可以这样使用:UPDATE TABLE SET columnname = columnname + 1;从表中选择列名
  • 单一查询方法能否处理来自不同进程的同时更新而没有任何副作用?
  • 这可能是列表中最差的解决方案。它不仅在进行另一个选择,授予不使用表但仍需要处理,就像其他提出的解决方案一样,由于触发器,数据可能无法反映数据库中的实际内容。如果存在或 DBA 决定稍后添加触发器以修改更新时的字段,则此解决方案将失败。它还假设 where 子句是一个唯一字段,您只会获得最后更新的值。
【解决方案2】:

一个函数可以很容易地做到这一点。听起来您想限制代码连接到数据库的次数。使用存储函数或过程,您只需建立一个连接。是的,存储的函数内部有两个查询(更新然后选择),但是这些查询是在服务器端执行的,不会停下来与客户端进行往返。

http://sqlfiddle.com/#!2/0e6a09/1/0

这是我的桌子骨架:

CREATE TABLE tbl_user (
  id       VARCHAR(100) PRIMARY KEY,
  user_id  VARCHAR(100),
  amount   DECIMAL(17,4) );

INSERT INTO tbl_user VALUES ('1', 'John', '100.00');

以及建议的功能:

CREATE FUNCTION incrementAmount
  (p_id VARCHAR(100), p_amount DECIMAL(17,4))
RETURNS DECIMAL(17,4)
BEGIN
  UPDATE tbl_user
SET amount = amount + p_amount
WHERE id = p_id;
  RETURN (SELECT amount FROM tbl_user WHERE id = p_id);
END
//

然后您只需运行一个查询,在您刚刚创建的函数上使用 SELECT

SELECT incrementAmount('1', 5.00)

查询结果为:

105

【讨论】:

【解决方案3】:

我们也可以使用:

UPDATE  tbl_user  SET id = LAST_INSERT_ID(id),  amount = 2.4,user_id=4 WHERE id = 123;

// SELECT
$id =SELECT LAST_INSERT_ID();
SELECT amount,user_id FROM tbl_user  WHERE id = $id   LIMIT 1

【讨论】:

  • 这可能是最接近的答案,但是这仍然存在原子问题。
【解决方案4】:

单个查询是不可能的,但是您可以将多个命令组合到一个脚本中,并通过对数据库服务器的单个请求来执行它们。

运行此脚本:

"UPDATE tbl_user SET amount=amount-'$amount' WHERE id='".$id."';SELECT amount FROM tbl_user  WHERE id='".$id."'; "

此外,您可能需要检查 $id 是否为数字,因为我没有看到代码中的 SQL 注入保护。 SQL 注入是一个严重的威胁,您最好做好准备并保护自己免受它的侵害。

【讨论】:

  • 我们可以使用程序吗?
  • 当然可以。如果您想这样做,则创建需要 id 值的过程并将脚本放入过程中。
  • 过程的执行时间是否比 sql 长得多?
  • 不,它没有。事实上,如果您需要在多个地方使用它,那么建议使用一个过程。
【解决方案5】:

流程如下

CREATE PROCEDURE UpdateAndSelect
(
    @amount MONEY,
    @id INT
)
AS
BEGIN

   UPDATE tbl_user
   SET amount = @amount
   WHERE id = @id
   LIMIT 1

   SELECT amount
   FROM tbl_user
   WHERE id = @id
   LIMIT 1

END
GO

你可以通过设置你的变量(@amoutn 和@id)来调用这个存储过程,然后调用:

exec UpdateAndSelect

希望这有助于解决您的问题

【讨论】:

  • 我认为这不是 MySQL 的有效语法。对我来说看起来像 T-SQL(对于 Microsoft SQL Server)。
  • 原来是T-SQL,我的错
猜你喜欢
  • 1970-01-01
  • 2014-08-26
  • 2016-06-27
  • 2021-01-04
  • 2013-10-15
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多