Discussione:
Chiarimenti funzionamento collate
(troppo vecchio per rispondere)
AlessandroD
2004-09-02 06:42:07 UTC
Permalink
Ho un SQL Server 2000 SP3 ENG su Win 2000 Server ENG con un DB, e sia SQL
che il DB utilizzano come collate di default SQL_Latin1_General_CP1_CI_AS.
Su un portatile WinXP Home ITA ho installato MSDE 2000 RelA e ho provveduto
a restorare il DB usando un suo backup.
Ho notato che il collate per MSDE sul portatile è Latin1_General_CI_AS,
mentra il collate per il DB è stato mantenuto a
SQL_Latin1_General_CP1_CI_AS.
In una query eseguo una cosa di questo tipo:

select CAMPO_TXT
from TAB
union
select
'==='
union
select CAMPO_TXT
from TAB2
order by CAMPO_TXT

La query sul portatile così come è scritta genera l'errore sul conflitto
delle regole di confronto per l'operatore union.
Quindi la prima cosa che ho fatto per risolvere il problema è stato di
castare il collate della costante stringa a SQL_Latin1_General_CI_AS in
questo modo:

select CAMPO_TXT
from TAB
union
select
'===' collate SQL_Latin1_General_CI_AS
union
select CAMPO_TXT
from TAB2
order by CAMPO_TXT

Ed effettivamente ha funzionato.
Però non capisco il motivo del cast, la costante stringa non dovrebbe
ereditare il collate del DB, che coincide con quello dei campi testo nelle
tabelle referenziate dalla query? Sembra invece che utilizzi il collate del
server, almeno credo vista la natura dell'errore.
Purtroppo, siccome il portatile dove essere pronto per l'altra
settimana...., è stato consegnato appena ho fatto presente di avere risolto
la cosa, quindi non ho modo di fare delle prove di contorno per chiarirmi la
questione.
Cosa ne pensate?
Ciao, Alessandro
AlessandroD
2004-09-02 10:06:34 UTC
Permalink
Post by AlessandroD
Ho un SQL Server 2000 SP3 ENG su Win 2000 Server ENG con un DB, e sia SQL
che il DB utilizzano come collate di default SQL_Latin1_General_CP1_CI_AS.
Su un portatile WinXP Home ITA ho installato MSDE 2000 RelA e ho provveduto
a restorare il DB usando un suo backup.
Ho notato che il collate per MSDE sul portatile è Latin1_General_CI_AS,
mentra il collate per il DB è stato mantenuto a
SQL_Latin1_General_CP1_CI_AS.
select CAMPO_TXT
from TAB
union
select
'==='
union
select CAMPO_TXT
from TAB2
order by CAMPO_TXT
La query sul portatile così come è scritta genera l'errore sul conflitto
delle regole di confronto per l'operatore union.
Quindi la prima cosa che ho fatto per risolvere il problema è stato di
castare il collate della costante stringa a SQL_Latin1_General_CI_AS in
select CAMPO_TXT
from TAB
union
select
'===' collate SQL_Latin1_General_CI_AS
union
select CAMPO_TXT
from TAB2
order by CAMPO_TXT
Ed effettivamente ha funzionato.
Però non capisco il motivo del cast, la costante stringa non dovrebbe
ereditare il collate del DB, che coincide con quello dei campi testo nelle
tabelle referenziate dalla query? Sembra invece che utilizzi il collate del
server, almeno credo vista la natura dell'errore.
Purtroppo, siccome il portatile dove essere pronto per l'altra
settimana...., è stato consegnato appena ho fatto presente di avere risolto
la cosa, quindi non ho modo di fare delle prove di contorno per chiarirmi la
questione.
Cosa ne pensate?
Trovato, vi ho fuorviato, visto che naturalmente nel mio post non avevo
indicato un dettaglio che in realtà era la chiave per chiarire la
questione...
La prima select della union fa riferimento ad una variabile di tipo table
nella cui definizione non ho indicato nessun collate per il campo testo.
Dall'errore che ho ricevuto deduco che le variabili di tipo table siano
trattate come le tabelle temporanee # e ## circa il reperimento del collate
da abbinare ai campi testo quando questo non è specificato esplicitamente. E
per le tabelle temporanee il db di riferimento è il tempdb che per me, sul
portatile, ha come collate Latin1_General_CI_AS, diverso quindi dal DB dove
risiede la query incriminata.
Facendola breve, il cast esplicito diventa inutile se nella definizione
della variabile table specifico un collate adatto per il campo testo, e io
ho scelto database_default in modo che venga utilizzato il collate del DB
dove risiede la query.
In questo modo è sparito il conflitto nelle regole di confronto tra la
variabile table ed il resto della query: infatti tutti i campi si trovano ad
usare lo stesso collate.
Ciao, Alessandro

Continua a leggere su narkive:
Loading...