![](/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.