Вставьте IF NOT EXIST, выберите IF EXIST - PullRequest
0 голосов
/ 03 июля 2019

Столкнулся с некоторым недоразумением о том, как работает функция Postgresql.Задача состоит в том, чтобы проверить, существует ли в моей базе данных id.Если это так - вернуть некоторые данные из существующей записи.Если нет - вставьте некоторые данные и верните все обратно.

CREATE OR REPLACE FUNCTION test(_id varchar, _data varchar[]) RETURNS varchar[] AS $$
BEGIN
    IF EXISTS (SELECT 1 FROM my_table WHERE id = _id) THEN
        SELECT * FROM my_table WHERE id = _id;
    ELSE
        INSERT INTO my_table (id, filename, size) VALUES (_data) RETURNING *;
    END IF;
END
$$ LANGUAGE plpgsql;

Выбор возвращает ошибку: ERROR: invalid input syntax for integer: "id123"

SELECT test('id123', ARRAY['id123', 'filename', 123456]);

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 03 июля 2019

Передача нескольких аргументов для различных столбцов таблицы в качестве элементов массива не очень хорошая идея. Вы можете лучше использовать составной тип в качестве аргумента. Это помогает вам даже передавать несколько строк данных в функции, как показано в этом примере

Если вы настаиваете на использовании элементов массива, вы не можете просто использовать их в VALUES(), на них нужно ссылаться, используя индекс

INSERT INTO my_table  (id, filename, size) 
                      VALUES (_data[1],_data[2],_data[3]::int );

Другая проблема связана с RETURNING *; Он не возвращается из функции. Он просто возвращает результат запроса. Если вы просто хотите использовать RETURNING, можно использовать a с предложением.

Предполагая, что определение вашей таблицы выглядит примерно так:

                    Table "public.my_table"
  Column  |       Type        | Collation | Nullable | Default
----------+-------------------+-----------+----------+---------
 id       | character varying |           |          |
 filename | text              |           |          |
 size     | integer           |           |          |

вы можете написать тип возврата вашей функции как TABLE

CREATE OR REPLACE FUNCTION test(_id varchar, _data varchar[]) 
 RETURNS TABLE (id varchar, filename text, size int)
AS $$
BEGIN
 IF NOT EXISTS ( SELECT 1 FROM my_table t WHERE t.id = _id) THEN
   RETURN QUERY
   with  ins AS 
    ( 
      INSERT INTO my_table  (id, filename, size) 
                      VALUES (_data[1],_data[2],_data[3]::int ) RETURNING *
     )                    ---refer elements             ^ properly cast them
    SELECT * FROM ins;   
    ELSE
     RETURN QUERY SELECT * FROM my_table t WHERE t.id = _id; 

    END IF;
END
$$ LANGUAGE plpgsql;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...