2013-12-12 19 views
24

Sto lavorando su una vista, in cui sto usando un inner join su due tabelle che provengono da due server differenti. Stiamo usando un server collegato. Quando si esegue la query sto ottenendo questo messaggio:Come sbarazzarsi del conflitto di regole di confronto in una query di SQL Server?

non può risolvere il conflitto di confronto tra "SQL_Latin1_General_CP1_CI_AS" e "Arabic_CI_AS" nel uguale al funzionamento.

Non so molto di collazione. Cercando attraverso internet trovo le soluzioni per usare COLLATE, ma il concetto di COLLATE non mi è chiaro. Cambierà qualcosa per uno qualsiasi dei database? Sto cercando una soluzione senza modificare nulla per i database.

Qualsiasi buon materiale didattico per questi concetti è il benvenuto.

+0

puoi mostrare il codice SQL su cui stai lavorando? –

risposta

37

È possibile risolvere il problema forzando le regole di confronto utilizzate in una query a essere una particolare fascicolazione, ad es. SQL_Latin1_General_CP1_CI_AS o DATABASE_DEFAULT. Ad esempio:

SELECT MyColumn 
FROM FirstTable a 
INNER JOIN SecondTable b 
ON a.MyID COLLATE SQL_Latin1_General_CP1_CI_AS = 
b.YourID COLLATE SQL_Latin1_General_CP1_CI_AS 

Nella query sopra, a.MyID e b.YourID sarebbe colonne con un tipo di dati di testo. L'utilizzo di COLLATE impone alla query di ignorare le regole di confronto predefinite nel database e utilizzare invece le regole di confronto fornite, in questo caso SQL_Latin1_General_CP1_CI_AS.

Fondamentalmente quello che sta succedendo qui è che ogni database ha la sua collazione che "fornisce regole di ordinamento, caso, e le proprietà di sensibilità accento per i dati" (da http://technet.microsoft.com/en-us/library/ms143726.aspx) e si applica alle colonne con tipi di dati testuali, per esempio VARCHAR, CHAR, , ecc. Quando due database presentano regole di confronto diverse, non è possibile confrontare le colonne di testo con un operatore come uguale a (=) senza affrontare il conflitto tra le due regole di confronto disparate.

+0

Grazie Roryap. Sto aggiornando il mio codice con COLLATE. Ti farò sapere se ho qualche problema. Quindi significa che nulla verrà modificato a livello di database e questo COLLATE verrà eseguito solo all'interno dello script SQL. – elmo

+0

Grazie, ha funzionato. Il mio problema è stato risolto. – elmo

+0

abbastanza interessante, fino ad ora pensavo di dover cambiare le regole di confronto a livello di database per far corrispondere le em, non sapevo di poterle confrontare nella mia query usando 'COLLATE'! grazie a questo mi hai salvato un sacco di problemi. – Niklas

3

ho risolto un problema simile avvolgendo la query in un'altra interrogazione ...

query iniziale stava lavorando trovare dando singole colonne di output, con alcune delle colonne provenienti dalle query sub con Max o la funzione Somma, e altro con sostituzioni "distinte" o maiuscole e simili.

ho incontrato l'errore di confronto dopo il tentativo di creare un unico campo della produzione con ...

select 
rtrim(field1)+','+rtrim(field2)+','+... 

La query eseguirebbe come ho scritto, ma si sarebbe verificato l'errore dopo aver salvato lo sql e ricaricarlo .

Wound up fissandolo con qualcosa di simile ...

select z.field1+','+z.field2+','+... as OUTPUT_REC 
from (select rtrim(field1), rtrim(field2), ...) z 

Alcuni campi sono "max" di una sottoquery, con un caso di sostituzione, se nullo e altri sono i campi data, e alcuni sono lasciati unisce (potrebbe essere NULL) ... in altre parole, tipi di campi misti. Credo che questa sia la causa del problema causato dalle regole di confronto del sistema operativo e dal confronto del database che sono leggermente diverse, ma convertendo tutto in stringhe tagliate prima della selezione finale, lo ordina, tutto in SQL.