web-dev-qa-db-fra.com

Utilisation de la clause "With Clause" SQL Server 2008

Quelqu'un peut-il me montrer un exemple de script SQL Server que je peux consulter et qui utilise le "With Clause"?

J'essaie d'utiliser cette clause pour parcourir les 200 bases de données qui contiennent la même table que j'essaie d'exécuter une requête. J'essaie d'éviter d'utiliser un curseur parce que le temps de requête prend trop de temps ainsi que d'utiliser une boucle while.

Quelqu'un peut-il me conseiller sur ce que je peux faire?.

Merci.

21
Jeff

Juste un coup, mais voici une autre façon d'écrire FizzBuzz :) 100 lignes suffisent pour montrer l'instruction WITH, je pense.

;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

Mais la véritable puissance derrière WITH (connue sous le nom d’expression de table commune http://msdn.Microsoft.com/en-us/library/ms190766.aspx "CTE") dans SQL Server 2005 et au-dessus est le Récursivité, comme ci-dessous, où la table est constituée par des itérations ajoutant à la table virtuelle à chaque fois.

;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

Pour exécuter une requête similaire dans toutes les bases de données, vous pouvez utiliser le sp_msforeachdb non documenté . Il a été mentionné dans une autre réponse, mais c'est sp_msforeachdb, pas sp_foreachdb.

Soyez prudent lorsque vous l'utilisez, car certaines choses ne sont pas ce que vous attendez. Considérez cet exemple

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

Au lieu du nombre d'objets dans chaque base de données, vous obtiendrez le même nombre signalé, commencez celui de la base de données actuelle. Pour contourner ce problème, "utilisez" toujours la base de données en premier. Notez les crochets pour qualifier les noms de base de données multi-Word.

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

Pour votre requête spécifique sur le remplissage d'une table de pointage, vous pouvez utiliser quelque chose comme ci-dessous. Vous n'êtes pas sûr de la colonne DATE, donc cette table de comptage ne contient que les colonnes DBNAME et IMG_COUNT, mais j'espère que cela vous aidera.

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
36
RichardTheKiwi

Il existe deux types de clauses AVEC :

Voici le FizzBuzz sous forme SQL, utilisant une expression de table commune WITH (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

Voici une instruction select utilisant également une clause WITH

SELECT * FROM orders WITH (NOLOCK) where order_id = 123
8
Simon Hughes

Essayez la procédure sp_foreachdb.

1
Joel Coehoorn