检测 PostgreSQL SQL 函数(不是 PL/pgSQL)中的 UPDATE 失败
为了模仿 MySQL-REPLACE 语句(又名 UPSERT),我需要尝试更新记录,如果失败 - 插入它。但是我如何检测 SQL 过程中的 UPDATE 失败呢?
begin transaction;
create table pref_users (
id varchar(32) primary key,
first_name varchar(32),
last_name varchar(32),
female boolean,
avatar varchar(128),
city varchar(32),
lat real check (-90 <= lat and lat <= 90),
lng real check (-90 <= lng and lng <= 90),
last_login timestamp default current_timestamp,
last_ip inet,
medals smallint check (medals > 0)
);
create table pref_rate (
obj varchar(32) references pref_users(id),
subj varchar(32) references pref_users(id),
good boolean,
fair boolean,
nice boolean,
about varchar(256),
last_rated timestamp default current_timestamp
);
create table pref_money (
id varchar(32) references pref_users,
yw char(7) default to_char(current_timestamp, 'YYYY-WW'),
money real
);
create index pref_money_yw_index on pref_money(yw);
create or replace function update_pref_users(id varchar,
first_name varchar, last_name varchar, female boolean,
avatar varchar, city varchar, last_ip inet) returns void as $$
update pref_users set
first_name = $2,
last_name = $3,
female = $4,
avatar = $5,
city = $6,
last_ip = $7
where id = $1;
-- XXX how to detect failure here? XXX
insert into pref_users(id, first_name, last_name,
female, avatar, city, last_ip)
values ($1, $2, $3, $4, $5, $6, $7);
$$ language sql;
commit;
我的 update_pref_users SQL 函数中是否需要第二对 BEGIN/COMMIT ?
To mimic the MySQL-REPLACE statement (aka UPSERT) I need to try to UPDATE a record and if that fails - INSERT it. But how can I detect that the UPDATE has failed in my SQL procedure?
begin transaction;
create table pref_users (
id varchar(32) primary key,
first_name varchar(32),
last_name varchar(32),
female boolean,
avatar varchar(128),
city varchar(32),
lat real check (-90 <= lat and lat <= 90),
lng real check (-90 <= lng and lng <= 90),
last_login timestamp default current_timestamp,
last_ip inet,
medals smallint check (medals > 0)
);
create table pref_rate (
obj varchar(32) references pref_users(id),
subj varchar(32) references pref_users(id),
good boolean,
fair boolean,
nice boolean,
about varchar(256),
last_rated timestamp default current_timestamp
);
create table pref_money (
id varchar(32) references pref_users,
yw char(7) default to_char(current_timestamp, 'YYYY-WW'),
money real
);
create index pref_money_yw_index on pref_money(yw);
create or replace function update_pref_users(id varchar,
first_name varchar, last_name varchar, female boolean,
avatar varchar, city varchar, last_ip inet) returns void as $
update pref_users set
first_name = $2,
last_name = $3,
female = $4,
avatar = $5,
city = $6,
last_ip = $7
where id = $1;
-- XXX how to detect failure here? XXX
insert into pref_users(id, first_name, last_name,
female, avatar, city, last_ip)
values ($1, $2, $3, $4, $5, $6, $7);
$ language sql;
commit;
And do I need a 2nd pair of BEGIN/COMMIT inside of my update_pref_users SQL-function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你不能使用 SQL 作为一种语言,你需要 pl/pgsql,因为 SQL 中缺乏 if-else 结构。
在 pl/pgsql 中,您可以使用特殊变量 FOUND 查看查询是否找到了某些内容。
不需要额外的 SELECT 语句。
You can't use SQL as a language, you need pl/pgsql because of the lack of if-else constructions in SQL.
Within pl/pgsql you can use the special variable FOUND to see if a query has found something.
There is no need for extra SELECT statements.