sql >> Base de Datos >  >> RDS >> Sqlserver

Intercalación en SQL Server

Introducción

Ya debe haber escuchado el término "Colección" en SQL Server. La intercalación es una configuración que determina cómo se realiza la clasificación de datos de caracteres. Esta es una configuración importante que tiene un gran impacto en cómo se comporta el motor de base de datos de SQL Server al tratar con datos de caracteres. En este artículo, nuestro objetivo es analizar las intercalaciones en general y mostrar algunos ejemplos de manejo de intercalaciones.

¿Dónde encuentro intercalaciones?

Puede encontrar la intercalación de SQL a nivel de servidor, base de datos y columna. Otra cosa importante que debe saber es que la configuración de intercalación no necesita ser la misma a nivel de servidor, base de datos y columna. Además, puede actualizar sus consultas para usar intercalaciones específicas. Es en este momento cuando se dará cuenta de la importancia de configurar la intercalación correcta en su entorno, ya que existe una gran posibilidad de problemas inesperados si la intercalación no es coherente.

¿Cuáles son los diferentes tipos de colaciones disponibles?

Puede obtener la lista completa de intercalaciones disponibles consultando la función del sistema sys.fn_helpcollations()

select * from sys.fn_helpcollations()

Esto devolverá el siguiente resultado.

Si está buscando intercalaciones específicas por idioma, puede filtrar más el nombre. Por ejemplo, si está buscando la intercalación compatible con el idioma maorí, puede usar la siguiente consulta.

select * from sys.fn_helpcollations()
    where name like '%Maori%'

Esto devolverá el siguiente resultado.

De esta manera, puede verificar las intercalaciones admitidas para la intercalación de su elección. Con solo consultar la función del sistema fn_helpcollations(), se devolvieron 5508 filas en total, lo que significa que hay tantas intercalaciones admitidas. Tenga en cuenta que esto cubre la mayoría de los idiomas del mundo.

¿Cuáles son las diferentes opciones que ves en el nombre de la intercalación?

Por ejemplo, en esta colación:Maori_100_CS_AI_KS_WS_SC_UTF8, puede ver las distintas opciones en el nombre de la colación.

CS – distingue entre mayúsculas y minúsculas
IA – insensible al acento
KS – Sensible al tipo de kana
WS – sensible al ancho
SC – caracteres complementarios
UTF8 – Estándar de codificación
Según el tipo de opción de intercalación seleccionada, el motor de la base de datos de SQL Server funcionará de manera diferente al tratar con datos de caracteres para las operaciones de clasificación y búsqueda. Por ejemplo, si utiliza la opción de distinción entre mayúsculas y minúsculas en la intercalación de SQL, el motor de la base de datos se comportará de manera diferente para una operación de consulta que busque "Adam" o "adam". Suponiendo que tiene una tabla llamada "muestra" y hay una columna de nombre con un usuario "adam". La consulta a continuación no arrojará resultados si no hay una fila con el nombre de pila "Adam". Esto se debe a la opción "CS-Sensible a mayúsculas y minúsculas" en la colación.

select * from sample
    where firstname like '%Adam%'

Con este sencillo ejemplo, puede comprender la importancia de elegir la opción de intercalación SQL correcta. Asegúrese de comprender los requisitos de la aplicación antes de seleccionar la intercalación en primer lugar.

Encontrar intercalación en la instancia de SQL Server

Puede obtener la intercalación del servidor en SQL Server Management Studio (SSMS) haciendo clic con el botón derecho en la instancia de SQL, luego haciendo clic en la opción "Propiedades" y marcando la pestaña "General". Esta intercalación se selecciona de forma predeterminada en la instalación de SQL Server.

Alternativamente, puede usar la opción de propiedad del servidor para encontrar el valor de intercalación.

select SERVERPROPERTY('collation'),

Encontrar colación de una base de datos SQL

En SSMS, haga clic derecho en la base de datos SQL y vaya a "Propiedades". Puede verificar los detalles de la intercalación en la pestaña "General" como se muestra a continuación.

Alternativamente, puede usar la función base de datos propiedad ex para obtener los detalles de una colación de base de datos.

select DATABASEPROPERTYEX('Your DB Name','collation')

Encontrar la intercalación de una columna en una tabla

En SSMS, vaya a la tabla, luego a las columnas y, finalmente, haga clic con el botón derecho en las columnas individuales para ver las "Propiedades". Si la columna es de un tipo de datos de caracteres, verá los detalles de la intercalación.

Sin embargo, al mismo tiempo, si comprueba el valor de un tipo de datos que no son caracteres, el valor de intercalación será nulo. A continuación se muestra una captura de pantalla de una columna que tiene un tipo de datos int.

Como alternativa, puede usar una consulta de muestra a continuación para ver los valores de intercalación de las columnas.

select sc.name, sc.collation_name from sys.columns sc
inner join sys.tables t on sc.object_id=t.object_id
where t.name='t1' – enter your table name

A continuación se muestra el resultado de la consulta.

Probar diferentes intercalaciones en consultas SQL

En esta sección, veremos cómo se ve afectado el orden de clasificación cuando se utilizan diferentes intercalaciones en las consultas. Se crea una tabla de muestra con 2 columnas como se muestra a continuación.

La columna fname tiene la intercalación predeterminada de la base de datos a la que pertenece. En este caso, la intercalación es SQL_Latin1_General_CP1_CI_AS.
Para insertar algunos registros en la tabla, utilice una consulta a continuación. Asigne sus propios valores a los parámetros.

insert into emp
  values (1,'mohammed')
  insert into emp 
  values (2,'moinudheen')
  insert into emp
  values (3,'Mohammed')
  insert into emp
  values (4,'Moinudheen')
  insert into emp
  values (5,'MOHAMMED')
  insert into emp
  values (6,'MOINUDHEEN')

Ahora, consulta la tabla emp y ordénala por la columna fname usando diferentes intercalaciones. Usaremos la intercalación predeterminada de la columna para clasificar, así como otra intercalación que distingue entre mayúsculas y minúsculas:SQL_Latin1_General_CP1_CS_AS.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS 
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – this is default

El resultado de estas consultas se muestra a continuación. Observe la diferencia en la intercalación utilizada. Usamos mayúsculas y minúsculas en lugar de mayúsculas y minúsculas.

También puede consultar los planes de consulta para ambas consultas para detectar la diferencia. En el primer plan de consulta donde usamos una intercalación diferente a la de la columna, puede notar el operador adicional "Calcular escalar".

Cuando pasa el mouse sobre el operador "Calcular escalar", verá los detalles adicionales como se muestra a continuación. Esto se debe a la conversión implícita que se lleva a cabo, ya que estamos usando una intercalación diferente de la predeterminada que se usa en la columna.

Con este pequeño ejemplo, puede ver el tipo de impacto en el rendimiento de las consultas cuando usa intercalaciones explícitamente en las consultas. En nuestra base de datos de demostración, usamos una tabla simple pero imaginamos un escenario en tiempo real donde pequeños cambios en el rendimiento de las consultas pueden causar resultados inesperados.

Comprobar si es posible cambiar la intercalación a nivel de instancia

En esta sección, revisaremos diferentes escenarios en los que es posible que tengamos que cambiar las intercalaciones predeterminadas. Puede encontrar situaciones en las que se le entreguen servidores o bases de datos y es posible que no cumplan con sus políticas estándar, por lo que es posible que deba cambiar la intercalación. La intercalación predeterminada de SQL Server es SQL_Latin1_General_CP1_CI_AS. Cambiar la intercalación en el nivel de instancia de SQL no es sencillo. Requiere crear secuencias de comandos para todos los objetos en las bases de datos de usuario, exportar los datos, descartar las bases de datos de usuario, reconstruir la base de datos maestra con la nueva intercalación, crear las bases de datos de usuario y luego importar todos los datos. Por lo tanto, si está instalando nuevas instancias de SQL, solo asegúrese de obtener la intercalación correcta la primera vez, de lo contrario, es posible que tenga que hacer mucho trabajo no deseado más adelante. Explicar en detalle las etapas para cambiar la intercalación a nivel de instancia está más allá del alcance de este artículo debido a los pasos detallados requeridos para cada una de las etapas.

Cambio de intercalación a nivel de base de datos

Afortunadamente, cambiar la intercalación del nivel de la base de datos no es tan difícil como cambiar la intercalación de instancias. Podemos actualizar la intercalación usando tanto SSMS como T-SQL. En SSMS, simplemente haga clic derecho en la base de datos, vaya a "Propiedades" y haga clic en la pestaña "Opciones" en el lado izquierdo. Allí, puede ver la opción para cambiar la intercalación en el menú desplegable.

Haga clic en "Aceptar" una vez hecho. Acabo de cambiar la intercalación de la base de datos a SQL_Latin1_General_CP1_CI_AS. Solo asegúrese de realizar esta operación cuando la base de datos no esté en uso, ya que de lo contrario la operación fallará como se muestra a continuación.

Use la consulta anterior para cambiar la intercalación de la base de datos usando T-SQL.

USE master;  
GO  
ALTER DATABASE mo  
COLLATE SQL_Latin1_General_CP1_CS_AS;  
GO

Notará que cambiar la intercalación del nivel de la base de datos no afectará la intercalación de las columnas existentes en las tablas. Puede utilizar los ejemplos anteriores para comprobar el impacto de la intercalación en el criterio de ordenación de las consultas siguientes.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS 
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – - this is default

La intercalación de la columna fname seguirá siendo la original y permanecerá sin cambios incluso después de cambiar la intercalación del nivel de la base de datos.

Sin embargo, la nueva intercalación de nivel de base de datos se aplicará a todas las columnas nuevas en las tablas nuevas que creará. Por lo tanto, siempre pruebe minuciosamente el cambio de las intercalaciones de la base de datos, ya que tiene un impacto considerable en el resultado o el comportamiento de las consultas.

Cambiar intercalación a nivel de columna

En la sección anterior, notó que incluso después de cambiar la intercalación del nivel de la base de datos, la intercalación de las columnas existentes en las tablas permanece sin cambios. En esta sección, veremos cómo podemos cambiar la intercalación de las columnas existentes en las tablas para que coincida con la intercalación de la base de datos. En la sección anterior, cambió la intercalación de la base de datos a SQL_Latin1_General_CP1_CS_AS. A continuación, desea identificar todas las columnas en las tablas de usuario que no coinciden con esta intercalación de base de datos. Puede usar este script para identificar esas columnas.

select so.name TableName,sc.name ColumnName, sc.collation_name CollationName from
sys.objects so inner join sys.columns sc on so.object_id=sc.object_id
where sc.collation_name!='SQL_Latin1_General_CP1_CS_AS' and so.[type] ='U'

El resultado de muestra de mi base de datos de demostración se muestra a continuación.

Supongamos que desea cambiar la intercalación de la columna fname existente a "SQL_Latin1_General_CP1_CS_AS", entonces puede usar este script alternativo a continuación.

use mo
go
ALTER TABLE dbo.emp ALTER COLUMN fname  
            nvarchar(20) COLLATE SQL_Latin1_General_CP1_CS_AS NULL;  
GO

Si usa los ejemplos anteriores en los que verificó el rendimiento de la consulta usando diferentes intercalaciones, notará que el operador "calcular escalar" no se usa cuando usamos la misma intercalación que la de la base de datos. Consulte la captura de pantalla a continuación. En el ejemplo anterior, podría haber notado que el operador "Calcular escalar" se usa en el primer plan de ejecución. Como cambiamos la intercalación de columnas para que coincida con la intercalación de la base de datos, no hay necesidad de conversión implícita. Verá el operador "Calcular escalar" en la segunda consulta, ya que utiliza una intercalación diferente explícitamente.

select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS – - this is default
select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS

¿Podemos cambiar la intercalación de las bases de datos del sistema?

No es posible cambiar la intercalación de las bases de datos del sistema. Si intenta cambiar la intercalación de las bases de datos del sistema:maestra, modelo, msdb o tempdb, recibirá este mensaje de error.

Deberá seguir los pasos descritos anteriormente sobre cómo cambiar la intercalación en el nivel de instancia de SQL Server para cambiar la intercalación de las bases de datos del sistema. Es importante obtener las intercalaciones correctas la primera vez que instala SQL Server para evitar este tipo de problemas.

El problema conocido sobre el conflicto de colación

Otro problema común que puede encontrar es el error relacionado con el conflicto de intercalación, especialmente al usar objetos temporales. Los objetos temporales se almacenan en tempdb. Al ser tempdb una base de datos del sistema, asumirá la intercalación de la instancia de SQL. Cuando crea bases de datos de usuario que tienen una intercalación diferente a la de la instancia de SQL, se encontrará con problemas al usar objetos temporales. También puede enfrentar problemas al comparar columnas en tablas que tienen intercalaciones diferentes. A estas alturas, ya sabe que una tabla puede tener columnas con diferentes intercalaciones, ya que no podemos cambiar la intercalación en el nivel de la tabla. El mensaje de error común que notará es algo así como "No se puede resolver el conflicto de intercalación entre" Intercalación 1 "y" Intercalación 2 "en la operación igual a". Collation1 y Collation2 pueden ser cualquier intercalación utilizada en una consulta. Usando un ejemplo simple, podemos producir una demostración de este conflicto de colación. Si completó los ejemplos anteriores en este artículo, ya tendrá una tabla llamada "emp". Simplemente cree una tabla temporal en su base de datos de demostración e inserte registros usando el script de muestra provisto.

create table #emptemp
(id int,
 fname nvarchar(20))

insert into  #emptemp
select * from emp

Simplemente ejecute una unión usando ambas tablas y obtendrá este error de conflicto de intercalación como se muestra a continuación.

select e.id, et.fname 
from emp e inner join #emptemp et
on e.fname=et.fname

Notará que la intercalación de la base de datos del usuario utilizada es "SQL_Latin1_General_CP1_CS_AS" y no coincide con la intercalación del servidor. Para corregir este tipo de error, puede modificar las columnas que se utilizan en los objetos temporales para utilizar la intercalación predeterminada de la base de datos del usuario. Puede usar la opción "database_default" o proporcionar explícitamente el nombre de la intercalación de la base de datos del usuario. En este ejemplo, usamos la intercalación "SQL_Latin1_General_CP1_CS_AS". Pruebe una de estas opciones
Opción 1: Use la opción base de datos_predeterminada

alter table #emptemp alter column
 fname nvarchar(20) collate database_default

Una vez hecho esto, vuelva a ejecutar la declaración de selección y el error se solucionará.
Opción 2: Utilice la intercalación de la base de datos de usuarios de forma explícita

alter table #emptemp alter column
 fname nvarchar(20) collate SQL_Latin1_General_CP1_CS_AS

Una vez hecho esto, ejecute la declaración de selección nuevamente y el error se solucionará.

Conclusión

En este artículo, aprendió sobre:
• el concepto de intercalación
• las diferentes opciones de intercalación disponibles
• encontrar detalles de intercalación para cualquier instancia SQL, base de datos y columna
• A EJEMPLO DE TRABAJO sobre cómo probar opciones de intercalación en consultas SQL
• cambiar intercalaciones a nivel de instancia, nivel de base de datos y nivel de columna
• CÓMO cambiar intercalaciones de bases de datos del sistema
• un conflicto de intercalación y cómo para arreglarlo

Ahora conoce la importancia de la intercalación y la importancia de configurar la intercalación correcta en la instancia de SQL y también en los objetos de la base de datos. Pruebe siempre los diversos escenarios en su entorno de prueba antes de aplicar cualquiera de las opciones anteriores en sus sistemas de producción.