【问题标题】:Have SQL query fail if subquery returns null如果子查询返回 null,则 SQL 查询失败
【发布时间】:2016-02-19 01:50:50
【问题描述】:

如果下面的子查询没有找到记录,它会返回 null 并将 action_batch_id 设置为这样。如果子查询没有返回记录,是否有可能让整个查询失败/退出?

UPDATE action_batch_items 
SET action_batch_id = (SELECT id FROM action_batches WHERE id = '123' 
AND batch_count < 1000  AND batch_size < 100000) 
WHERE id = 1234567

更新:这是结构(它是 ActiveRecord)

CREATE TABLE "public"."action_batches" (
    "id" int8 NOT NULL,
    "action_batch_container_id" int8 NOT NULL,
    "action_message" json,
    "adaptor" json,
    "batch_count" int4 DEFAULT 0,
    "batch_size" int8 DEFAULT 0
)

CREATE TABLE "public"."action_batch_items" (
    "id" int8 NOT NULL,
    "action_batch_id" int8,
    "config" json
)

【问题讨论】:

  • 这可能会有所帮助:stackoverflow.com/a/8766815/1073631 -- 假设您有一个join 的字段... action_batch_items 是否有一个action_batches_id
  • 因为我没有误会你的意思,但是这个查询对我来说真的很奇怪。您将 action_batch_id 更新为子查询的结果,但在您的子查询中,让我们检查一下。您选择 ID,其中 id = '123'。所以不是所有的结果都应该是 123 或 null?正如你问的那样,你期望 123 或根本没有变化?
  • @sgeddes 它是 ActiveRecord 执行原始 SQL,但是 action_batch_item 有一个 action_batch_id
  • 您的内部子查询令人困惑。如果您有WHERE id = '123',这是否意味着分配给action_batch_idid 将始终为123

标签: sql postgresql subquery


【解决方案1】:
create or replace function raise_error(text) returns int as $$
begin
  raise exception '%', $1;
  return -1;
end; $$ language plpgsql;

然后

action_batch_id = coalesce((select id ...), raise_error('No data'));

【讨论】:

  • COALESCE() 函数可以接受多个记录/值作为输入吗?
  • @TimBiegeleisen 当然不是。但是update .. set = (select ...) 也不接受多行结果。
  • 您的解决方案不是意味着action_batch_items 表中的每条 记录都可能引发错误吗?
  • @TimBiegeleisen 不。只针对第一次失败。
  • @FábioZangirolami IMO 之类的 raise(text)raiseif(condition, text) 应该包含在 SQL 标准中 :) 祝你好运!
【解决方案2】:

尝试使用COALESCE()

UPDATE action_batch_items 
SET action_batch_id = 
(
    SELECT COALESCE(id, action_batch_id)
    FROM action_batches
    WHERE id = '123' AND batch_count < 1000  AND batch_size < 100000
) 
WHERE id = 1234567

如果子查询返回NULLaction_batch_id 列将不会更改。在子查询返回一个或多个非NULL 记录的情况下,您的UPDATE 将像以前一样运行。

【讨论】:

  • 老兄,但是action_batch_id在表action_batch_items中,他没有提到action_batches也有action_batch_id,如果有的话。它可能与项目表中的 batch_id 不同
  • 好点。我将等待他对此发表评论。外部查询的列应该在子查询中可见。
  • action_batch_id 将被更改为空子查询结果(0 行)。 coalesce 应该包装子查询,反之亦然。
  • action_batch_id 设置为相同的值有什么坏处吗?
  • @TimBiegeleisen 添加了结构
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多