Esiste un modo più semplice per risolvere i disallineamenti delle regole di confronto di SQL Server / database rispetto alla modifica di ogni colonna?


8

NOTA BENE: So che questa domanda è stata posta un centinaio di volte prima, ma volevo solo verificare che non ci fosse una soluzione più semplice che avrei potuto perdere prima di andare avanti e scrivere / ottenere un sacco di codice per farlo.

Il nostro software utilizza un database originariamente progettato per SQL Server 7 e, come tale, tutti gli script che lo creano non specificano regole di confronto esplicite per nessuna colonna di caratteri. Invece, quando un database viene creato / ripristinato su SQL Server 2000 o versione successiva, ogni colonna eredita le regole di confronto del database (che risulta essere il SQL_Latin1_General_CP1_CI_ASdato che era l'impostazione predefinita di SQL Server 7).

Teoricamente, questo non importerebbe troppo, dal momento che se il nostro database viene creato da zero sul server di un cliente, eredita le regole di confronto del server del cliente (che è normalmente il predefinito di installazione moderno Latin1_General_CP1_CI_AS) e tutto funziona. Tuttavia, questo scenario si interrompe quando ci inviano un backup del database o quando inviamo loro un backup del database e riceviamo l'errore di mancata corrispondenza della collazione temuta ogni volta che il codice tenta di accedere alle tabelle temporanee ecc.

Abbiamo cercato di istruire i clienti a installare o ricostruire le loro istanze di SQL Server per utilizzare le regole di confronto preferite, ma ovviamente ciò non sempre accade e non è sempre possibile.

Le soluzioni che implicano la creazione di un nuovo database e la copia dei dati non sono davvero pratiche per noi, abbiamo bisogno di una "bacchetta magica" che possiamo sventolare in un database live per correggere tutte le colonne sul posto senza disturbare i dati. Sto pensando di scrivere un'utility per fare questo, ma dal momento che sarà un lavoro abbastanza grande, qualcuno ha qualche suggerimento più semplice?

Risposte:


6

Un'opzione è quella di "provare" il tuo codice contro la mancata corrispondenza delle regole di confronto.

È possibile utilizzare le regole di confronto speciali "DATABASE_DEFAULT" per forzare senza sapere qual è la regole di confronto effettive. Lo si utilizza su colonne di tipo char in tabelle temporanee, variabili di tabella e tabelle di sistema che è necessario utilizzare.

Esempio:

CREATE TABLE #Currency (CCY CHAR(3))
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --error!
GO
-- in join too
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY COLLATE DATABASE_DEFAULT --no error
GO
DROP TABLE #Currency
GO


CREATE TABLE  #Currency (CCY CHAR(3) COLLATE DATABASE_DEFAULT)
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --no error!
GO

DROP TABLE #Currency
GO

Questo significa anche che quando i tuoi client migrano il loro DB in una nuova casella di SQL Server con un'altra fascicolazione diversa, funziona anche ...


2

La risposta breve è che non esiste un modo semplice. Ho avuto lo stesso problema in passato.

Quello che vorrei dire è 2 cose, in primo luogo quando il tuo cliente ti invia un database con regole di confronto inattese, installa una nuova istanza SQL con regole di confronto predefinite che corrisponde al suo DB e ci lavora dentro.

Il secondo è assicurarsi che l'app funzionerà con altre regole di confronto quindi le impostazioni predefinite (poiché potrebbero cambiare in futuro) e funzionerà correttamente fintanto che le regole di confronto sul server SQL e sul DB corrispondono. Quindi è abbastanza facile far installare al cliente un server SQL con regole di confronto che corrispondano al proprio DB e funzionerà.

Oppure scrivi un'utilità che aggiornerà tutte le tabelle, ecc. Nel tuo database come hai detto, ma potrebbe essere più lavoro di quanto desideri.


2

Se tutte le colonne nel database sono dello stesso confronto, ciò causerà problemi solo quando si effettuano query tra database (o l'applicazione è sensibile all'ordinamento).

Il punto critico viene quando ti rendi conto che l'unione alle tabelle temporanee è cross-database, come lo sono in tempdb. Questo è facile da ordinare però - basta assicurarsi che qualsiasi colonna di testo nelle tabelle temporanee sia creata esplicitamente con la COLLATE database_defaultdirettiva. Ciò significa che la colonna verrà creata con le regole di confronto predefinite del database corrente anziché la raccolta predefinita di tempdb (che sarà la stessa predefinita del server).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.