2012-03-08 4 views
0

Как использовать массив для вставки в таблицу в функции?PLPGSQL Array in Functions

CREATE TABLE places 
(
id  SERIAL PRIMARY KEY 
,location VARCHAR(100) NOT NULL 
,timestamp TIMESTAMP 
,person_id INTEGER NOT NULL REFERENCES people ON UPDATE... 
); 

CREATE TABLE people 
(
id  SERIAL PRIMARY KEY 
,name VARCHAR(100) NOT NULL 
); 

Я пытаюсь сделать функцию, где я хотел бы сделать:

SELECT function(location_name, now(), '{1,2,3}'); 

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

SELECT function(location_name, now(), '{3,5,7,8,10}'); 

Я не знаю, с чего начать в принятии ВСТАВИТЬ динамичны и извлечение идентификаторов из массива , Unest может использоваться для переменных INSERT INTO в DECLARE, но динамический аспект не может быть выполнен. Надеюсь, я сделал это ясно.

ответ

2

Написание функции plpgsql - это всегда возможность (и я делаю это много). Но в этом случае может быть решена проще:

INSERT INTO places (location, ts, person_id) 
SELECT 'some_location', now(), unnest('{1,2,3}'::int4[]) 

Я заменил свое имя столбца timestamp с ts, потому что я не думаю, что это хорошая идея, чтобы использовать имя типа в качестве идентификатора. Это приводит к запутывающим побочным эффектам и сообщениям об ошибках.


Если вам нужно JOIN к результирующему набору из unnest() функции - как ваш вопрос, кажется, подразумевает (но проблема оказалась проще) - вы должны сделать это суб-запрос:

INSERT INTO places (location, ts, name) 
SELECT 'some_location', now(), p.name 
FROM (SELECT unnest('{1,2,3}'::int4[]) AS id) AS x 
JOIN people p USING (id); 

Я добавил столбец name, который не в вашей модели, просто продемонстрировать.

+0

Спасибо за ваш ответ, могу ли я сделать, для i в массиве LOOP вместо этого? Есть ли побочные эффекты для LOOP? – Neeran

+0

Внутри функции plpgsql или 'DO', да. Не знаю, какие побочные эффекты могут быть. Вас может заинтересовать новый цикл ['FOREACH'] (http://www.postgresql.org/docs/current/interactive/plpgsql-control-structures.html#PLPGSQL-FOREACHARARAR) –