【问题标题】:SQL Server *= Operator?SQL Server *= 运算符?
【发布时间】:2010-11-02 07:15:04
【问题描述】:

今天在客户的生产系统中,我发现了一个 SQL Server 查询,其中包含不熟悉的语法。在下面的示例中,*= 运算符的作用是什么?我找不到任何提及它on MSDN。查询确实执行并返回数据。据任何人所知,自从他们使用 SQL Server 2000 以来,这一直在系统中,但他们现在正在运行 2005。

declare @nProduct int
declare @iPricingType int
declare @nMCC int

set @nProduct = 4
set @iPricingType = 2
set @nMCC = 230

--Build SQL for factor matrix

Select distinct
base.uiBase_Price_ID,
base.nNoteRate, 
base.sDeliveryOpt, 
IsNull(base.nPrice,0) as nPrice, 
IsNull(base.nPrice,0) + Isnull(fact.nFactor,0) as nAdjPrice, 
base.iProduct_ID,
fact.iPosition as fiPosition, 
base.iPosition, 
CONVERT(varchar(20), base.dtDate_Updated, 101) + ' ' + CONVERT(varchar(20), base.dtDate_Updated, 108) as 'dtDate_Updated', 
fact.nFactor, 
fact.nTreasFactor, 
product.sProduct_txt ,  
pfi.sPFI_Name,  
mccprod.nServicing_Fee,  
fact.nNoteRate as fNoteRate,  
mcc.nLRA_Charge as nLRA  
From 
tbl_Base_Prices base, tbl_Factors fact, tbl_Product product, tbl_PFI pfi, tbl_MCC mcc, tbl_MCC_Product mccprod 
Where
base.iProduct_ID = @nProduct  
And base.iProduct_ID *= fact.iProduct_ID 
And base.iPosition *= fact.iPosition 
And base.nNoteRate *= fact.nNoteRate 
And base.iPricing_Type = @iPricingType
And fact.iMCC_ID =  @nMCC
And fact.iProduct_ID = @nProduct
And mcc.iMCC_ID =  @nMCC 
And mcc.iPFI_ID = pfi.iPFI_ID 
And mccprod.iMCC_ID =  @nMCC
And mccprod.iProduct_ID =  @nProduct
And base.iProduct_ID = product.iProduct_ID 
and fact.iPricing_Type= @iPricingType
Order By
base.nNoteRate, base.iPosition 

【问题讨论】:

    标签: sql sql-server operators


    【解决方案1】:

    立即删除此代码并替换为左连接。即使在 SQL Server 2000 中,此代码也不总是正确解释(有时 SQL Server 决定它是交叉连接),因此可能会给出不正确的结果!将来也不推荐使用它(Using Outer Joins, SQL Server 2000 documentation 存档自 the original)。

    我要补充一点,在调整左连接时,您还应该删除所有其他隐式连接。自 1992 年以来,隐式连接语法已过时,它没有任何借口仍在生产代码中。并且混合隐式和显式连接会产生意想不到的结果。


    【讨论】:

    • This code does not always interpret correctly (Sometimes SQL Server decides it is a cross join) even in SQL Server 2000 and thus can give incorrect results! Also it is deprecated for the future. 我知道这已经很老了,但我想知道您是否有支持此声明的文档?谢谢!
    • 建议使用 SQL-92 语法,因为它不受传统 Transact-SQL 外部连接有时会导致的歧义的影响。来自SQL 2000 BOL: Using Outer Joins。该主题的较新版本甚至没有提及 *==* 加入。
    • 另外(感谢@MikaelEriksson):不鼓励将这种语法用于外部连接,因为它可能会导致模棱两可的解释,而且它是非标准的。而是在 FROM 子句中指定连接。来自SQL 2000 BOL: SELECT
    • 这些参考资料都没有涉及到歧义的确切细节,但即使是微软也将它们记录为不可靠并且能够产生不正确/模棱两可的结果这一事实只会放大情绪你不应该使用它们。永远。
    • 你@AaronBertrand。 SQL Server BOL 也是我的参考。我还通过在这样的论坛上回答问题(尽管当时不存在 SO)知道它们在某些情况下会产生交叉连接,这就是我多年前碰巧在 BOL 中找到参考的方式。
    【解决方案2】:

    外部连接的非 ANSI 语法(*==*)在官方 list of deprecated features that will be removed in the next version of SQL 上。

    以下 SQL Server 数据库 不支持引擎功能 在下一版本的 SQL Server 中。做 不要在新功能中使用这些功能 开发工作,并修改 当前使用这些的应用程序 尽快推出功能。

    替换功能是ANSI compliant syntax of JOIN

    【讨论】:

    • @spencer7593 我认为你错了。 *==* 是专有语法,从未出现在任何 ANSI/ISO 标准中。
    【解决方案3】:

    这是旧的 ANSI (ANSI-89) 语法左外连接运算符。我建议不要使用它 - ANSI 语法更冗长且更具可读性。

    【讨论】:

    • 它是非标准的和贬低的,所以不是 ANSI ;)
    • 这些是 ansi-89,而不是较新的 ansi-92
    • * 从来不是 ANSI。
    【解决方案4】:

    是左外连接,=*是右外连接。

    例如以下是相等的;

      SELECT * FROM Table1 LEFT OUTER JOIN Table2 ON Table1.ID = Table2.FK_ID
    
      SELECT * FROM Table1, Table2 WHERE Table1.ID *= Table2.FK_ID
    

    【讨论】:

    • 实际上,它们并不总是相等的。在像这样的简单查询中,在更复杂的查询中,有一个很好的机会是数据库会将其解释为交叉连接而不是左连接。甚至 SQL Server 2000 BOL 也谈到了这个问题。在 SQL Server 中不适合使用隐式左连接语法,除非您使用的是不支持显式语法的早期版本。
    • CROSS JOIN。逗号,CROSS JOIN 完全一样。它只是返回类似于LEFT JOIN 的结果的运算符。
    • @DaveBoltman *= 不表示运算符 & 逗号不表示存在 * 时的交叉连接;整个 join-where 表示不是交叉连接的过滤器。
    • @philipxy 我已经纠正了。你教会了我一些东西——谢谢!!
    【解决方案5】:

    我相信这些是“非 ANSI 外连接运算符”。您的数据库兼容级别必须为 80 或更低。

    【讨论】:

    • 有ansi,只是ansi-89而不是ansi-92。他们也是邪恶的。
    【解决方案6】:

    这是一种简写连接语法。看看这个涵盖这个主题的线程。

    Transact-SQL shorthand join syntax?

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      相关资源
      最近更新 更多