2010-06-25 18 views
5

La siguiente consulta no devuelve ningún resultado y no hay error en SQL Server 2008 (probado en SP1), puede ejecutarla en cualquier base de datos, incluso maestro:Roles de paréntesis en SQL Server ¿SELECCIONAR consultas?

WITH computed_table (id) AS 
(
    SELECT id FROM this_table_does_not_exist 
) 
(SELECT * FROM computed_table) 
UNION 
(SELECT * FROM another_table_that_does_not_exists) 

En SQL Server 2005, se produce un error debido a que el las tablas no existen Usted obtener también consigue un error si se quita algunos paréntesis:

WITH computed_table (id) AS 
(
    SELECT id FROM this_table_does_not_exist 
) 
SELECT * FROM computed_table 
UNION 
(SELECT * FROM another_table_that_does_not_exists) 

El mismo tipo de problemas aparece con tablas reales: en algunas ocasiones, la consulta no devuelve ningún resultado, y si usted hace algunos ligeros cambios , como eliminar un espacio o un retorno de carro, funciona de nuevo ...

Creo que puede haber un problema en la consulta, porque SELECCIONAR entre paréntesis puede interpretarse como una expresión en lugar de una subconsulta, como en this page. Pero eso debería al menos devolver un error.

¿Echo de menos algo?

Editar 26/06/2010: Ejecuté algunas sesiones de creación de perfiles, con los siguientes resultados.

Para la consulta anterior, la secuencia de eventos es:

  • Excepción (Error: 208, nombre de objeto no válido)
  • SQL: BatchStarting
  • SQL: StmtStarting
  • SQL: BatchCompleted

Para la consulta sin paréntesis:

  • Excepción (Error: 208)
  • SQL: BatchStarting
  • SQL: StmtStarting
  • Excepción (Error: 208)
  • Error del usuario Mensaje (nombre de objeto no válido 'this_table_does_not _exist')
  • SQL : BatchCompleted

Para una consulta de trabajo:

  • SQL: BatchStarting
  • SQL: StmtStarting
  • plan de presentación Todo
  • SQL: StmtCompleted
  • SQL: BatchCompleted

También me encontré con una de las consultas con tablas reales que me está causando el mismo problema.La secuencia de eventos es:

  • SQL: BatchStarting
  • SQL: StmtStarting
  • SQL: BatchCompleted

no temprana "Excepción" => existen las tablas. No "SQL: StmtCompleted" => significa que se produjo un error, no pude ver ninguna otra razón por la que este evento no se haya planteado. No "Showplan All" => significa que el error ocurre antes (o cuando) se calcula el plan de ejecución. Puede ser causado por la combinación de cte y paréntesis.

Plantearé el problema con el soporte de Microsoft la próxima semana.

+0

¿ha intentado cambiar los select * 's a los nombres de las columnas reales? – DForck42

+1

¡qué pregunta tan maravillosa! Primero, en 2008, también obtiene errores en la segunda declaración. Además, no veo que la declaración de UNIÓN tenga algo que ver con el comportamiento extraño, ya que la eliminación de la unión y la segunda selección no parece cambiar los resultados. Un dato interesante: cuando uso el primer enunciado y solicito un plan de ejecución estimado, no recibo ningún plan. Voy a correr un rastro ahora. HABLARÉ CONTIGO MÁS S TARDE. – MaasSql

+0

También publicará el código al que hace referencia: "También ejecuté una de las consultas con tablas reales que me causa el mismo problema". Además, por pura curiosidad, ¿estás tratando esto como un bloqueador para el desarrollo/un problema de producción? Si es así, parece que la solución sería no seguir el patrón cte, luego el paréntesis. – MaasSql

Respuesta

3

Así que simplifiqué el sql solo un poco, según mi comentario anterior sobre la pregunta original.

WITH computed_tabled AS 
(
    SELECT id FROM this_table_does_not_existd 
) 
(SELECT id FROM computed_tabled) 

Parece que nos da el mismo comportamiento. Entonces corrí un rastro. clases de eventos:

  • SQL: Lote A partir
  • SQL: lotes Completado
  • SQL: StmtStarting
  • SQL: StmtCompleted
  • plan de presentación Todo
  • plan de presentación XML

Lo que atrapado fue inesperado:

  • SQL: BatchStarting
  • SQL: StmtStarting
  • SQL: BatchCompleted

Nota: no SQL: StmtCompleted, no hay planes. Entonces, a continuación, vuelvo a la configuración de captura y agrego cada clase de evento en Errores y advertencias. Vuelva a ejecutar la consulta, y ¿qué sabe usted? El primer evento capturado es:

Error: 208, Severity: 16, State: 1 

¿Qué significa 208? Pero, el cliente nunca ve el error.

Lo que creo que es está sucediendo es que el código en el DBMS es decir - hey, no nos pidieron que devolviéramos nada ni hiciéramos nada, entonces ¿para qué molestarse? Liberemos algunos recursos para alguien más exigente.

Así que probamos este trozo de código:

--asdfasdf 
(SELECT 1) 

que soplaba totalmente mi teoría de distancia. El paréntesis NO se interpretaba como una expresión. En cambio, se interpretaban como una consulta completa (es decir, el cliente es solicitando que se devuelva algo) y devolvió un conjunto de registros con 1 columna y 1 fila. Pero no hay plan, probablemente b/c no se necesita ningún plan, ya que no hay objetos db involucrados.

Así, a meterse con mi mente un poco más he intentado esto:

declare @id as integer; 
; 
WITH computed_table AS 
(
    SELECT id FROM this_table_does_not_exist 
) 
select @id = (SELECT id FROM computed_table) 

Lo cual, al igual que la eliminación de los paréntesis, produce un mensaje de error del usuario.

Digo, no te falta nada. Creo que esto es un error de MS SQL Server. Ciertamente parece relacionado con el cte y el paréntesis. Intenté buscar en Google para mencionarlo, pero no encontré nada. Esto me dará algo de qué hablar en la próxima reunión local de PASS. Lo siento todo lo que tengo que agregar a la situación es confusión. ¡Si aprendo algo, estaré seguro y lo publicaré aquí!


actualización: 2010-06-26 10:09 CST fui a Microsoft Connect en un intento de encontrar esta figura como un problema. No he podido encontrar algo en torno a cte 208 o cte invalid object. Honestamente, no sé de otro sitio de listado de errores para el servidor SQL que uno podría verificar. También traté de buscar el Soporte de Microsoft y, de nuevo, Google.

Cuestiones relacionadas