![](/img/trans.png)
[英]Using Delta Tables in Azure Synapse Dedicated/Serverless SQL Pools
[英]How to loop a SELECT statement on a list of tables in Azure Synapse using Dynamic SQL?
我經常需要找出多個表的記錄計數的最新日期。 目前我正在嘗試從表列表中找出最大加載日期。
我有以下示例表列表:
TableA
TableB
TableC
TableD
到目前為止,我能夠聲明一個變量並將單個表名作為參數傳遞到我的 SQL 狀態表中,如下所示:
DECLARE @SQLstmnt varchar(500)
DECLARE @tname varchar(200)
SET @tname = 'TableA'
SET @SQLstmnt = 'SELECT MAX(loaddate) FROM ' + @tname
EXEC (@SQLstmnt)
但我不知道如何傳遞我的整個表名列表(TableA, TableB, TableC, TableD)
並在列表中的每個表上循環上面的 SELECT 語句。
我搜索了一種解決方案,但我似乎找不到適合我的情況的解決方案。
有人可以幫忙嗎?
您可以為所有表構建一個動態聯合查詢並以這種方式執行它:
DECLARE @SQL NVARCHAR(MAX);
SELECT @SQL = CONCAT('SELECT TableName, Date FROM (',
STRING_AGG(CONCAT('SELECT TableName = ''', t.Name, ''', Date = MAX(', c.name, ')
FROM ', QUOTENAME(s.name), '.', QUOTENAME(t.name)), ' UNION ALL '),
') AS t;')
FROM sys.columns AS c
INNER JOIN sys.tables AS t
ON t.object_id = c.object_id
INNER JOIN sys.schemas AS s
ON s.schema_id = t.schema_id
WHERE c.name = 'LoadDate' -- Check Column Exists
AND t.name IN ('TableA', 'TableB', 'TableC', 'TableD') -- Limit to required tables;
HAVING COUNT(*) > 0
PRINT @sql
EXECUTE sp_executesql @SQL;
這將為您的示例構建一個類似這樣的 SQL 語句:
SELECT TableName, Date
FROM (SELECT TableName = 'TableA', Date = MAX(LoadDate) FROM dbo.TableA
UNION ALL
SELECT TableName = 'TableB', Date = MAX(LoadDate) FROM dbo.TableB
UNION ALL
SELECT TableName = 'TableC', Date = MAX(LoadDate) FROM dbo.TableC
UNION ALL
SELECT TableName = 'TableD', Date = MAX(LoadDate) FROM dbo.TableD
) AS t;
並將所有表/日期作為一個集合返回:
如果您真的想遍歷表,那么我仍然會使用系統視圖作為起點來驗證 (a) 表是否存在並且 (b) 包含加載日期列,但使用CURSOR
來執行語句針對每個表而不是構建單個語句:
DECLARE TableCursor CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR
SELECT CONCAT(QUOTENAME(s.name), '.', QUOTENAME(t.name))
FROM sys.columns AS c
INNER JOIN sys.tables AS t
ON t.object_id = c.object_id
INNER JOIN sys.schemas AS s
ON s.schema_id = t.schema_id
WHERE c.name = 'LoadDate'
AND t.name IN ('TableA', 'TableB', 'TableC', 'TableD') -- Limit to required tables;
DECLARE @TableName SYSNAME;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL NVARCHAR(MAX) = CONCAT('SELECT TableName = ''', @TableName, ''', Date = MAX(LoadDate) FROM ', @TableName);
EXECUTE sp_executesql @SQL;
FETCH NEXT FROM TableCursor INTO @TableName;
END
CLOSE TableCursor;
DEALLOCATE TableCursor;
超級簡單...只需使用一個WHILE
循環
DECLARE @MyTable TABLE ([Name] varchar(256), Done bit default(0));
INSERT INTO @MyTable ([Name])
VALUES
('TableA'),
('TableB'),
('TableC'),
('TableD');
DECLARE @SQLstmnt nvarchar(max), @tname varchar(200);
WHILE EXISTS (SELECT 1 FROM @MyTable WHERE Done = 0) BEGIN
SELECT TOP 1 @tname = [Name]
FROM @MyTable
WHERE Done = 0;
SET @SQLstmnt = 'SELECT MAX(loaddate) FROM ' + @tname + ';';
-- This is the best practice way to execute dynamic SQL
-- EXEC sp_executesql @SQLstmnt;
-- Debug the dynamic SQL
PRINT(@SQLstmnt);
UPDATE @MyTable SET Done = 1 WHERE [Name] = @tname;
END;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.