web-dev-qa-db-de.com

Verwenden der "With-Klausel" von SQL Server 2008

Kann mir jemand ein Beispiel für ein SQL Server-Skript zeigen, das ich mir mit dem "With Clause" ansehen kann?

Ich versuche, diese Klausel zu verwenden, um 200 Datenbanken zu durchlaufen, die dieselbe Tabelle enthalten, für die ich eine Abfrage ausführen möchte. Ich versuche, die Verwendung eines Cursors zu vermeiden, da die Abfragezeit zu lang ist und auch eine while-Schleife verwendet wird.

Kann mir jemand raten, was ich tun kann.

Vielen Dank.

21
Jeff

Nur ein Schubser, aber hier ist eine andere Möglichkeit, FizzBuzz zu schreiben :) 100 Zeilen reichen aus, um die WITH-Anweisung zu zeigen, wie ich finde.

;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

Die eigentliche Kraft hinter WITH (bekannt als Common Table Expression http://msdn.Microsoft.com/en-us/library/ms190766.aspx "CTE") in SQL Server 2005 und höher ist die Rekursion (siehe unten), bei der die Tabelle durch Iterationen aufgebaut wird, die jedes Mal zur virtuellen Tabelle hinzugefügt werden.

;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

Um eine ähnliche Abfrage in allen Datenbanken auszuführen, können Sie die undokumentierte sp_msforeachdb verwenden. Es wurde in einer anderen Antwort erwähnt, aber es ist sp_msforeachdb, nicht sp_foreachdb.

Seien Sie vorsichtig, wenn Sie es verwenden, da einige Dinge nicht das sind, was Sie erwarten. Betrachten Sie dieses Beispiel

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

Anstelle der Anzahl der Objekte in jeder Datenbank wird die gleiche Anzahl gemeldet, beginnend mit der der aktuellen Datenbank. Um dies zu umgehen, "benutzen" Sie immer zuerst die Datenbank. Beachten Sie die eckigen Klammern, um Namen von Datenbanken mit mehreren Wörtern zu kennzeichnen.

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

Für Ihre spezielle Abfrage zum Ausfüllen einer Auflistungstabelle können Sie Folgendes verwenden. Sie sind sich der DATE-Spalte nicht sicher, daher enthält diese Auflistungstabelle nur die Spalten DBNAME und IMG_COUNT. Wir hoffen, dass dies Ihnen weiterhilft.

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

Es gibt zwei Arten von MIT -Klauseln:

Hier ist der FizzBuzz in SQL-Form unter Verwendung eines allgemeinen Tabellenausdrucks 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

Hier ist eine select-Anweisung, die auch eine WITH-Klausel verwendet

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

Versuchen Sie es mit der Prozedur sp_foreachdb.

1
Joel Coehoorn