我有一个游标,它遍历数据库中的每个基本表。它通过执行一条动态SQL将记录插入到另一个表中,但是到目前为止,它需要花费20分钟以上的时间来执行。
DECLARE TableCursor CURSOR FOR
SELECT TABLE_NAME
FROM <DB>.INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
WHILE(@@FETCH_STATUS = 0)
BEGIN
#Dynamic SQL Query to insert data into each table in cursor#
我进行了一些研究,发现使用带有UNION表达式的CTE会更快,但是我不确定如何进行转换,例如如何遍历CTE中的每个表。
非常感谢您的帮助。
编辑:这是动态SQL的示例:
SELECT @SQL = 'WITH CTE_DATES(DATE_VAL) AS (
SELECT DISTINCT DATE_VAL
FROM DATE_EVERY_DAY
WHERE DATE_VAL <= GETDATE()
)
INSERT INTO COUNT_RECORDS_TABLE (DATE_VAL, TABLE_NAME, NUM_RECS_IMPORTED)
SELECT cd.DATE_VAL, ''' + @TableName + ''' AS TABLE_NAME, COUNT(CAST(tn.IMPORT_DATE AS DATE)) AS NUM_RECS_IMPORTED
FROM CTE_DATES AS cd LEFT JOIN ' + @TableName + ' AS tn
ON CAST(tn.IMPORT_DATE AS DATE) = cd.DATE_VAL
GROUP BY cd.DATE_VAL'
答案 0 :(得分:1)
我会尝试使用sys.sp_MSForeachTable。这大约是最快的速度,而?字符是[schema]。[tablename]格式的表名。很明显,如果您只需要表名,则可以做一些文本替换。直接替换意味着您无需弄乱CTE,并且如果DATE_EVERY_DAY.DATE_VAL列上有索引,则该查询可以利用它。
EXEC sys.sp_MSforeachtable
'INSERT INTO COUNT_RECORDS_TABLE (DATE_VAL, TABLE_NAME, NUM_RECS_IMPORED)
SELECT
cd.DATE_VAL,
''?'' AS TABLE_NAME,
COUNT(tn.IMPORT_DATE) AS NUM_RECS_IMPORTED
FROM
DATE_EVERY_DAY AS cd
LEFT JOIN
? AS tn ON
CAST(tn.IMPORT_DATE AS DATE)=cd.DATE_VAL
WHERE
DATE_VAL <= GETDATE()
GROUP BY
cd.DATE_VAL
'
这里有一个深入的示例:SQL Server Undocumented Stored Procedures sp_MSforeachtable and sp_MSforeachdb