2016-08-19 2 views
1

Я хочу написать функцию, которая добавит запись вставки, а затем вставьте одну или несколько записей в соответствующую таблицу. Я думаю, что знаю, что делать внутри функции, но я не знаю, как должна выглядеть подпись функции.PostgreSQL: Создание функции, которая принимает несколько значений

Вот макет образец:

CREATE TABLE sales(id SERIAL, customer id, sold date); 
CREATE TABLE saleitems(SERIAL, sale int, details varchar, price numeric(6,2)); 

SELECT addSale(42, '2016-01-01', 
    values ('stuff',13),('more stuff',42),('things',3.14),('etc',0)) items(price,details)); 

CREATE OR REPLACE FUNCTION addSale(customer,sold,items) RETURNS int AS 
$$ 
-- I think I can handle the rest 
$$ 
LANGUAGE sql; 

Решающие пункты:

  1. Я хотел бы иметь возможность использовать VALUES (…) name(…) конструкции в качестве аргумента - это возможно?
  2. Настоящая проблема, я думаю, является последним параметром items. Каков соответствующий тип этого?
  3. Я хотел бы, чтобы язык был SQL, так как мой следующий шаг - перевести это на другие диалекты (MySQL & SQL Server). Однако я сделаю все, что нужно.

В конце концов я завершу тело кода внутри транзакции и верну новое значение sales.id.

Вопрос: какой правильный параметр принимать табличное выражение в форме VALUES?

ответ

0

Лучше здесь, чтобы создать новый тип, который содержит детали и цену продукта:

CREATE TYPE product_details AS (
    details varchar, 
    price numeric(6,2) 
); 

Тогда можно определить параметр функции типа product_details[], то есть массив деталей продукта. Так как вы хотите иметь функцию SQL и нужно получить значение последовательного столбца одной вставки для использования в других вставках, необходимо КТР:

CREATE FUNCTION addSale(_customer int, _sold int, _items product_details[]) RETURNS int AS 
$$ 
    WITH s AS (
    INSERT INTO sales (customer, sold) VALUES (_customer, _sold) RETURNING id; 
) 
    INSERT INTO saleitems (sale, details, price) 
    SELECT s.id, i.d, i.p 
    FROM s, unnest(_items) i(d, p); 
$$ LANGUAGE sql; 

И тогда вы вызываете функцию следующим образом:

SELECT addSale(42, '2016-01-01'::date, 
       ARRAY[('stuff',13),('more stuff',42),('things',3.14),('etc',0)]); 
Смежные вопросы