Comportamiento SQL al ejecutar consultas con conjunciones

Si tengo una consulta SQL que está realizando una verificación de existencia contra tres tablas:

IF EXISTS(SELECT [KEY] FROM [Table1] WHERE [KEY]='Key1')
    AND EXISTS(SELECT [KEY] FROM [Table2] WHERE [KEY]='Key2')
    AND EXISTS(SELECT [KEY] FROM [Table3] WHERE [KEY]='Key3')
  1. ¿SQL Server admite la "salida anticipada" para las declaraciones condicionales, de modo que si la comprobación inicial de existe con [Tabla1] devuelve falso, las dos comprobaciones de existencia restantes no se ejecutan?
  2. Suponiendo que Microsoft SQL Server sea el backend, ¿qué comportamiento de bloqueo esperaría ver en las tres tablas a las que se hace referencia, nuevamente asumiendo que la verificación inicial existente contra Table1 devolverá falso?

Algunas pruebas básicas que utilizan funciones en lugar de consultas reales sugerirían que se admite la "salida anticipada", pero el análisis de bloqueo durante la ejecución de la consulta también sugiere que se adquiere un bloqueo en las tres tablas, lo que contradice los hallazgos de la "salida anticipada".

¿SQL Server adquiere un bloqueo en todas las tablas en una consulta, en caso de que los necesite más adelante?

preguntado el 16 de mayo de 11 a las 19:05

Se supone que las sentencias SQL son atómicas. Al combinar tres consultas separadas en una sola como lo ha hecho, fuerza al servidor SQL a bloquear las tablas involucradas, para que pueda recuperar resultados consistentes. De lo contrario, algunas de las claves que está comprobando podrían aparecer o desaparecer en una tabla mientras la consulta real se ejecuta en otra. -

3 Respuestas

SQL Server realizar una evaluación de cortocircuito, pero no puede controlar el orden en el que elige evaluar las cláusulas, a menos que lo haga a través de un CASE declaración.

contestado el 16 de mayo de 11 a las 23:05

De hecho, se ha demostrado que CASE no es predecible. Encontrará el guión / artículo de demostración - gbn

@gbn thx, sería de agradecer. Mi información de: weblogs.sqlteam.com/jeffs/archive/2008/02/22/… - D'Arcy Rittich

OK lo encontré, resulta ser un error de SQL Server (actualización de marzo de 2011) de bartduncansql.wordpress.com/2011/03/03/…. También hay cosas en los comentarios a su enlace de uno de los equipos de MS SQL Server blogs.msdn.com/b/sqlprogrammability/archive/2006/05/12/… - gbn

notario público. Actualicé mi respuesta para reflejar nueva información. Tienes razón, así que +1 - gbn

Editar: hay un error en SQL Server aparentemente que provoca un cortocircuito ocasional. Vea los comentarios sobre la respuesta de RedFilter. Si desea un cortocircuito, utilice IF anidados.

Generalmente, SQL es declarativo, no procedimental, por lo que nunca puede asumir que una expresión o consulta se evaluará en el orden en que se escribe. Editar: excepto CASO ...

IF EXISTS(SELECT [KEY] FROM [Table1] WHERE [KEY]='Key1')
BEGIN
    IF EXISTS(SELECT [KEY] FROM [Table2] WHERE [KEY]='Key2')
    BEGIN
        IF EXISTS(SELECT [KEY] FROM [Table3] WHERE [KEY]='Key3')
        BEGIN

Esto también cambiaría la forma en que se aplican los bloqueos: ahora tendrá bloqueos separados para cada consulta en lugar de bloqueos para las tres tablas durante la primera expresión AND

contestado el 16 de mayo de 11 a las 23:05

SQL Server no hace cortocircuito. Todas las partes de la declaración deben evaluarse y todos los bloqueos relevantes deben tomarse mientras se ejecuta la consulta.

contestado el 23 de mayo de 17 a las 15:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.