使用“With Clause”SQL Server 2008

时间:2011-01-14 21:16:33

标签: sql-server-2008 sql-server-2008-r2

有人可以向我展示一个示例SQL服务器脚本,我可以看一下使用“With Clause”吗?

我正在尝试使用此子句来遍历200个数据库,这些数据库包含我尝试运行查询的相同表。我试图避免使用游标,因为查询时间太长以及使用while循环。

有人可以告诉我我能做些什么。

谢谢。

3 个答案:

答案 0 :(得分:36)

只是一个戳,但这是写FizzBu​​zz的另一种方式:) 我估计100行足以显示WITH语句。

;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

但SQL Server 2005及更高版本中WITH背后的真正强大功能(称为公用表表达式http://msdn.microsoft.com/en-us/library/ms190766.aspx“CTE”)是递归,如下所示,通过迭代添加到虚拟表来构建表每一次。

;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

要在所有数据库中运行类似的查询,可以使用未记录的 sp_msforeachdb 。在另一个答案中已经提到过,但它是sp_msforeachdb,而不是sp_foreachdb。

使用它时要小心,因为有些东西不是你所期望的。考虑这个例子

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

您将获得报告的SAME计数,而不是每个数据库中的对象计数,从当前数据库开始。 要解决这个问题,请始终先“使用”数据库。请注意方括号以限定多字数据库名称。

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

有关填充计数表的具体查询,可以使用如下所示的内容。不确定DATE列,所以这个tally表只有DBNAME和IMG_COUNT列,但希望它可以帮助你。

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 :(得分:8)

有两种类型的 WITH 子句:

以下是SQL表单中的FizzBu​​zz,使用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

这是一个也使用WITH子句

的select语句
SELECT * FROM orders WITH (NOLOCK) where order_id = 123

答案 2 :(得分:1)

尝试使用sp_foreachdb过程。