寻找更有效的方法来跨多个表选择最大RowUpdateDateTime列

时间:2013-01-10 20:52:02

标签: sql-server tsql loops

我的数据库的每个表中的每一行都有一个RowUpdateDateTime列,这是更新或插入特定行的最新时间。我还有每个表中有1到7个不同的数据源;有些有1个,有些有7个。

基本上,我正在尝试遍历这些表,并为这些表中的每个表找到每个这些源的最新RowUpdateDateTime(如果适用)。这是我和同事写这篇文章的真正长期查询。它是功能性的,但我怀疑可以重写。

IF OBJECT_ID('tempdb..#SourceID') IS NOT NULL
BEGIN
    DROP TABLE #SourceID
END

IF OBJECT_ID('tempdb..#Tables') IS NOT NULL
BEGIN
    DROP TABLE #Tables
END

IF OBJECT_ID('tempdb..#UpdateCount') IS NOT NULL
BEGIN
    DROP TABLE #UpdateCount
END

GO


CREATE TABLE #SourceID
    (
    SourceID varchar(4),
    CounterID int
    )

INSERT INTO #SourceID (SourceID,CounterID)
SELECT 'ZEND',1
UNION ALL
SELECT 'ABC',2
UNION ALL
SELECT 'DEF',3
UNION ALL 
SELECT 'GHI',4
UNION ALL
SELECT 'JKL',5
UNION ALL
SELECT 'MNO',6
UNION ALL
SELECT 'PQR',7
UNION ALL
SELECT 'STU',8

GO  

CREATE TABLE #Tables
    (
    Name varchar(100),
    CounterID int
    )

INSERT INTO #Tables (Name,CounterID)
SELECT 'livendb..Table1',1
UNION ALL
SELECT 'livendb..Table2',2
UNION ALL
SELECT 'livendb..Table3',3
UNION ALL
SELECT 'livendb..Table4',4
UNION ALL
SELECT 'livendb..Table5',5
UNION ALL
SELECT 'livendb..Table6',6
UNION ALL
SELECT 'livendb..Table7',7
UNION ALL
SELECT 'livefdb..Table8',8
UNION ALL
SELECT 'livefdb..Table9',9
UNION ALL
SELECT 'livefdb..Table10',10
UNION ALL
SELECT 'livefdb..Table11',11
UNION ALL
SELECT 'livefdb..Table12',12
UNION ALL
SELECT 'livefdb..Table13',13

GO

Declare @counter varchar(10)
Declare @tablename varchar(100)
Declare @query varchar(1100)
Declare @sourceid varchar(4)
Declare @sourcecounter varchar(10) 


CREATE TABLE #UpdateCount
    (
    SourceID varchar(3),
    TableName Varchar(100),
    MaxRowUpdateDateTime datetime,
    --TotalRowCount int
    )


SET @sourcecounter = (SELECT COUNT(*) FROM #SourceID)
SET @counter = (SELECT COUNT (*) FROM #Tables)

WHILE @sourcecounter >= 0
BEGIN
    SET @sourceid = (SELECT SourceID FROM #SourceID WHERE CounterID = (@sourcecounter))
        IF @sourceid <> 'ZEND'
        BEGIN
                WHILE @counter >=0
                BEGIN
                    SET @tablename = (SELECT Name FROM #Tables WHERE CounterID = (@counter))

                    IF @counter <> 0
                    BEGIN
                    SET @query = 'INSERT INTO #UpdateCount (SourceID,TableName,MaxRowUpdateDateTime)
                                VALUES (
                                        (SELECT SourceID FROM #SourceID WHERE CounterID = '+@sourcecounter+')
                                        ,(SELECT Name FROM #Tables WHERE CounterID = '+@counter+')
                                        ,(SELECT MAX(RowUpdateDateTime) FROM '+@tablename+' WHERE SourceID = 
                                                        (SELECT SourceID FROM #SourceID WHERE CounterID = '+@sourcecounter+')))'

                    EXECUTE (@query)
                    END
                SET @counter = (@counter-1)
                END

        END

    SET @sourcecounter = (@sourcecounter-1)
    SET @counter = (SELECT COUNT (*) FROM #Tables)
END

        SELECT  SourceID
                ,SUBSTRING(TableName,10,22) as TableName
                ,MaxRowUpdateDateTime
                --,TotalRowCount
        FROM #UpdateCount 
            Where MaxRowUpdateDateTime IS NOT NULL
            ORDER BY TableName

DROP TABLE #Tables
DROP TABLE #UpdateCount
DROP TABLE #SourceID

1 个答案:

答案 0 :(得分:1)

根据此示例的模式,您可能会更好(因为代码更简单)。它没有回答你的整个问题(很难对没有数据的动态SQL进行编码 - 至少对我而言)。

这应该为你提供一个良好的起点。

USE AdventureWorks2012
GO

DECLARE @Query VARCHAR(MAX) =''

;WITH Tables AS
(
    SELECT DISTINCT TABLE_NAME = '[' + TABLE_SCHEMA + ']' + '.' + '[' + TABLE_NAME + ']'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE COLUMN_NAME = 'ModifiedDate'
)
SELECT  @Query  = @Query + 
'   SELECT   SourceTable    = '''+ TABLE_NAME + '''
            ,RecentMod      = MAX(ModifiedDate) 
    FROM ' + TABLE_NAME + ' UNION ALL'
FROM Tables

SET @Query = LEFT(@Query, LEN(@Query) - LEN(' UNION ALL'))

EXEC (@Query)

制作这样的结果;

SourceTable                                     |   RecentMod
===========================================================================
[dbo].[AWBuildVersion]                          |   2012-03-14 00:00:00.000
[dbo].[OLE DB Destination]                      |   2008-07-31 00:00:00.000
[HumanResources].[Department]                   |   2002-06-01 00:00:00.000
[HumanResources].[Employee]                     |   2009-01-26 09:17:08.637
[HumanResources].[EmployeeDepartmentHistory]    |   2007-12-15 00:00:00.000
[HumanResources].[EmployeePayHistory]           |   2008-07-31 00:00:00.000
[HumanResources].[JobCandidate]                 |   2008-01-23 18:32:21.313
[HumanResources].[Shift]                        |   2002-06-01 00:00:00.000
[HumanResources].[vJobCandidate]                |   2008-01-23 18:32:21.313
[Person].[Address]                              |   2008-07-31 00:00:00.000
[Person].[AddressType]                          |   2002-06-01 00:00:00.000
[Person].[BusinessEntity]                       |   2012-01-14 13:47:22.467
[Person].[BusinessEntityAddress]                |   2008-10-13 11:15:06.967
...