Случайно вставить 1 из 3 объявленных переменных - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть три переменные, которые объявлены и им присвоено целочисленное значение.

Я пытаюсь случайным образом назначить целочисленное значение полю в операторе 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 "{"

Этот же формат работает, если значениеслучайным образом выбирается строка, но поскольку они являются переменными, внутренние фигурные скобки не могут быть заключены в кавычки.

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Используйте конструктор ARRAY вместо (недопустимого) литерала массива.

(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.См .:

0 голосов
/ 26 сентября 2019

Возможно, вы можете попробовать разбить индекс и массив на их собственные переменные?

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...