2009-06-11 3 views
22

Сегодня, находясь внутри производственной системы клиента, я нашел запрос SQL Server, который содержал незнакомый синтаксис. В приведенном ниже примере, что делает оператор *=? Я не мог найти упоминания об этом on MSDN. Запрос выполняет и возвращает данные. Насколько кто знает, это было в системе, так как они использовали SQL Server 2000, но они в настоящее время работает 2005SQL Server * = Оператор?

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 

ответ

24

Немедленно удалить этот код и заменить его левым соединением. Этот код не всегда правильно интерпретируется (иногда SQL Server решает, что это перекрестное соединение) даже в SQL Server 2000 и, следовательно, может дать неверные результаты! Также он устарел для будущего.

Я собираюсь добавить, что при настройке на левые соединения вы также должны удалить все другие неявные соединения. Синтаксис неявного соединения был устаревшим с 1992 года, нет оправдания тому, что он все еще находится в производственном коде. И смешивание неявных и явных соединений может дать неожиданные результаты.

+3

'Этот код не всегда правильно интерпретируется (иногда SQL Server решает, что это перекрестное соединение) даже в SQL Server 2000 и, следовательно, может дать неверные результаты! Также он устарел для будущего. «Я знаю, что это очень старый, но мне было интересно, есть ли у вас документация, поддерживающая это утверждение? Благодаря! – swasheck

+2

* Синтаксис SQL-92 рекомендуется, потому что он не подлежит двусмысленности, которая иногда возникает из внешних соединений Transact-SQL. * Из [SQL 2000 BOL: Использование внешних соединений] (http://msdn.microsoft.com /en-us/library/aa213228(v=sql.80).aspx). Более новые версии этой темы даже не упоминают объединения '* =' и '= *'. –

+1

Также (спасибо @MikaelEriksson): * Использование этого синтаксиса для внешних объединений обескураживается из-за возможности неоднозначной интерпретации и потому, что это нестандартно. Вместо этого укажите соединения в предложении FROM. * Из [SQL 2000 BOL: SELECT] (http://msdn.microsoft.com/en-us/library/aa259187 (v ​​= sql.80) .aspx). –

0

Это синтаксис старше ANSI (ANSI-89) левое внешнее соединение оператора. Я бы рекомендовал не использовать его - синтаксис ANSI является более подробным и более читаемым.

+1

Это не стандартное и лишенное таким образом ANSI;) –

+0

это ansi-89, а не новинка ansi-92 –

1

Я считаю, что это «внешние ANSI-соединения без ANSI». Уровень совместимости вашей базы данных должен быть 80 или ниже.

+1

Есть ansi, просто ansi-89, а не ansi-92. Они также ЗЛО. –

10

Это левое внешнее соединение, = * - правое внешнее соединение.

E.g. следующие равны;

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

    SELECT * FROM Table1, Table2 WHERE Table1.ID *= Table2.FK_ID 
+0

Собственно, они не всегда равны. В простом запросе, подобном этому, возможно, в более сложном запросе есть хорошая таблица, в которой база данных будет интерпретировать ее как перекрестное соединение вместо левого соединения. Даже SQL Server 2000 BOL говорит об этой проблеме. Нет никаких обстоятельств, когда целесообразно использовать неявный синтаксис левого соединения на SQL-сервере, если вы не используете такую ​​раннюю версию, которая не раскрывает синтаксис. – HLGEM

6

Синтаксис не-ANSI для внешних соединений (*= и =*) находится на официальном list of deprecated features that will be removed in the next version of SQL.

Следующие SQL Server Database Engine функции не будут поддерживаться в следующей версии SQL Server. Do не использовать эти функции в новых разработках и изменять приложения, которые в настоящее время используют эти функции как можно скорее.

Функция замены - ANSI compliant syntax of JOIN.

+0

@ spencer7593 Я думаю, вы ошибаетесь. '* =' и '= *' был проприетарным синтаксисом, никогда ни в одном стандарте ANSI/ISO. –

Смежные вопросы