如何在SQL中处理错误?

如何在SQL中处理错误?,sql,postgresql,Sql,Postgresql,让我们做一个简单的例子。假设我想检查用户是否已登录,查看他是否有权查看对话,然后获取对话的消息。在SQL中,有没有任何方法可以通过一个查询实现这一点?下面是一些伪代码 @uid = select userid from sessions where session=@session if @uid == empty Error NotLoggedIn @IsUser = select 1 from conversation_users where conversation_id=@convo_i

让我们做一个简单的例子。假设我想检查用户是否已登录,查看他是否有权查看对话,然后获取对话的消息。在SQL中,有没有任何方法可以通过一个查询实现这一点?下面是一些伪代码

@uid = select userid from sessions where session=@session
if @uid == empty Error NotLoggedIn
@IsUser = select 1 from conversation_users where conversation_id=@convo_id AND userid=@uid
if @IsUser == false Error NotAllowed
-- Actual query here
select body, time, user from conversation where conversation_id=@convo_id

您不能在纯SQL中抛出错误/异常,它不允许这样做。(除了明显的情况外,例如从0除以0,即
选择0/0
。您可以(ab)使用
CASE
表达式使其有条件,即
选择CASE如果为false,则0/0 end
将永远不会抛出错误。)

对于您想要的内容,通常的SQL等价物是运行单独的查询&在(SQL-)客户端构建逻辑。此外,当错误原因无关紧要时,您可以使用较少的查询,即:

select c.body, c.time, c.user
from   conversation c
join   conversation_users using (conversation_id)
join   sessions using (userid)
where  session         = :session
and    conversation_id = :convo_id
如果出现错误,这将不会返回一行。还可以一次返回所有数据,以确定(SQL-)客户端的错误原因:

with logged_in as (
  select userid, :convo_id conversation_id
  from   sessions
  where  session = :session
),
user_allowed as (
  select count(1) > 0 is_allowed
  from   logged_in
  join   conversation_users using (userid, conversation_id)
)
select    l.userid is not null is_logged_in,
          a.is_allowed,
          c.body,
          c.time,
          c.user
from      user_allowed a
left join logged_in l on true
left join conversation using (conversation_id)

如果您确实需要PostgreSQL抛出自定义错误,则需要使用。

如果您想在逻辑之后选择body、time、user,则需要一个函数。如果只需要执行逻辑,
DO
单个语句就可以了