2009-04-30 22 views
5

De acuerdo con this, SQL Server 2K5 usa UCS-2 internamente. Puede almacenar datos UTF-16 en UCS-2 (con tipos de datos apropiados, nchar, etc.); sin embargo, si hay un carácter suplementario, se almacena como 2 caracteres UCS-2.Almacenamiento de datos UTF-16/Unicode en SQL Server

Esto trae los problemas obvios con las funciones de cadena, concretamente que lo que es un carácter es tratado como 2 por SQL Server.

Estoy algo sorprendido de que SQL Server básicamente solo pueda manejar UCS-2, y más aún para que esto no se corrija en SQL 2K8. Aprecio que algunos de estos personajes no sean tan comunes.

Además de las funciones sugeridas en el artículo, cualquier sugerencia sobre el mejor enfoque para tratar con las funciones de cadena (rotas) y datos UTF-16 en SQL Server 2K5.

+0

¿Qué funciones de cadena están rotas por favor? – gbn

+3

LEN devolverá el número de caracteres UCS-2 en la cadena, no el número de caracteres UTF-16. SUBSTRING dividirá los caracteres UTF-16 por la mitad. Lo mismo aplica para IZQUIERDA y DERECHA. SUPERIOR e INFERIOR probablemente también se rompa. REVERSE definitivamente se rompería. CHARINDEX y PATINDEX también. No estoy seguro acerca de DIFERENCIA y MATERIA. Así que muchos de ellos ... –

+2

Gracias por señalar esto. El hecho de que no sea compatible con TODOS los caracteres Unicode significa que algunos valores de cadena UTF-16 (por ejemplo, desde Windows o .NET) no son válidos para volcar en SQL Server sin verificación. Para que cualquier aplicación sea libre de errores y técnicamente correcta (la forma en que los caracteres RARE causantes de errores no hacen una pequeña diferencia en lo que respecta a la corrección), TODAS las cadenas deben validarse para que contengan caracteres compatibles con UCS-2. siendo almacenado en SQL Server. ¡Maravilloso! Forma de hacer mi trabajo mucho más difícil Microsoft. – Triynko

Respuesta

2

Las funciones de cadena funcionan bien con cadenas de caracteres Unicode; los que se preocupan por el número de caracteres tratan a un personaje de dos bytes como un solo carácter, no como dos caracteres. Los únicos a los que hay que prestarle atención son len() y datalength(), que devuelven diferentes valores al usar unicode. Devuelven los valores correctos, por supuesto, len() devuelve la longitud en caracteres, y datalength() devuelve la longitud en bytes. Simplemente resultan ser diferentes debido a los caracteres de dos bytes.

Por lo tanto, siempre que use las funciones adecuadas en su código, todo debería funcionar de forma transparente.

EDITAR: Sólo una doble comprobación Books Online, los datos Unicode ha trabajado abierto con menú con funciones de cadena desde SQL Server 2000.

EDIT 2: Como se ha señalado en los comentarios, funciones de cadena de SQL Server no son compatibles el conjunto de caracteres Unicode completo debido a la falta de soporte para analizar sustitutos fuera del plano 0 (o, en otras palabras, las funciones de cadena de SQL Server solo reconocen hasta 2 bytes por carácter.) SQL Server almacenará y devolverá los datos correctamente, sin embargo cualquier la función de cadena que depende del recuento de caracteres no devolverá los valores esperados. La forma más común de omitir esto parece ser procesar la cadena fuera de SQL Server o bien utilizar la integración de CLR para agregar funciones de procesamiento de cadenas con reconocimiento Unicode.

+5

Ha malentendido la pregunta. UTF-16 permite caracteres suplementarios. Esto funciona almacenando un único carácter (desde la perspectiva del usuario) en 2 unidades de código, es decir, 4 bytes. UCS-2 no maneja caracteres suplementarios. Por lo tanto, los 4 bytes se tratan como dos caracteres por SQL Server cuando, de hecho, son un solo carácter. –

+0

Eso es solo para caracteres fuera de los lenguajes definidos estándar. El libro blanco establece que esto es principalmente para lenguajes históricos. – Rick

+0

Opina sobre la edición: SQL Server funciona bien en UCS-2 datos Unicode. UCS-2 es un estándar en desuso, Windows ha usado UTF-16 internamente desde Win2K. –

-2

algo que añadir, que acabo de aprender de la manera difícil:

si se utiliza una "n" de campo en el oráculo (im corriendo 9i), y acceder a ella a través de la OracleClient .net, parece que sólo parametrizado sql funcionará ... el prefijo unicode N'string 'no parece funcionar si tienes algunos sql en línea.

y por "trabajo", quiero decir: perderá cualquier carácter que no sea compatible con el juego de caracteres base. Entonces, en mi caso, los caracteres en inglés funcionan bien, el cirílico se convierte en signos de interrogación/basura.

esta es una discusión más completa sobre el tema: http://forums.oracle.com/forums/thread.jspa?threadID=376847

Wonder si la variable ORA_NCHAR_LITERAL_REPLACE se puede ajustar en la cadena de conexión o algo así.

+0

Hola, boomhauer, la pregunta era sobre Microsoft SQL Server. Su respuesta puede ser útil en otro lugar. –

+0

wow ... algo sucedió aquí. ¿Me posteé a la pregunta incorrecta? Casi me pregunto si SO jodió esto, ya que ha estado presente desde febrero de 2010 ... –

+0

de hecho, ¡SÉ que esta respuesta solía ser sobre otra pregunta! –

5

SQL Server 2012 ahora es compatible con UTF-16, incluidos pares de sustitución. Consulte http://msdn.microsoft.com/en-us/library/ms143726(v=sql.110).aspx, especialmente la sección "Caracteres suplementarios".

Así que una solución para el problema original es adoptar SQL Server 2012.

+0

Si bien es cierto que SQL Server 2012 introdujo las intercalaciones '_SC' que tienen un manejo adecuado de Caracteres Suplementarios, la Cuestión es _muy_específica sobre pertenecer a SQL Server 2005. Además, no es" UTF-16 + pares suplentes "desde UTF-16 = "UCS-2 + pares de sustitución". –

Cuestiones relacionadas