2013-11-14 22 views
-1

我正在查找SQL Server中的查詢,該查詢將返回特定架構中所有表中給定年份的行總數,在此例中爲dbodbo架構中所有表按年排列的行數

該模式中的所有表都有一個名爲UPDT_TS的列,該列存儲該行上次更新並可用於此日期計算的時間。

+0

你將不得不作出一個過程通過'information_schema.tables'獲取該模式的所有表格,然後對按提取年份分組的行進行計數並將其總和。 –

+0

我們在這裏討論的表格有多少? – JNK

回答

2

您可以使用簡單的遊標和動態SQL。

declare @v_Year int 
set @v_Year = 2013 

declare @v_TableName nvarchar(256) 
declare @v_SQL nvarchar(max) 
declare @v_Count int 

declare @v_ResultTable table 
(
    TableName nvarchar(256), 
    [RowCount] int 
) 

declare cur cursor local fast_forward read_only for 
select t.name from sys.tables as t 
inner join sys.columns as c on t.object_id = c.object_id 
where c.name = 'UPDT_TS' and t.schema_id = schema_id('dbo') 

open cur 

while (1=1) 
begin 

    fetch next from cur into @v_TableName 

    if @@FETCH_STATUS <> 0 
     break; 

    set @v_SQL = 'select @v_Count = count(*) from '+QUOTENAME(@v_TableName)+' where year(UPDT_TS) = ' + cast(@v_Year as nvarchar(4)) 

    exec sp_executesql @v_SQL, N'@v_Count int output', @v_Count output 

    insert into @v_ResultTable 
    select @v_TableName, @v_Count 

end 

close cur 
deallocate cur 

select * from @v_ResultTable 

編輯 剛看到山羊的答案張貼後:)看起來我們哈得同樣的想法:)

2

假設你有一個結果表中插入記錄,你可以用一個簡單的光標做到這一點:

DECLARE @Iterator varchar(255) 
     ,@strSQL varchar(MAX) 

DECLARE xyz CURSOR CURSOR FAST_FORWARD READ_ONLY 
FOR 
SELECT t.name 
FROM sys.schemas s 
JOIN sys.tables t 
    ON s.schema_id = t.schema_id 
WHERE s.name = 'dbo' 

OPEN xyz 
FETCH NEXT FROM xyz 
INTO @Iterator  
WHILE @@FETCH_STATUS = 0 
BEGIN 

SET @strSQL = 'INSERT INTO Results 
      SELECT COUNT(*) as Rows, '''[email protected]+''' as TableName 
      FROM '+QUOTENAME(@Iterator)+' 
      WHERE YEAR(UPDT_TS) = 2013   
      ' 
EXEC (@strSQL) 

    FETCH NEXT FROM xyz 
    INTO @Iterator 
END 
CLOSE xyz 
DEALLOCATE xyz 
GO 

每當處理動態SQL它可以幫助改變EXEC (@strSQL)PRINT (@strSQL),以確保你已經得到了固定的語法。

+1

哈哈...謝謝...我不認爲編輯看起來很正確的列別名。 (+1) – swasheck

+0

我喜歡'QUOTENAME'的用法,經常使用'FOR XML PATH',但別在別處考慮。不是故意刪除'CURSOR FAST_FORWARD READ_ONLY',但我認爲這種情況不會有什麼不同。 –

+0

它不會,但我只是把它作爲一個習慣的問題 – swasheck

0

這也將工作:

DECLARE @sql NVARCHAR(max) 
,@year INT 

SET @year = 2013 

SELECT @sql = 'select sum (total) from (' + SUBSTRING(cast((
      SELECT ' union select count(*) as Total 
       from ' + quotename(table_name) + ' 
       where 
        UPDT_TS between dateadd(year,@year-1900,0) and dateadd(s,-1,dateadd(year,@year-1900+1,0))' 
      FROM information_schema.columns 
      WHERE column_name = 'UPDT_TS' 
       AND TABLE_SCHEMA = 'dbo' 
      FOR XML path('') 
      ) AS NVARCHAR(max)), 8, 8000) + ') as Presum' 

PRINT @sql 

EXEC sp_executesql @sql 
,N'@year int' 
,@year = @year