【问题标题】:Randomly insert 1 of 3 declared variables随机插入 3 个声明变量中的 1 个
【发布时间】:2020-01-26 03:24:53
【问题描述】:

我声明了三个变量,并为它们分配了一个整数值。

我正在尝试将整数值随机分配给 UPDATE 语句中的字段,但出现错误。

这是我要执行的语句:

FOR user_record IN (SELECT * FROM users_to_add) LOOP
    UPDATE 
        customer."user"
    SET
        primary_site_id  = ({site_GRO, site_WHS, site_SHR}[])[ceil(random()*3)],
    WHERE
        userid = (SELECT userID FROM customer.user
                  WHERE emailaddress=user_record.email_address);           
END LOOP;

我得到:

SyntaxError: syntax error at or near "{"

如果随机选择的值是一个字符串,同样的格式也适用,但由于这些是变量,内部大括号不能用引号括起来。

【问题讨论】:

  • 请始终提供您的 Postgres 版本和完整的函数 /DO 声明,以简化此操作。 site_GROsite_WHSsite_SHR 应该是单独的变量还是来自 customer."user"

标签: sql arrays postgresql random plpgsql


【解决方案1】:

使用ARRAY constructor 代替(无效的)数组字面量。

(ARRAY[site_GRO, site_WHS, site_SHR])[ceil(random()*3)]

但是,基于集合的解决方案通常比循环更有效:

UPDATE customer."user" u
SET    primary_site_id  = CASE trunc(random()*3)::int
                             WHEN 0 THEN site_gro  -- your variables here
                             WHEN 1 THEN site_whs
                             WHEN 2 THEN site_shr
                           END
FROM   users_to_add ua
WHERE  u.userid = ua.email_address;

应该达到同样的效果。在内部 PL/pgSQL 块或作为独立的SQL DML 命令工作(然后您需要自己插入变量值)。

单个多行 UPDATE比循环中的许多更新便宜得多

trunc()ceil() 稍微正确一些,因为random() 在域[0,1) 中返回一个值(1 除外)。它也更快。

CASE 构造比构建一个数组来提取单个元素要快得多。

旁白:

避免像user 这样的保留字作为标识符。总是需要双引号,并且在忘记时会导致令人困惑的错误。 还要避免标识符中的随机大写。这适用于 SQL 以及 PL/pgSQL。见:

【讨论】:

    【解决方案2】:

    也许您可以尝试将索引和数组拆分为它们自己的变量?

    FOR user_record IN (SELECT * FROM users_to_add) LOOP
      a := ARRAY[site_GRO, site_WHS, site_SHR];
      i := ceil(random()*3);
      UPDATE 
        customer."user"
      SET
        primary_site_id  = a[i]
      WHERE
        userid = (SELECT userID FROM customer.user WHERE emailaddress=user_record.email_address);        
    END LOOP;
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2011-12-13
      • 2017-05-19
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多