CREATE OR REPLACE FUNCTION hire( id_pracownika integer,imie character varying,nazwisko character varying,miasto character varying,pensja real) RETURNS TEXT AS $BODY$ DECLARE wynik TEXT; sprawdzenie INT; BEGIN sprawdzenie = id_pracownika; IF EXISTS (SELECT id_pracownika FROM pracownicy WHERE id_pracownika=sprawdzenie) THEN wynik = "JUZ ISTNIEJE"; RETURN wynik; ELSE INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja) VALUES (id_pracownika,pensja); wynik = "OK"; RETURN wynik; END IF; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;
问题是我收到的错误是id_pracownika是一个列名和一个变量.
如何在这种上下文中指定“id_pracownika”是指列名?
解决方法
CREATE OR REPLACE FUNCTION hire( id_pracownika integer,imie varchar,nazwisko varchar,miasto varchar,pensja real) RETURNS TEXT AS $func$ BEGIN IF EXISTS (SELECT 1 FROM pracownicy p WHERE p.id_pracownika = hire.sprawdzenie) THEN RETURN 'JUZ ISTNIEJE'::text; -- wynik ELSE INSERT INTO pracownicy(id_pracownika,pensja) VALUES (hire.sprawdzenie,hire.imie,hire.nazwisko,hire.miasto,hire.pensja); RETURN 'OK'::text; -- wynik END IF; END $func$ LANGUAGE plpgsql;
>与@pozs一样,使用函数名对模式限定列名和前缀函数参数以在必要时消除歧义.
但请注意,INSERT的目标列表中的列名可能不会加前缀.无论如何,这些都不会模棱两可.
>就像@Frank所评论的那样,最好避免这种含糊不清,这样就不容易出错.
如果您还需要列名作为函数参数名称,则避免命名冲突的一种方法是在函数内部使用ALIAS
.这是ALIAS实际上有用的极少数情况之一.
或者您可以在ordinal position中引用输入参数:在这种情况下,id_pracownika为$1.
但还有更多:
>字符串文字(文本常量)必须用单引号括起来:’确定’,而不是“确定”.
> plpgsql中的赋值运算符是:=.
> The forgotten assignment operator “=” and the commonplace “:=”
>在EXISTS表达式中,选择的内容无关紧要. SELECT id_pracownika与SELECT 1或SELECT 123/0相同.只有行的存在才重要.
> What is easier to read in EXISTS subqueries?
>分配变量比其他编程语言相对昂贵.如果有一种优雅的方法来保存这些操作,那么这是plpgsql的首选方式.尽可能在sql语句中直接执行.
> VOLATILE COST 100是函数的默认装饰器.你不必拼出那些.
选择或插入
你的函数是“SELECT或INSERT”的另一个实现 – 一个UPSERT问题的变体,面对并发写入负载比你想象的更复杂. (您的简单解决方案忽略的潜在问题,顺便说一句,并且可能使其失败!)详细信息:
> Is SELECT or INSERT in a function prone to race conditions?
POSTERT in Postgres 9.5
Postgres团队(最突出的是Peter Geoghegan)在Postgres 9.5中实施了UPSERT. Details in the Postgres Wiki.这个新语法将做一个干净的工作:
INSERT INTO pracownicy(id_pracownika,hire.pensja); ON CONFLICT DO nothing RETURNING 'OK'::text; -- wynik IF NOT FOUND THEN RETURN 'JUZ ISTNIEJE'::text; END IF;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。