【问题标题】:Update 1 of 2 columns - depending on a condition更新 2 列中的 1 - 取决于条件
【发布时间】:2016-02-08 12:37:02
【问题描述】:

在 2 名玩家的游戏中,我试图通过调用以下存储函数来允许跳过玩家的回合:

CREATE OR REPLACE FUNCTION skip_game(
        IN in_uid integer, -- player id
        IN in_gid integer) -- game id
        RETURNS void AS
$func$
BEGIN
        UPDATE games
        SET stamp1 = extract('epoch' from current_timestamp)
        WHERE gid = in_gid
        AND player1 = in_uid
        AND stamp1 < stamp2; -- it is player1's turn

        IF NOT FOUND THEN
                UPDATE games
                SET stamp2 = extract('epoch' from current_timestamp)
                WHERE gid = in_gid
                AND player2 = in_uid
                AND stamp2 < stamp1; -- it is player2's turn
        END IF;

END
$func$  LANGUAGE plpgsql;

是否可以将上述两个 UPDATE 语句合并为一个 - 并根据条件将 stamp1stamp2 设置为当前纪元时间?

另外,我不明白,为什么 PostgreSQL 9.5 总是报告 1 row 正在更新 - 如果我使用无效参数调用该函数的事件?

# select skip_game(1, 1);
 skip_game
-----------------

(1 row)

# select skip_game(95, 95);
 skip_game
-----------------

(1 row)

这是games 表(我为stamp 列使用纪元整数,以便与客户端的移动应用程序进行通信 - 它使用 SQLite):

CREATE TABLE games (
        gid SERIAL PRIMARY KEY,
        created TIMESTAMP NOT NULL,

        player1 INTEGER REFERENCES users(uid) ON DELETE CASCADE NOT NULL,
        player2 INTEGER REFERENCES users(uid) ON DELETE CASCADE,

        stamp1 INTEGER, -- timestamp of the last turn
        stamp2 INTEGER, -- timestamp of the last turn

        letters1 VARCHAR(7) NOT NULL,
        letters2 VARCHAR(7) NOT NULL,
        letters  VARCHAR(116) NOT NULL,

        board VARCHAR(225) NOT NULL,
        style INTEGER NOT NULL CHECK (1 <= style AND style <= 4)
);

【问题讨论】:

    标签: postgresql stored-procedures sql-update stored-functions postgresql-9.5


    【解决方案1】:

    使用单个UPDATE

    UPDATE games
    SET stamp1 = CASE WHEN stamp1 < stamp2 THEN extract('epoch' from current_timestamp) 
                      ELSE stamp1 END
       ,stamp2 = CASE WHEN stamp2 < stamp1 THEN extract('epoch' from current_timestamp) 
                      ELSE stamp2 END
    WHERE gid = in_gid AND (player1 = in_uid OR player2 = in_uid);
    

    【讨论】:

      【解决方案2】:

      在查询中添加条件:

      UPDATE games
      SET stamp1 = CASE  WHEN stamp1 < stamp2 THEN extract('epoch' from current_timestamp) ELSE stamp1 END,
          stamp2 = CASE  WHEN stamp2 < stamp1 THEN extract('epoch' from current_timestamp) ELSE stamp2 END
      WHERE gid = in_gid
      AND (player1 = in_uid OR player2 = in_uid); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-27
        • 2022-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多