两条sql语句有啥区别?

Posted

技术标签:

【中文标题】两条sql语句有啥区别?【英文标题】:What is the difference between the two sql statements?两条sql语句有什么区别? 【发布时间】:2009-05-20 18:32:56 【问题描述】:

美好的一天

我们要做的只是在触发器内确保用户没有插入两个名称中包含“单独”的费用。这些费用需要单独处理。

由于某种原因,sql 的顶部似乎在两周前停止工作。为了解决它,我以第二种方式重新编码并获得正确的结果。我感到困惑的是,为什么第一部分 似乎 在过去几年中一直有效,而现在却没有?

SELECT  @AloneRecordCount = count(*) 

FROM  inserted i 
      INNER JOIN deleted d on i.id = d.id 

WHERE  i.StatusID = 32 
      AND d.StatusID <> 32 
      AND i.id IN  
      (SELECT settlementid FROM vwFundingDisbursement fd
      WHERE fd.DisbTypeName LIKE  '%Alone'
      AND fd.PaymentMethodID = 0)


SELECT  @AloneRecordCount = count(i.id) 

FROM    inserted i INNER JOIN
        deleted d on i.id = d.id
        JOIN vwFundingDisbursement fd on i.id = fd.settlementid

WHERE   i.StatusID = 32 
        AND d.StatusID <> 32  
        AND fd.DisbTypeName like '%Alone'
        AND fd.PaymentMethodID = 0

这是在 SQL Server 2005 上 没有错误,顶部语句只会返回 1 或零 而底部语句将返回找到的实际数字。

【问题讨论】:

什么引擎,请问有什么错误吗? 这是一个 ON DELETE 触发器吗? 它在更新后触发。 为了节省其他人的阅读时间:在 UPDATE 触发器中,“已删除”表包含更新前的行,而“插入”表包含新值的行。 【参考方案1】:

您的 vwFundingDisbursement.settlementid 值是否为空?最近出现过吗?

【讨论】:

不,那是我看过的东西之一。感谢您的宝贵时间。 +1 好点,如果子选择中的 any 行为 NULL,则“i.id IN (...)”永远不会为真。如果一个结算ID 为NULL,即使在处理过程中是暂时的,这也有失败的风险。 不,IN 是连续的 OR 并处理 NULL。 "NOT IN" 为 NULL 失败。看到这个***.com/questions/129077/… 谢谢,我以为这两个都是【参考方案2】:

架构(或至少视图的创建方式)会有所帮助,但这里只是猜测...

如果您在 vwFundingDisbursement 中查找分配类型名称中值为“Alone”的多行,则当您的源表 (INSERTED) 连接到视图中的多行时,JOIN 将返回多行。如果你使用 IN,SQL 并不关心它是否返回多个匹配,它只会给你一行。

举个例子:

CREATE TABLE dbo.Test_In_vs_Join1
(
     my_id     INT     NOT NULL
)

CREATE TABLE dbo.Test_In_vs_Join2
(
     my_id     INT     NOT NULL
)

INSERT INTO dbo.Test_In_vs_Join1 (my_id) VALUES (1)
INSERT INTO dbo.Test_In_vs_Join1 (my_id) VALUES (2)
INSERT INTO dbo.Test_In_vs_Join1 (my_id) VALUES (3)
INSERT INTO dbo.Test_In_vs_Join1 (my_id) VALUES (4)
INSERT INTO dbo.Test_In_vs_Join1 (my_id) VALUES (5)

INSERT INTO dbo.Test_In_vs_Join2 (my_id) VALUES (1)
INSERT INTO dbo.Test_In_vs_Join2 (my_id) VALUES (1)
INSERT INTO dbo.Test_In_vs_Join2 (my_id) VALUES (2)
INSERT INTO dbo.Test_In_vs_Join2 (my_id) VALUES (3)
INSERT INTO dbo.Test_In_vs_Join2 (my_id) VALUES (3)

SELECT
     T1.my_id,
     COUNT(*)
FROM
     dbo.Test_In_vs_Join1 T1
INNER JOIN dbo.Test_In_vs_Join2 T2 ON
     T2.my_id = T1.my_id
GROUP BY
    T1.my_id

SELECT
     T1.my_id,
     COUNT(*)
FROM
     dbo.Test_In_vs_Join1 T1
WHERE
    T1.my_id IN (SELECT T2.my_id FROM dbo.Test_In_vs_Join2 T2)
GROUP BY
    T1.my_id

顺便说一句,像这样将一列隐藏在另一列中是违反规范化形式的,只是提出问题。正如您所发现的那样,在触发器中执行这种业务逻辑也是一条危险的道路。

【讨论】:

我不确定您所说的隐藏列是什么意思,但我当然同意并理解不将业务逻辑放入数据库的想法。而且我根本不喜欢触发器,但这不是我的决定。 这可能是正确的解决方案; IN 子句不会在 vwFundingDisbursement 中找到多行,但 JOIN 会。掩埋列可能是 DisbTypeName 末尾的 Alone。它应该是它自己的列。 我的意思是隐藏一列是您似乎有一个字符列 DisbTypeName 并且在该列中您存储了一个标志,表明该费用是否可以与其他相同费用一起插入类型。 实际上,如果您不希望出现数据完整性问题,这正是属于数据库的那种逻辑。这样做是应用程序将是一个糟糕的选择,因为它不会涵盖在应用程序之外进行的任何更新。然而,即使在数据库中,这个触发器也不是我会处理的,因为 LIKE '%Alone' 不能使用索引。我将单独的状态放在它自己的列中,然后放置一个覆盖该列和 id 字段的唯一索引。 这种校验既属于数据库(保持数据干净),也属于应用程序(提供好的校验UI),冗余校验不一定是坏事。尽管在某些情况下,您可以主张多个级别的严格性,而 DB 只强制执行最低的通用级别。【参考方案3】:

计数(*) 计数(i.id)

将根据 NULL 值返回不同的计数

In SQL, what’s the difference between count(*) and count('x')?

【讨论】:

但标识列不可能为 NULL @Andomar,是的,在你指出之前,你才注意到这一点。【参考方案4】:

我假设这个 MSSQL(?) 并且它正在处理一个 UPDATE 语句,因为您要加入两个插入/删除的表?

这个触发器在哪个表上?

【讨论】:

以上是关于两条sql语句有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

存储过程和sql语句有啥区别

SQL 'select' 和 PL/SQL 'select' 语句有啥区别?

sql语句中嵌套时候用in 和=有啥区别

mysql sql语句两条合并成一条

在 SQL/MySQL 中,join 语句中的“ON”和“WHERE”有啥区别?

SQL数据库中查询语句Order By和Group By有啥区别