2009-06-11 3 views
22

Oggi mentre all'interno del sistema di produzione di un cliente, ho trovato una query di SQL Server che conteneva una sintassi non familiare. Nell'esempio seguente, cosa fa l'operatore *=? Non ho potuto trovare alcuna menzione di esso on MSDN. La query esegue e restituisce i dati. Per quanto si sa, questo è stato nel sistema dal momento che stavano usando SQL Server 2000, ma sono ora in esecuzione 2005.SQL Server * = Operatore?

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 

risposta

24

Rimuovere immediatamente questo codice e sostituirlo con un giunto di sinistra. Questo codice non sempre interpreta correttamente (a volte SQL Server decide che è un cross join) anche in SQL Server 2000 e quindi può dare risultati errati! Inoltre è deprecato per il futuro.

Aggiungo che nella regolazione ai join di sinistra è necessario rimuovere anche tutti gli altri join impliciti. La sintassi di join implicita è stata obsoleta dal 1992, non ci sono scuse perché è ancora in codice di produzione. E mescolare join impliciti ed espliciti può dare risultati inaspettati.

+3

'Questo codice non sempre interpreta correttamente (a volte SQL Server decide che è un cross join) anche in SQL Server 2000 e quindi può dare risultati errati! Inoltre è deprecato per il futuro. So che questo è molto vecchio, ma mi stavo chiedendo se tu avessi una documentazione che supporti questa affermazione? Grazie! – swasheck

+2

* La sintassi SQL-92 è consigliata poiché non è soggetta all'ambiguità che a volte risulta dai legacy outer join di Transact-SQL. * Da [SQL BOL 2000: utilizzo di outer join] (http://msdn.microsoft.com /en-us/library/aa213228(v=sql.80).aspx). Le versioni più recenti di questo argomento non menzionano nemmeno join * * e '= *'. –

+1

Inoltre (grazie a @MikaelEriksson): * L'uso di questa sintassi per i join esterni è scoraggiato a causa del potenziale di interpretazione ambigua e perché non è standard. Invece, specificare i join nella clausola FROM. * Da [SQL 2000 BOL: SELECT] (http://msdn.microsoft.com/en-us/library/aa259187 (v ​​= sql.80) .aspx). –

0

Questa è la sintassi più vecchio ANSI (ANSI-89) ha lasciato outer join operatore. Mi raccomando di non usarlo - la sintassi ANSI è più prolissa ed è molto più leggibile.

+1

Non è standard e non è disponibile, quindi non ANSI;) –

+0

quelli sono ansi-89, non il più recente ansi-92 –

1

Credo che quelli siano "operatori di join esterni non ANSI". Il livello di compatibilità del database deve essere 80 o inferiore.

+1

Ci sono ansi, solo ansi-89 piuttosto che ansi-92. Sono anche MALE. –

10

È un join esterno sinistro, = * è un join esterno destro.

E.g. i seguenti sono uguali;

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

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

In realtà, non sono sempre uguali. In una semplice query come questa probabilmente, in una query più complessa, c'è una buona sequenza in cui il database la interpreterà come un cross join al posto di un join sinistro. Anche SQL Server 2000 BOL parla di questo problema. Non vi è alcuna circostanza in cui sia opportuno utilizzare la sintassi di join sinistro implicita nel server SQL a meno che non si stia utilizzando una versione anticipata che la sintassi esplicita non sia supportata. – HLGEM

6

Il non ANSI sintassi per outer join (*= e =*) è sul sito ufficiale list of deprecated features that will be removed in the next version of SQL.

il seguente SQL Server Database Engine funzioni non saranno supportate nella prossima versione di SQL Server. Non utilizzare queste funzionalità nel nuovo lavoro di sviluppo e modificare le applicazioni che attualmente utilizzano queste funzioni il prima possibile.

la funzione di sostituzione è il ANSI compliant syntax of JOIN.

+0

@ spencer7593 Penso che tu abbia torto. '* =' and '= *' era una sintassi proprietaria, mai in uno standard ANSI/ISO. –