如何知道查询失败的原因

时间:2016-08-10 09:13:25

标签: database api

让我们假设一个多租户应用程序包含以下表格:

person (tenant_id, id, status, name, company_id)
company (tenant_id, id, name)

更新人员条目时,以下约束适用:

  • company_id必须存在且tenant_id必须匹配
  • status必须有效

我目前正在使用一个考虑所有约束的查询:

UPDATE person 
SET person.company_id = 100
WHERE person.tenant_id = 'A'
 AND person.id = 1
 AND person.status = 10
 AND EXISTS (SELECT TRUE FROM company WHERE company.tenant_id='A' and company.id=100)

查询的输出表示已更新的行数。

在没有更新行的情况下,我想知道根本原因。是因为:

  • id(在我的情况下,这是我的主键)不存在。
  • id已存在,但status不正确。
  • company_id不存在。

这将允许我返回相应的错误消息。

你认为最好是:

事先进行单独查询

  1. 选择除主键之外没有任何约束的条目。
  2. SELECT id, status, name FROM person WHERE tenant_id = 'A' AND id = 1
    

    如果未找到任何条目,我可以立即返回404。

    如果找到条目,我可以检查status是否有效。如果它无效,我可以返回错误消息。

    1. 确保company对象存在
    2. SELECT id, name FROM company WHERE tenant_id = 'A' AND id = 100
      

      如果它不存在,我可以返回错误信息。

      如果是,我可以尝试进行更新。

      1. 更新
      2. 运行包含所有约束的初始查询,因为自步骤1以来数据可能已更改。

        优点:没有?

        缺点:多个数据库调用,进程较慢,数据可以在此过程中更改。

        首先运行整个查询,然后尝试找到原因

        在这里,我尝试保持乐观并立即运行初始查询,因为大多数时候数据都是有效的。

        我进行了额外的查询(与上面相同),只有在数据无效时才知道根本原因。

        在我运行初始查询和上次查询的时间之间,数据可能仍会发生变化。

        优点:数据有效时更快

        缺点:如果发生错误,可以进行多次数据库调用,在此过程中可以更改数据。

        使用存储过程

        这样可以解决“数据更改”问题,但我想避免使用存储过程。

        优点:进行一次数据库调用

        缺点:数据库工作负载

        非常具体,我正在使用运行此应用程序。

2 个答案:

答案 0 :(得分:0)

尝试使用

UPDATE person 
    SET person.company_id = 100
    WHERE person.tenant_id = 'A'
     AND person.id = 1
     AND person.status = 10
     AND EXISTS (SELECT id FROM company WHERE company.tenant_id='A' and company.id=100)

答案 1 :(得分:0)

性能的角度来看,最有可能的是“先运行整个查询并尝试查找之后的原因”是您的最佳选择,其中“之后”表示“仅在案例中”当事实证明没有更新行“。

这是基于这样的“失败”将相对罕见的假设,并且该假设本身基于以下假设:用于识别要更新的行的选择标准将相对最近建立。 (如果是5天前的一批数据,情况可能略有不同。)

(我可能还想从功能的角度来看,尝试将错误消息提升到你想要的精度水平是相对不常见的,原因是它总是变得比你想象的更“复杂”而且比你想象的要复杂得多。)

相关问题