删除SQL删除语句而不是错误输出

时间:2017-02-16 22:20:47

标签: sql-server tsql

有人可以解释这个查询是如何执行的吗? credit_transaction_key中不存在financial_transaction列,但financial_transaction_jnl中确实存在。{1}}。我没有得到的是,如果列在一个表而不是另一个表中,该查询甚至会执行。这不应该出错吗?

delete from financial_transaction_jnl
where credit_transaction_key in 
      (select credit_transaction_key
       from financial_transaction
       where account_key in 
             (select account_key
              from account
              where created_by = (select USER_KEY
                                  from USERS 
                                  where USER_ID = 'ME')
                and created_dttm > Cast('2/16/2017' as datetime)
             )
      )

financial_transaction:    financial_transaction_key account_key

financial_transaction_jnl:    financial_transaction_jnl_key financial_transaction_key credit_transaction_key

2 个答案:

答案 0 :(得分:1)

您需要使用表别名。

SQL必须假设您的列来自哪里。

在这种情况下,所有内容都会被删除:

financial_transaction.redit_transaction_key in
(SELECT credit_transaction_key from  financial_transaction

但您可能正在尝试这样做:

financial_transaction_jnl.redit_transaction_key in
    (SELECT credit_transaction_key from  financial_transaction

答案 1 :(得分:1)

  

credit_transaction_key中不存在financial_transaction列,但financial_transaction_jnl中确实存在。{1}}。 [...]难道不应该出错吗?

没有。如果确实financial_transaction不包含名为credit_transaction_key的列,那么在子查询中,将针对当前外部行集的列列表(即financial_transaction_jnl的列)解析标识符行。由于选择的值与要与选择进行比较的值相同,因此您提供的查询与此稍微简单的查询具有相同的效果:

delete from financial_transaction_jnl
where exists (
  SELECT 1
  from financial_transaction
  where account_key in (
    select account_key
    from account
    where created_by = (SELECT USER_KEY  FROM USERS WHERE USER_ID = 'ME')
      AND created_dttm > Cast('2/16/2017' AS DATETIME)
  )
)

因为外部查询的WHERE子句因此看起来不依赖于其目标表中的值,所以将删除所有行或none。这似乎不太可能是预期的效果。

如另一个答案所示,限定外部查询中的列名称不会改变这个含义。将内部查询中的列名称限定为financial_transaction.credit_transaction_key确实会导致查询出错。