Проблема PostgreSQL с именованными аргументами в функции - PullRequest
1 голос
/ 30 ноября 2009

PostgreSQL 8.4 в Linux. У меня есть функция:

CREATE OR REPLACE FUNCTION production.add_customer (  
name varchar(100),  
email_address varchar(300),  
street_address text,  
city varchar(50),  
state varchar(2),  
zip varchar(10),  
secret1 bytea,  
secret2 bytea,   
secret3 bytea,  
secret4 bytea,  
referrer text)  
RETURNS integer as $$  
BEGIN  
INSERT INTO customers (name, email_address, street_address, city, state, zip, secret1, secret2, secret3, secret4, create_date, referrer) VALUES  
(name, email_address, street_address, city, state, zip, create_date, referrer
pgp_sym_encrypt(secret1, 'reallylongrandomstring'),   
pgp_sym_encrypt(secret2, 'reallylongrandomstring'),   
pgp_sym_encrypt(secret3, 'reallylongrandomstring'),   
pgp_sym_encrypt(secret4, 'reallylongrandomstring'),   
current_timestamp, referrer);  
RETURNING customer_id;  
END;  
$$ LANGUAGE plpgsql;   

Это возвращает эту ошибку, когда я пытаюсь создать его:

ERROR:  syntax error at or near "$1"
LINE 1: INSERT INTO customers ( $1 ,  $2 ,  $3 ,  $4 ,  $5 ,  $6 ,  ...
                            ^
QUERY:  INSERT INTO customers ( $1 ,  $2 ,  $3 ,  $4 ,  $5 ,  $6 ,  $7 ,  $8 ,  $9 ,  $10 , create_date,  $11 ) VALUES ( $1 ,  $2 ,  $3 ,  $4 ,  $5 ,  $6 , create_date,  $11  pgp_sym_encrypt( $7 , 'reallylongrandomstring'), pgp_sym_encrypt( $8 , 'reallylongrandomstring'), pgp_sym_encrypt( $9 , 'reallylongrandomstring'), pgp_sym_encrypt( $10 , 'reallylongrandomstring'), current_timestamp,  $11 )
CONTEXT:  SQL statement in PL/PgSQL function "add_customer" near line 8
myserver=#

Я пытался ALIAS FOR, не повезло. Идеи?

Ответы [ 3 ]

3 голосов
/ 30 ноября 2009

Ваши аргументы имеют то же имя, что и столбцы в INSERT; PL / pgSQL неправильно подставляет оба набора идентификаторов (столбцы и значения) аргументом, заканчивая бессмысленным INSERT, который вы видите в ошибке.

См. Официальное слово в разделе Осторожно на этой странице , но по сути вам придется изменить имена аргументов.

1 голос
/ 30 ноября 2009

Это поведение будет изменено в PostgreSQL 9.0.

a) PostgreSQL 9.0 умнее и применяет переменные только в нужных местах

b) приоритет является необязательным - например, PostgreSQL, как Oracle или исключение повышения

Для более старой версии используйте префикс для всех локальных переменных и параметров в каждой функции со встроенным SQL.

0 голосов
/ 30 ноября 2009

name - зарезервированное ключевое слово в PostgreSQL.

Измените его на INSERT INTO customers ("name", etc etc...

Также то, что он сказал: добавьте все ваши имена переменных к _ или подобному.

...