PostgreSQL INSERT INTO SELECT CASE 问题
PotgresSQL INSERT INTO SELECT CASE problem
我有以下查询,我想从子查询中插入任意数量的行。当然我得到一个错误 SQL Error [21000]: ERROR: more than one row returned by a sub query used as an expression
因为一些子查询 return 多行
insert into logs (_timestap, _message, _mode, _user_id)
select :_timestamp, :_message, :_mode,
case :_mode
-- select all users that have the given grade. NOTE that this sub query returns multiple rows
when 'byGrade' then (select u.id from users u where grade = :_grade)
-- The user id value is already passed
when 'byIndividual' then (select :_user_id limit 1)
-- This sub query also returns multiple rows (all infact) from the users table
when 'everyone' then (select id from users)
end
PostgreSQL 版本 10。
我该如何解决这个问题?
这需要程序代码,可以在数据库客户端使用您最喜欢的编程语言 (TM) 或 database server-side procedural language. Plain SQL is declarative language and does not have advanced conditionals。 SQL CASE
不足以完成这份工作。
在 Pl/PgSQL 中看起来像:
CREATE FUNCTION do_the_thing(
p_timestap timestamptz,
p_message text,
p_mode text,
p_user_id integer)
RETURNS VOID
LANGUAGE plpgsql AS $definition$
BEGIN
if p_mode = 'byGrade' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, u.id from users u where grade = p_grade;
elsif p_mode = 'byIndividual' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, p_user_id;
elsif p_mode = 'everyone' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, id from users;
end if;
END;
$definition$;
union all
可以帮忙:
insert into logs (_timestap, _message, _mode, _user_id)
select :_timestamp, :_message, :_mode, id
from users
where :_mode = 'byGrade' and grade = :_grade
union all
select :_timestamp, :_message, :_mode, :_user_id
where :_mode = 'byIndividual'
union all
select :_timestamp, :_message, :_mode, id
from users
where :_mode = 'everyone';
我有以下查询,我想从子查询中插入任意数量的行。当然我得到一个错误 SQL Error [21000]: ERROR: more than one row returned by a sub query used as an expression
因为一些子查询 return 多行
insert into logs (_timestap, _message, _mode, _user_id)
select :_timestamp, :_message, :_mode,
case :_mode
-- select all users that have the given grade. NOTE that this sub query returns multiple rows
when 'byGrade' then (select u.id from users u where grade = :_grade)
-- The user id value is already passed
when 'byIndividual' then (select :_user_id limit 1)
-- This sub query also returns multiple rows (all infact) from the users table
when 'everyone' then (select id from users)
end
PostgreSQL 版本 10。
我该如何解决这个问题?
这需要程序代码,可以在数据库客户端使用您最喜欢的编程语言 (TM) 或 database server-side procedural language. Plain SQL is declarative language and does not have advanced conditionals。 SQL CASE
不足以完成这份工作。
在 Pl/PgSQL 中看起来像:
CREATE FUNCTION do_the_thing(
p_timestap timestamptz,
p_message text,
p_mode text,
p_user_id integer)
RETURNS VOID
LANGUAGE plpgsql AS $definition$
BEGIN
if p_mode = 'byGrade' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, u.id from users u where grade = p_grade;
elsif p_mode = 'byIndividual' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, p_user_id;
elsif p_mode = 'everyone' then
insert into logs (_timestap, _message, _mode, _user_id)
select p_timestamp, p_message, p_mode, id from users;
end if;
END;
$definition$;
union all
可以帮忙:
insert into logs (_timestap, _message, _mode, _user_id)
select :_timestamp, :_message, :_mode, id
from users
where :_mode = 'byGrade' and grade = :_grade
union all
select :_timestamp, :_message, :_mode, :_user_id
where :_mode = 'byIndividual'
union all
select :_timestamp, :_message, :_mode, id
from users
where :_mode = 'everyone';