2013-11-29 5 views
0

Ну, я пытаюсь создать простую процедуру, которая проверяет, имеет ли пользователь такой логин, а если нет - добавляет новую строку в таблицу users. Но застрял с неожиданной проблемой.PostgreSQL sql-state: 42601 on SELECT INTO

CREATE OR REPLACE FUNCTION register_user(character varying, character varying, character varying,character varying,character varying) 
    RETURNS bigint AS 
$BODY$ 
DECLARE 
    new_user_login ALIAS FOR $1; 
    new_user_password ALIAS FOR $2; 
    new_user_email ALIAS FOR $3; 
    new_user_first_name ALIAS FOR $4; 
    new_user_last_name ALIAS FOR $5; 
    login_exist bigint; 
    new_user_id bigint; 
    emails_array character varying array; --yep, it's array of emails 
BEGIN  
    SELECT INTO login_exist count(login) FROM users WHERE users.login = new_user_login; 
    IF (login_exist = 0) THEN 
     SELECT array_append(emails_array, new_user_email); 
     INSERT INTO users (login,password,emails,first_name,last_name) 
     VALUES (new_user_login,new_user_password,emails_array,new_user_first_name,new_user_last_name) 
     RETURNING id INTO new_user_id; 
     RETURN new_user_id; 
    ELSE 
     RETURN 0; 
    END IF; 
END 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

Он возвращает sql-состояние: 42601 на SELECT INTO. Но если только число равно 0. Когда логин существует, он правильно возвращает 0; В чем проблема? Я даже не знаю, что это. thx для справки;

+0

Если это не будет 'ВЫБРАТЬ INTO ...' для plpgsql построить? Вы уверены, что это работает? –

+0

Вам необходимо * предоставить свою версию Postgres этим. –

ответ

1

Эта инструкция:

SELECT array_append(emails_array, new_user_email); 

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

Если вы хотите добавить в исходный массив, то это должно быть:

SELECT array_append(emails_array, new_user_email) INTO emails_array; 

Однако это не нужно. Вы можете упростить тело функции в:

BEGIN 

INSERT INTO users (login,password,emails,first_name,last_name) 
SELECT new_user_login,new_user_password,array[new_user_email],new_user_first_name,new_user_last_name 
WHERE NOT EXISTS (select 1 FROM users WHERE users.login = new_user_login) 
RETURNING id INTO new_user_id; 

RETURN coalesce(new_user_id,0); 

END; 
1

В дополнение к тому @Daniel already answered, не используют устаревшую ALIAS для именования параметров функций. Quoting the manual here:

Лучше всего использовать его только с целью переопределения заданных имен.

Использование argument names вместо:

CREATE OR REPLACE FUNCTION register_user(_login  text 
             , _password text 
             , _email  text 
             , _first_name text 
             , _last_name text) 
    RETURNS bigint AS 
$func$ 
DECLARE 
    _id bigint; 
BEGIN 
    INSERT INTO users (login, password, emails, first_name, last_name) 
    SELECT _login, _password, ARRAY[_email], _first_name, _last_name 
    WHERE NOT EXISTS (SELECT 1 FROM users WHERE login = _login) 
    RETURNING id INTO _id; 

    RETURN COALESCE(_id, 0); 
END 
$func$ LANGUAGE plpgsql; 
Смежные вопросы