SQL Server en la práctica

Por qué SQL cambia entre la aplicación y SSMS

Compara opciones de sesión, tipos de parámetros y metadatos de módulos para explicar diferencias de SQL entre la aplicación y una ventana SSMS.

Una consulta funciona en SSMS pero falla o se ralentiza en la aplicación. Copiar el texto no reproduce la solicitud completa. La conexión tiene opciones, el controlador envía tipos de parámetros y un módulo puede conservar ajustes capturados cuando se creó.

Comparar interpretación antes de optimizar

El ejemplo interpreta la misma cadena de fecha con dos valores de DATEFORMAT. Guarda el formato original de la sesión y lo restaura al terminar.

DECLARE @OriginalFormat nvarchar(3);
SELECT @OriginalFormat = date_format
FROM sys.dm_exec_sessions WHERE session_id = @@SPID;

SET DATEFORMAT dmy;
SELECT TRY_CONVERT(date, '03/04/2023') AS InterpretedAsDMY;

SET DATEFORMAT mdy;
SELECT TRY_CONVERT(date, '03/04/2023') AS InterpretedAsMDY;

SET DATEFORMAT @OriginalFormat;

SELECT
    @@SPID AS SessionId,
    @@LANGUAGE AS SessionLanguage,
    @@DATEFIRST AS FirstDayOfWeek,
    @@LOCK_TIMEOUT AS LockTimeoutMs,
    SESSIONPROPERTY('ANSI_WARNINGS') AS AnsiWarnings,
    SESSIONPROPERTY('ARITHABORT') AS ArithAbort,
    SESSIONPROPERTY('QUOTED_IDENTIFIER') AS QuotedIdentifier;

DBCC USEROPTIONS;

El primer resultado es 3 de abril de 2023 y el segundo 4 de marzo de 2023. Ambas conversiones funcionan. Una prueba que solo busca errores no detectará la diferencia. Una fecha válida pero equivocada puede resultar más peligrosa que un fallo claro.

Prefiere parámetros de fecha tipados. Si necesitas intercambio textual, define una representación inequívoca y un estilo explícito adecuado. No dependas del idioma del desarrollador. DATEFIRST también puede afectar cálculos del día de la semana y exige un contrato claro.

Ejecuta el diagnóstico mediante la conexión real de la aplicación cuando sea posible. Otra sesión administrativa describe sus propios ajustes. Captura además base de datos, compatibilidad, aislamiento y tipos de parámetros. varchar y nvarchar con el mismo texto visible no son los mismos metadatos.

Separar sesión y metadatos del módulo

Algunas opciones SET influyen en ejecución y otras en análisis o creación del módulo. QUOTED_IDENTIFIER determina cómo se interpretan las comillas dobles. sys.sql_modules permite examinar uses_quoted_identifier y uses_ansi_nulls de procedimientos almacenados.

Cambiar una opción en una ventana de diagnóstico no modifica necesariamente los valores capturados del procedimiento. Si una migración creó el módulo con ajustes incorrectos, corrige deliberadamente CREATE o ALTER y verifica después los metadatos. Usa comillas simples para cadenas y convenciones coherentes para identificadores.

No recurras al comportamiento antiguo de NULL como solución moderna. SQL Server 2017 y posteriores siempre utilizan ANSI_NULLS ON. Escribe IS NULL o IS NOT NULL. Un SET ANSI_NULLS OFF heredado no restaura de forma fiable una suposición obsoleta.

El pool de conexiones añade otra razón para ser explícito. Inicialización y restablecimiento dependen del proveedor. La ruta soportada de conexión debe establecer lo necesario, sin confiar en que una solicitud anterior preparó la sesión.

Investigar planes sin un interruptor mágico

Algunas opciones participan en el contexto de caché de planes. Contextos distintos pueden producir planes diferentes para SQL aparentemente idéntico. Eso no demuestra que cambiar ARITHABORT sea la corrección adecuada. Parámetros de compilación, estimaciones y accesos pueden explicar el comportamiento real.

Captura ambos planes y compara tipos de parámetros, valores compilados, estimaciones de filas y lecturas medidas. Reproduce valores representativos en el mismo contexto. Una prueba interactiva para un cliente pequeño no explica una solicitud de producción para uno enorme.

Ciertas funciones indexadas también necesitan un conjunto concreto de opciones. Índices filtrados y sobre columnas calculadas tienen requisitos que incluyen ANSI_WARNINGS, QUOTED_IDENTIFIER y ARITHABORT, además de NUMERIC_ROUNDABORT OFF. Comprueba el conjunto completo documentado para la función.

Presta igual atención al estado transaccional. IMPLICIT_TRANSACTIONS puede dejar trabajo abierto más de lo esperado, y LOCK_TIMEOUT limita bloqueos, no duración total. Esas diferencias cambian fallos y esperas incluso sin otro plan.

Sitúa finalmente los ajustes necesarios en inicialización y despliegue y prueba las rutas de aplicación y administración. Guarda las opciones observadas con el incidente. El objetivo es reproducir la solicitud completa, para que 'funciona en mi ventana' sea una comparación útil y no el final de la investigación.

Referencias técnicas: Microsoft Learn: SET statements · Microsoft Learn: SET DATEFORMAT · Microsoft Learn: SET QUOTED_IDENTIFIER.

Pregunta sobre este artículo

¿Tiene alguna pregunta sobre este tema?

Cuéntenos qué está evaluando o dónde tiene dificultades. Le responderemos con una recomendación práctica.

Inquiries are not enabled in this preview.

Hacer una pregunta sobre este artículo