我有一个 sql 语句(继承),它具有以下 WHERE 子句:
WHERE
(Users_1.SecurityLevel IN ('Accounts', 'General manager'))
AND (PurchaseOrders.Approval = 1)
AND (PurchaseOrders.QuotedAmount = 0)
AND (Users_1.StaffNumber = ISNULL(ServiceRequests.POC_UserID, PurchaseOrders.Approval_UserID))
OR
(Users_1.SecurityLevel IN ('Accounts', 'General manager'))
AND (PurchaseOrders.QuotedAmount = 0)
AND (ServiceRequests.POC = 1)
AND (Users_1.StaffNumber = ISNULL(ServiceRequests.POC_UserID, PurchaseOrders.Approval_UserID))
OR
(ISNULL(ISNULL(PurchaseOrders.InvoiceNumber, ServiceRequests.InvoiceNumber), '!#') <> '!#')
AND (Users_1.StaffNumber = ISNULL(ServiceRequests.POC_UserID, PurchaseOrders.Approval_UserID))
Run Code Online (Sandbox Code Playgroud)
当事情没有很好地括起来时,我试图弄清楚操作的顺序。
在上面的例子中,AND 和 OR 语句是如何排序的?
是否有一个简单的规则,以便我可以将括号括起来以使其更具可读性?
对于 SQL WHERE 子句运算符,当涉及到运算的数学顺序时,我正在寻找类似“BODMAS”的东西。
谢谢
运算符优先级页面告诉您:
当一个复杂表达式有多个运算符时,运算符优先级决定了执行运算的顺序。执行顺序会显着影响结果值。
这AND比 具有更高的优先级OR。
然而,这是不正确的。在 SQL 中,你告诉系统你想要什么,而不是如何去做,并且优化器可以自由地重新排序操作,前提是产生相同的逻辑结果。
因此,虽然运算符优先级告诉您运算符是如何在逻辑上组合的,但它实际上并不控制每个逻辑段实际执行的顺序。这意味着由于执行顺序的保证而在其他语言中可能是安全的习语在 SQL 中实际上并不安全。例如支票,例如:
<String can be parsed as an int> && <convert the string to an int and compare to 20>
Run Code Online (Sandbox Code Playgroud)
在 C# 等语言中可以完全安全。SQL 中的相同逻辑是不安全的,因为优化器可能会在评估字符串是否可以解析为 int 之前选择执行字符串到 int 的转换,因此可能会抛出有关转换失败的错误。(当然,它也可以按您的预期工作而不产生错误)