проблема при выполнении pgsql, жалующегося на цикл

#arrays #postgresql #loops #plpgsql

#массивы #postgresql #циклы #plpgsql

Вопрос:

 create or replace function f() RETURNS void AS 

declare
   tableArray text[] := '{"ADDRESS","CONSISTENCY_CHECK","DEPARTMENT_SUPERVISION"}';
   tableName CHARACTER VARYING;
   value INTEGER ;
   
BEGIN
 FOREACH  tableName IN ARRAY tableArray 
 LOOP   
     select user_id from tableName where user_id=2631;
       if found then
         update tableName set user_id=2651 where user_id=2631;
         delete from tableName where user_id=2631;
  END loop;
end;
  

вот ошибка, которую я получаю при попытке выполнить pgplsql: ERROR syntax error at or near "loop"

Комментарии:

1. Тело функции должно быть строковым литералом, обычно использующим долларовые кавычки.

2. Я не вижу блока $ $ вокруг тела функции.

Ответ №1:

Есть еще проблемы:

  1. тело функции должно быть строковым — вы можете использовать апострофы или более обычные и практичные разделители пользовательских строк $$.

  2. результат SELECT не должен быть потерян. Предложение INTO отсутствует.

  3. имя таблицы не должно быть переменной — переменная не может использоваться в качестве имени таблицы. В этом случае вам нужна динамическая инструкция SQL — EXECUTE .

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

     CREATE OR REPLACE FUNCTION f() 
    RETURNS void AS $$
    DECLARE
      table_array text[] := '{"ADDRESS","CONSISTENCY_CHECK","DEPARTMENT_SUPERVISION"}';
      table_name text;
      value integer ;
      rc integer
    BEGIN
      FOREACH  table_name IN ARRAY table_array 
      LOOP
        EXECUTE format('SELECT * FROM %I WHERE user_id = $1', table_name) USING 2631;
        -- variable FOUND cannot be used for dynamic SQL
        GET DIAGNOSTICS rc = ROW_COUNT;
        IF rc > 0 THEN
          EXECUTE format('UPDATE %I SET user_id = $1 WHERE user_id = $2', table_name) USING 2651, 2631;
          EXECUTE format('DELETE %I WHERE user_id = $1', table_name) USING 2631;
         END IF;
       END LOOP;
     END;
     $$ LANGUAGE plpgsql;