首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解动态SQL

理解动态SQL
EN

Stack Overflow用户
提问于 2018-07-10 10:08:37
回答 2查看 72关注 0票数 2

在我试图理解动态SQL的过程中,我尝试通过动态插入sys.tables的每个表中的行数来开始simple。

这是我的密码:

代码语言:javascript
复制
SELECT 
    Name, ROW_NUMBER() OVER (ORDER BY NEWID() ) AS SomeNumb
INTO
    #Dyn
FROM 
    sys.tables

CREATE TABLE ##Results (Cnt INT)    

DECLARE @Table NVARCHAR(100)
DECLARE @Counter INT

SET @Counter = 1
SET @Table = (SELECT Name FROM #Dyn WHERE SomeNumb = @Counter)

DECLARE @Sql NVARCHAR(1000)

WHILE @Counter <= (SELECT COUNT(*) FROM #Dyn)
BEGIN
    INSERT INTO ##ResultsTable
    SELECT @Sql = 'SELECT COUNT(*) AS Cnt FROM #Dyn WHERE 
    Name = ' + @Table + 'AND SomeNumb = ' + @Counter
    EXECUTE (@Sql)

    SET @Counter = @Counter + 1
    SET @Sql = ''
END

SELECT * FROM ##ResultsTable

唯一的好处是不要出错。虽然这可能会给我一些方向。我知道我的ResultsTable存在范围问题,但我认为使用##而不是#可以解决这个问题。

任何指示都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-10 10:29:27

这里有一个经过审查的脚本。

代码语言:javascript
复制
IF OBJECT_ID('tempdb..#Dyn') IS NOT NULL
    DROP TABLE #Dyn

SELECT Name, ROW_NUMBER() OVER (ORDER BY NEWID() ) AS SomeNumb
INTO #Dyn
FROM sys.tables

IF OBJECT_ID('tempdb..#ResultsTable') IS NOT NULL
    DROP TABLE #ResultsTable

CREATE TABLE #ResultsTable (TotalRowCount INT)

DECLARE @Counter INT = 1
DECLARE @Sql NVARCHAR(MAX)

WHILE @Counter <= (SELECT COUNT(*) FROM #Dyn)
BEGIN

    DECLARE @Table NVARCHAR(100) = (SELECT Name FROM #Dyn WHERE SomeNumb = @Counter)

    SELECT @Sql = '
        INSERT INTO #ResultsTable (TotalRowCount)
        SELECT COUNT(*) AS Cnt 
        FROM #Dyn 
        WHERE Name = ''' + @Table + ''' AND SomeNumb = ' + CONVERT(NVARCHAR(10), @Counter)

    EXECUTE (@Sql)

    SET @Counter += 1

END


SELECT * FROM #ResultsTable

有几件事要提:

  • 您可以在EXEC之外创建一个临时表,并将其插入动态SQL中。
  • COUNT()表的#Dyn总是返回1,因为只有1条记录具有特定的表名。
  • 在动态SQL上打印varchar值(如@Table)时,需要添加额外的引号:
  • 在构建动态SQL (如VARCHAR )时,需要将所有非文字值转换为NVARCHAR@Counter

编辑:如果您想要对每个表进行实际计数,那么您不需要查询#Dyn

代码语言:javascript
复制
SELECT @Sql = '
    INSERT INTO #ResultsTable (TotalRowCount)
    SELECT COUNT(*) AS Cnt 
    FROM ' + QUOTENAME(@Table) +

EXECUTE (@Sql)
票数 0
EN

Stack Overflow用户

发布于 2018-07-10 10:37:33

一种方法不是使用CURSORWHILE循环,而是使用sys.tablessys.schemasFOR XML PATH

代码语言:javascript
复制
DECLARE @SQL nvarchar(MAX);
SET @SQL = (SELECT N'SELECT ''' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.name) +''' AS ObjectName, COUNT(*) AS [RowCount]' + NCHAR(10) +
                   N'FROM ' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.[name]) + N';' + NCHAR(10)
            FROM sys.tables t
                 JOIN sys.schemas s ON t.SCHEMA_ID = s.SCHEMA_ID
            FOR XML PATH(N''))

PRINT @SQL;
CREATE TABLE #Cnt (ObjectName sysname, [RowCount] int);
INSERT INTO #Cnt (ObjectName, [RowCount])
EXEC sp_executesql @SQL;

SELECT *
FROM #cnt;

DROP TABLE #cnt;

或者,您可以使用无文档化的过程sp_msforeachtable

代码语言:javascript
复制
CREATE TABLE #Cnt (ObjectName sysname, [RowCount] int);
INSERT INTO #Cnt (ObjectName, [RowCount])
EXEC sp_msforeachtable N'SELECT ''?'' AS ObjectName, COUNT(*) AS [RowCount]
FROM ?;';

SELECT *
FROM #cnt;

DROP TABLE #cnt;

但是,如果我没有记错的话,后一种方法实际上使用了CURSOR

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51262514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档