2011-01-14 12 views
19

¿Alguien me puede mostrar un script de SQL Server de ejemplo que puedo ver que usa el "With Clause"?Uso de "Con cláusula" SQL Server 2008

Estoy tratando de usar esta cláusula para iterar a través de 200 bases de datos que contienen la misma tabla en la que estoy tratando de ejecutar una consulta. Estoy tratando de evitar usar un cursor porque el tiempo de consulta lleva demasiado tiempo y también el uso de un ciclo while.

¿Alguien me puede aconsejar sobre lo que puedo hacer?

Gracias.

+1

'WITH' no le ayudará en esta tarea. ¿Están todas las bases de datos en la misma instancia? ¿Cuál es el código que está ejecutando en todos ellos? –

+3

Para citar a Inigo Montoya de [The Princess Bride] (http://www.imdb.com/title/tt0093779/): "Sigues usando esa palabra. No creo que signifique lo que piensas que significa". :-) –

+1

Martin, sí, están en la misma instancia. cada base de datos tiene la misma tabla. Deseo utilizar la función suma para recopilar todos los datos de las tablas y hacer que el nombre de cada base de datos se llene en una tabla temporal con las siguientes columnas: DBNAME, IMG_COUNT, DATE.El nombre de la tabla es tbldoc o dbo.tbldoc. Cada base de datos contiene esta tabla y todas tienen las mismas columnas que deseo consultar. ¿Qué haría para acelerar esto, en lugar de usar un cursor o while loop? – Jeff

Respuesta

31

Sólo un empuje, pero aquí es otra manera de escribir FizzBuzz :) 100 filas es suficiente para mostrar el estado CON, calculo .

;WITH t100 AS (
SELECT n=number 
FROM master..spt_values 
WHERE type='P' and number between 1 and 100 
)     
SELECT 
    ISNULL(NULLIF(
    CASE WHEN n % 3 = 0 THEN 'Fizz' Else '' END + 
    CASE WHEN n % 5 = 0 THEN 'Buzz' Else '' END, ''), RIGHT(n,3)) 
FROM t100 

Pero el verdadero poder detrás CON (conocida como tabla comunes Expresión http://msdn.microsoft.com/en-us/library/ms190766.aspx "CTE") en SQL Server 2005 y arriba es la recursividad, ya que por debajo de donde la mesa se construye a través de iteraciones agregándose a la mesa virtual cada vez.

;WITH t100 AS (
SELECT n=1 
union all 
SELECT n+1 
FROM t100 
WHERE n < 100 
)     
SELECT 
    ISNULL(NULLIF(
    CASE WHEN n % 3 = 0 THEN 'Fizz' Else '' END + 
    CASE WHEN n % 5 = 0 THEN 'Buzz' Else '' END, ''), RIGHT(n,3)) 
FROM t100 

para ejecutar una consulta de base de datos similar en todos, puede utilizar los indocumentados sp_msforeachdb. Se ha mencionado en otra respuesta, pero es sp_msforeachdb, no sp_foreachdb.

Tenga cuidado al usarlo, ya que algunas cosas no son lo que espera. Considere este ejemplo

exec sp_msforeachdb 'select count(*) from sys.objects' 

En lugar de los cargos de los objetos dentro de cada base de datos, obtendrá el mismo número reportado, comenzará el de la base de datos actual. Para evitar esto, siempre "use" la base de datos primero. Tenga en cuenta los corchetes para calificar nombres de bases de datos de varias palabras.

exec sp_msforeachdb 'use [?]; select count(*) from sys.objects' 

Para su consulta específica sobre cómo completar una tabla de conteo, puede usar algo como el siguiente. No estoy seguro acerca de la columna FECHA, por lo que esta tabla de recuento solo tiene las columnas DBNAME e IMG_COUNT, pero espero que lo ayude.

create table #tbl (dbname sysname, img_count int); 

exec sp_msforeachdb ' 
use [?]; 
if object_id(''tbldoc'') is not null 
insert #tbl 
select ''?'', count(*) from tbldoc' 

select * from #tbl 
+1

bien, parece que la mejor manera de hacerlo es utilizar un ciclo while que supuestamente es más rápido en el procesamiento en comparación con un ciclo while. esto es lo que tengo hasta ahora – Jeff

+0

Esto realmente me ayudó mucho a lograr la obtención de datos en el botón de localización clic de la cuadrícula. Muchas gracias. –

1

Pruebe el procedimiento sp_foreachdb.

+0

Eso solo utiliza un cursor, por lo que probablemente no sea un rendimiento de velocidad espectacular en el sistema actual del OP (no es que sospeche que esto sea posible) –

+0

Martin, sí, están en la misma instancia. cada base de datos tiene la misma tabla. Deseo utilizar la función de suma en una columna específica para reunir todos los datos de las tablas y hacer que el nombre de cada base de datos se llene en una tabla temporal con las siguientes columnas: DBNAME, IMG_COUNT, DATE. El nombre de la tabla es tbldoc o dbo.tbldoc. Cada base de datos contiene esta tabla y todas tienen las mismas columnas que deseo consultar. ¿Qué haría para acelerar esto, en lugar de usar un cursor o while loop? – Jeff

+0

No hay forma de hacerlo sin bucles. Sin embargo, la mayor parte del tiempo se tomará en las consultas individuales, no en el bucle en sí. Podría (1) Probar y paralelizar un poco. (2) Asegúrese de que 'tbldoc' en todas las bases de datos tenga los índices apropiados para la consulta tou que se está ejecutando o (3) Pruebe e introduzca algún precalculado. –

7

Hay dos tipos de CON cláusulas:

Aquí está el FizzBuzz en forma de SQL, utilizando una expresión de tabla común CON (CTE).

;WITH mil AS (
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY c.column_id) [n] 
FROM master.sys.all_columns as c 
CROSS JOIN master.sys.all_columns as c2 
)     
SELECT CASE WHEN n % 3 = 0 THEN 
      CASE WHEN n % 5 = 0 THEN 'FizzBuzz' ELSE 'Fizz' END 
     WHEN n % 5 = 0 THEN 'Buzz' 
     ELSE CAST(n AS char(6)) 
    END + CHAR(13) 
FROM mil 

que aquí hay una instrucción de selección también usando una cláusula WITH

SELECT * FROM orders WITH (NOLOCK) where order_id = 123 
+0

gracias es útil –