2009-04-30 18 views
5

In base a this, SQL Server 2K5 utilizza UCS-2 internamente. Può memorizzare dati UTF-16 in UCS-2 (con tipi di dati appropriati, nchar, ecc.), Tuttavia se è presente un carattere supplementare questo è memorizzato come 2 caratteri UCS-2.Memorizzazione di dati UTF-16/Unicode in SQL Server

Questo porta gli ovvi problemi con le funzioni di stringa, vale a dire che quello che è un carattere viene trattato come 2 da SQL Server.

Mi sorprende un po 'che SQL Server sia fondamentalmente in grado di gestire solo UCS-2 e ancor più che questo non sia risolto in SQL 2K8. Apprezzo che alcuni di questi personaggi potrebbero non essere così comuni.

Oltre alle funzioni suggerite nell'articolo, qualsiasi suggerimento sull'approccio migliore per gestire le funzioni di stringa (interrotte) e i dati UTF-16 in SQL Server 2K5.

+0

Quali funzioni di stringa sono danneggiate per favore? – gbn

+3

LEN restituirà il numero di caratteri UCS-2 nella stringa, non il numero di caratteri UTF-16. SUBSTRING dividerà i caratteri UTF-16 a metà. Lo stesso vale per SINISTRA e DESTRA. Anche UPPER e LOWER probabilmente si rompono. REVERSE si romperebbe sicuramente. CHARINDEX e PATINDEX anche. Non sono sicuro su DIFFERENCE e STUFF. Quindi molti di loro .... –

+2

Grazie per aver segnalato questo. Il fatto che non supporti TUTTI i caratteri Unicode significa che alcuni valori di stringa UTF-16 (ad esempio da Windows o .NET) non sono validi per eseguire il dump in SQL Server senza verifica. Affinché qualsiasi applicazione sia priva di bug e tecnicamente corretta (il modo in cui i personaggi RARE che causano errori non fanno un po 'di differenza per quanto riguarda la correttezza), TUTTE le stringhe devono essere convalidate per contenere i caratteri compatibili con UCS-2 prima essere archiviati in SQL Server. Meraviglioso! Modo per rendere il mio lavoro molto più difficile Microsoft. – Triynko

risposta

2

Le funzioni di stringa funzionano correttamente con stringhe di caratteri unicode; quelli che si preoccupano del numero di caratteri trattano un carattere a due byte come un singolo carattere, non due caratteri. Gli unici a cui prestare attenzione sono len() e datalength(), che restituiscono valori diversi quando si utilizza unicode. Restituiscono naturalmente i valori corretti - len() restituisce la lunghezza in caratteri e dataend() restituisce la lunghezza in byte. Sono semplicemente diversi per via dei caratteri a due byte.

Quindi, se si utilizzano le funzioni appropriate nel codice, tutto dovrebbe funzionare in modo trasparente.

EDIT: Basta ricontrollato Books Online, i dati unicode ha lavorato perfettamente con le funzioni di stringa in quanto SQL Server 2000.

EDIT 2: Come sottolineato nei commenti, funzioni di stringa di SQL Server non supportano il set di caratteri Unicode completo a causa della mancanza di supporto per l'analisi di surrogati al di fuori del piano 0 (o, in altre parole, le funzioni di stringa di SQL Server riconoscono solo fino a 2 byte per carattere.) SQL Server memorizzerà e restituirà i dati correttamente, tuttavia qualsiasi la funzione stringa che si basa sui conteggi dei caratteri non restituirà i valori previsti. Il modo più comune per aggirare questo problema è quello di elaborare la stringa all'esterno di SQL Server oppure utilizzare l'integrazione CLR per aggiungere funzioni di elaborazione di stringhe a conoscenza di Unicode.

+5

Hai frainteso la domanda. UTF-16 consente caratteri supplementari. Questo funziona memorizzando un singolo carattere (dal punto di vista dell'utente) in 2 unità di codice, cioè 4 byte. UCS-2 non gestisce caratteri supplementari. Quindi i 4 byte vengono considerati come due caratteri da SQL Server quando in realtà sono un carattere. –

+0

Questo è solo per i caratteri al di fuori delle lingue definite standard. Il whitepaper afferma che questo è principalmente per le lingue storiche. – Rick

+0

Commento alla modifica: SQL Server funziona correttamente sui dati Unicode UCS-2. UCS-2 è uno standard obsoleto, Windows ha utilizzato UTF-16 internamente da Win2K. –

-2

qualcosa da aggiungere, che ho appena imparato nel modo più duro:

se si utilizza una "n" campo in Oracle (9i im in esecuzione), e l'accesso tramite l'OracleClient .net, sembra che solo con parametri sql funzionerà ... il prefisso unicode di N'string non sembra fare il trucco se hai qualche sql in linea.

e "lavoro", intendo: perderà qualsiasi carattere non supportato dal set di caratteri di base. Quindi, nei miei casi, i caratteri inglesi funzionano bene, i caratteri cirillici si trasformano in punti interrogativi/spazzatura.

questa è una discussione più ampia sul tema: http://forums.oracle.com/forums/thread.jspa?threadID=376847

Wonder se la variabile ORA_NCHAR_LITERAL_REPLACE può essere impostata nella stringa di connessione o qualcosa del genere.

+0

Hi boomhauer, la domanda riguardava Microsoft SQL Server. La tua risposta potrebbe essere utile da qualche altra parte. –

+0

wow ... qualcosa è successo qui. ho posto alla domanda sbagliata? Mi chiedo quasi se SO abbia rovinato tutto, dato che è in circolazione da febbraio 2010 ... –

+0

infatti, SO che questa risposta era già su un'altra domanda! –

5

SQL Server 2012 ora supporta UTF-16 incluse le coppie di surrogati. Vedi http://msdn.microsoft.com/en-us/library/ms143726(v=sql.110).aspx, in particolare la sezione "Caratteri supplementari".

Quindi una soluzione per il problema originale è l'adozione di SQL Server 2012.

+0

Se è vero che SQL Server 2012 ha introdotto le regole di confronto '_SC' che hanno una corretta gestione dei caratteri supplementari, la domanda è _molto_ specifica relativa a SQL Server 2005. Inoltre, non è" UTF-16 + coppie surrogate "da UTF-16 = "UCS-2 + coppie surrogate". –