QUOTED_IDENTIFIER en T-SQL: controlando el comportamiento de las comillas

QUOTED_IDENTIFIER es una de esas configuraciones clave que hará que nuestro código en SQL Server funcione. ¿Sabes realmente lo que implica?

Una de las opciones de configuración menos comprendidas, pero no por ello menos importantes, en SQL Server es QUOTED_IDENTIFIER. A menudo la encontramos en los scripts generados por Management Studio, en procedimientos almacenados o al realizar tareas de mantenimiento, pero, por experiencia, rara vez se le presta la atención que realmente merece. En este artículo vamos a analizar en profundidad qué es QUOTED_IDENTIFIER, cómo afecta al comportamiento de nuestras consultas T-SQL y por qué es esencial conocer su implicación en entornos complejos.

Introducción a QUOTED_IDENTIFIER: ¿Qué hace realmente?

La opción QUOTED_IDENTIFIER determina cómo SQL Server interpreta las comillas dobles («) en una consulta T-SQL. Cuando esta opción está activada, las comillas dobles delimitan identificadores (por ejemplo, nombres de columnas o tablas), permitiendo el uso de palabras reservadas o caracteres especiales. Por el contrario, si la opción está desactivada, las comillas dobles se interpretan como literales de cadena, lo que puede romper código que dependa de identificadores entrecomillados.

El comportamiento predeterminado de SQL Server desde versiones muy tempranas es tener QUOTED_IDENTIFIER activado. Sin embargo, todavía es posible desactivarla explícitamente, y ahí es donde empiezan las particularidades.

QUOTED_IDENTIFIER ON: el estándar ANSI al que estamos acostumbrados

Cuando QUOTED_IDENTIFIER está activado, se siguen las reglas ANSI SQL: las comillas dobles delimitan identificadores, y las cadenas de texto deben ir entre comillas simples (‘). Esto permite, por ejemplo, crear una columna llamada «select» o «Column With Spaces» sin que el motor se queje por el uso de palabras reservadas o caracteres especiales.

Podemos ver este comportamiento claramente:

Además, algunas funcionalidades de SQL Server, como los índices XML, las columnas calculadas indexadas o las consultas distribuidas, requieren explícitamente que QUOTED_IDENTIFIER esté activado. Es más, al crear procedimientos almacenados, vistas, funciones o triggers, esta opción queda «grabada» junto al objeto y no puede cambiarse dinámicamente durante su ejecución.

QUOTED_IDENTIFIER OFF: compatibilidad heredada… y peligros potenciales

Cuando QUOTED_IDENTIFIER está desactivado, las comillas dobles se tratan como delimitadores de cadenas. Esto puede llevar a comportamientos inesperados si asumimos que SQL Server sigue el estándar ANSI. Por ejemplo:

Este comportamiento puede parecer trivial, pero en entornos donde el código se genera dinámicamente o se espera interoperabilidad con otros motores, las diferencias sintácticas pueden provocar errores difíciles de depurar.

Además, muchas características modernas del motor de SQL Server no funcionarán si QUOTED_IDENTIFIER está desactivado en el momento de crear el objeto. Un ejemplo frecuente es el intento de indexar una columna calculada:

Esta consulta nos va a devolver un Error 1934 porque no es posible crear un índice en una columna calculada cuando QUOTED_IDENTIFIER está desactivado.

Objetos definidos: persistencia silenciosa

Uno de los aspectos más delicados de QUOTED_IDENTIFIER es que su valor queda almacenado con el objeto al momento de su creación. Es decir, si definimos una vista o procedimiento con QUOTED_IDENTIFIER OFF, ese valor persistirá en el objeto, aunque más tarde ejecutemos SET QUOTED_IDENTIFIER ON en sesiones posteriores.

Este hecho tiene implicaciones especialmente relevantes cuando trabajamos con funcionalidades como replicación, indexed views o columnas calculadas indexadas, ya que en muchas de estas características, SQL Server exige que QUOTED_IDENTIFIER esté activado.

Un ejemplo habitual en mantenimiento de bases de datos es encontrar procedimientos que fallan al intentar recompilarse simplemente porque fueron creados originalmente con QUOTED_IDENTIFIER OFF.

Podemos comprobar la configuración de un procedimiento almacenado de la siguiente forma:

Si el valor devuelto es 0, el objeto fue creado con QUOTED_IDENTIFIER OFF.

QUOTED_IDENTIFIER y ANSI_NULLS: el tándem inseparable

Cuando tratamos con buenas prácticas en la definición de objetos de base de datos, QUOTED_IDENTIFIER suele mencionarse junto a ANSI_NULLS. Y no es casualidad: ambos son requeridos por muchas de las características avanzadas de SQL Server. Las herramientas de desarrollo como Management Studio o SSDT los activan por defecto en los scripts generados, precisamente para garantizar que los objetos resultantes no estén limitados en funcionalidades futuras. Un ejemplo típico sería:

Comportamiento en SQL Server Agent 

Aunque en el uso interactivo de SQL Server, por ejemplo desde SQL Server Management Studio, QUOTED_IDENTIFIER suele estar activado por defecto, no ocurre lo mismo en todos los contextos. Un caso especialmente importante es la ejecución de scripts T-SQL desde pasos de tipo «Transact-SQL script (T-SQL)» en los trabajos de SQL Server Agent.

En estos pasos, la configuración predeterminada de la sesión establece QUOTED_IDENTIFIER OFF. Esto puede pasar completamente desapercibido si no se especifica manualmente la opción al inicio del script, pero las consecuencias pueden ser críticas. Cualquier intento de crear índices en columnas calculadas, vistas indexadas, procedimientos almacenados que dependan de esa opción, o incluso utilizar ciertas instrucciones que exigen la semántica ANSI, fallará silenciosamente o con errores que no apuntan directamente al problema.

Para evitarlo, es recomendable incluir explícitamente la activación de QUOTED_IDENTIFIER al inicio de cualquier script ejecutado desde SQL Server Agent, especialmente si ese script crea o modifica objetos:

Esta simple precaución asegura que los comportamientos esperados de la sesión se mantendrán, alineados con el desarrollo realizado en otras herramientas como SSMS o Visual Studio.

QUOTED_IDENTIFIER en flujos de trabajo DevOps y control de versiones

En escenarios donde utilizamos herramientas de CI/CD para desplegar cambios en bases de datos, la configuración de QUOTED_IDENTIFIER cobra especial relevancia. Los generadores de scripts, como SQLPackage o herramientas de despliegue como DACPACs, se apoyan en estas configuraciones para determinar si deben aplicar ciertos cambios o recrear objetos desde cero.

No es raro encontrarse con diferencias de comportamiento entre entornos debido a inconsistencias en estas opciones. Por tanto, siempre es recomendable mantener estas configuraciones explícitas y estandarizadas a lo largo del ciclo de vida del desarrollo.

QUOTED_IDENTIFIER y el rendimiento: ¿hay impacto?

Aunque QUOTED_IDENTIFIER no afecta directamente al plan de ejecución o a la eficiencia de una consulta, sí tiene un impacto indirecto. Como hemos mencionado, su estado condiciona el uso de columnas calculadas indexadas, vistas indexadas y otras estructuras que sí mejoran el rendimiento. Por tanto, mantener esta opción activada es esencial para no limitar las posibilidades de optimización que ofrece SQL Server.

Conclusión

A estas alturas parece evidente: en la mayoría de los escenarios, debemos trabajar con QUOTED_IDENTIFIER ON. No solo garantiza compatibilidad con las funcionalidades modernas del motor de SQL Server, sino que evita ambigüedades y errores sutiles cuando se manipulan identificadores que contienen caracteres especiales o palabras reservadas.

Los únicos contextos en los que podríamos considerar desactivarlo son aquellos de compatibilidad con aplicaciones muy antiguas o migraciones específicas donde el código ya existente lo exige. Fuera de esos casos, es una práctica segura y recomendada mantener QUOTED_IDENTIFIER activado en todas nuestras sesiones y scripts.

Para cerrar, si queremos asegurarnos de que todos nuestros objetos han sido creados con QUOTED_IDENTIFIER ON, conviene hacer una auditoría periódica en nuestros entornos y revisar su uso, especialmente si trabajamos con desarrolladores múltiples o heredamos bases de datos legacy.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima! 

Publicado por Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

2 comentarios

[…] que influyen en cómo SQL Server interpreta y almacena los datos. Lo relevante es que, al igual que QUOTED_IDENTIFIER, estas opciones no solo afectan a la sesión actual, sino que quedan asociadas al objeto creado o […]

[…] opciones en vistas indexadas o columnas calculadas? Te recomendamos leer nuestros artículos sobre QUOTED_IDENTIFIER y ANSI_NULLS y ANSI_PADDING, donde exploramos con más detalle cómo afectan a la creación y uso […]

Deja una respuesta