【问题标题】:SQL Server 2014 Dynamic SQLSQL Server 2014 动态 SQL
【发布时间】:2015-08-13 01:48:38
【问题描述】:

请看一下代码并在最后一部分帮助我,--put all together = fail !!!

我想生成一个字符串来执行sp_executesql,但最后我得到了一个错误。我也试过打开光标,但它也出错了。

基本上,我试图获取所有表的每列每列的实际行数 因为如果添加和填充了新列,一般行数会告诉你。

USE AdventureWorks2014
GO
-- Create view to hold the dataset
Alter view vColumnSchema
AS
with myColumnName
As
(
Select      TOP (100) PERCENT 
            GetDate() As create_date,
            @@SERVERNAME As Server_Name,
            DB_Name() AS database_name,
            c.[object_id],
            s.name AS [schema_name],                      
            t.name as table_name,
            c.name as column_name,
            p.rows AS NUM_ROWS,
            c.[precision]                                     
from        sys.tables as t
INNER JOIN  sys.columns as c with(nolock) on t.[object_id] = c.[object_id]
INNER JOIN  sys.indexes AS i ON t.object_id = i.object_id 
INNER JOIN  sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id 
INNER JOIN  sys.schemas AS s ON s.schema_id = t.schema_id
WHERE       t.name NOT LIKE 'dt%' 
AND         i.object_id > 255 
AND         i.index_id <= 1
And         s.name is not null
Order by    s.name,
            t.name       
)
Select      Top 100 percent 
            create_date,
            Server_Name,
            database_name, 
            [schema_name],
            table_name,
            column_name,
            NUM_ROWS,
            case when precision = 0 then
            'Select Count('+column_name+')'+' from ' +[schema_name]+'.'+table_name+ ' where '+column_name+'<> '''' '  
            else 
            'Select Count(' +column_name+')'+' from ' +[schema_name]+ '.'+table_name+' where '+column_name+'> 0'   
            END as ColumnCount,
            case when precision = 0 
            then ' <> '''' '    
            Else '> 0' 
            END As WhereClause                  
from        myColumnName
Order by    [schema_name],
            table_name


GO
select * from vColumnSchema 
where table_name = 'ProductCostHistory'
go

select * from Production.ProductCostHistory -- 395 records
--pick one record and test it = pass
Select Count(EndDate) from Production.ProductCostHistory where EndDate<> '' --200 records

GO
--test = pass on both whereClause
Declare @Column_name nvarchar(50) = 'EndDate' 
Declare @Schema_Name nvarchar(20) = 'Production'
declare @table_name nvarchar(50)  = 'ProductCostHistory'
declare @whereClause nvarchar(5) =  '<> '''' ' 
declare @sqltext nvarchar(max) ='
select count('+@Column_name+') as ColumnCount from ' +@Schema_Name+'.'+@table_name+' where '+@Column_name+' '+@WhereClause+'
'
EXECUTE sp_executesql @sqltext 
GO
--examine each column = pass
Declare @Column_name nvarchar(50) = 'select Column_name from vColumnSchema'
EXECUTE sp_executesql @Column_name
GO
Declare @schema_name nvarchar(50) = 'select schema_name from vColumnSchema'
EXECUTE sp_executesql @schema_name
GO
declare @table_name nvarchar(50)  = 'select table_name from vColumnSchema'
EXECUTE sp_executesql  @table_name
GO
declare @WhereClause nvarchar(50)  = 'select WhereClause from vColumnSchema'
EXECUTE sp_executesql  @WhereClause 
GO
--put all together = fail !!!
declare @Column_name nvarchar(50) = 'select Column_name from vColumnSchema'
declare @schema_name nvarchar(50) = 'select schema_name from vColumnSchema'
declare @table_name nvarchar(50)  = 'select table_name from vColumnSchema'
declare @WhereClause nvarchar(5)  = 'select WhereClause from vColumnSchema';
declare @sqltext nvarchar(max)    ='
select count('+@Column_name+') as ColumnCount from ' +@Schema_Name+'.'+@table_name+' where '+@Column_name+' '+@WhereClause+' 
'
EXECUTE sp_executesql @sqltext
go

【问题讨论】:

  • 不要执行最后的@sqltext,而是尝试打印它。你会看到它变成了无法执行的东西。

标签: sql sql-server dynamic sql-server-2014


【解决方案1】:

如果你想要每个表每列的行数:

DECLARE @sql NVARCHAR(MAX) = '';

SELECT @sql = @sql +
N'SELECT '''
    + t.name + ''' AS TableName, ''' 
    + c.name + ''' AS ColName, COUNT(' + QUOTENAME(c.name) + ') AS [RowCount] FROM ' 
    + QUOTENAME(t.name) + ' UNION ALL' + CHAR(10)       
FROM sys.tables t
INNER JOIN sys.columns c
    ON c.object_id = t.object_id
WHERE
    t.type = 'U'
    AND c.system_type_id <> 35


SELECT @sql = LEFT(@sql, LEN(@sql) - 11)

PRINT @sql
EXECUTE sp_executesql @sql

【讨论】:

  • 感谢您的回复,但它产生与分区行号相同的结果,显示所有列具有相同的计数
【解决方案2】:

不确定你的最终游戏是什么但这可能会有所帮助并且不使用动态 sql ...

您可以在不使用 CTE 的情况下将列数放入原始查询中 这会将 col 计数放入原始选择中

Select      TOP (100) PERCENT 
            GetDate() As create_date,
            @@SERVERNAME As Server_Name,
            DB_Name() AS database_name,
            c.[object_id],
            s.name AS [schema_name],                      
            t.name as table_name,
            c.name as column_name,
            p.rows AS NUM_ROWS,
            c.[precision] ,
            (Select COUNT(c2.object_id) 
               FROM sys.columns c2 
              INNER JOIN sys.tables t2 ON t2.object_id = c2.object_id 
              WHERE t2.object_id = t.object_id 
              GROUP BY c2.object_id)  as ColCountThisTbl                                     
from        sys.tables as t
INNER JOIN  sys.columns as c with(nolock) on t.[object_id] = c.[object_id]
INNER JOIN  sys.indexes AS i ON t.object_id = i.object_id 
INNER JOIN  sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id 
INNER JOIN  sys.schemas AS s ON s.schema_id = t.schema_id
WHERE       t.name NOT LIKE 'dt%' 
AND         i.object_id > 255 
AND         i.index_id <= 1
And         s.name is not null
Order by    s.name,
            t.name `enter code here`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    相关资源
    最近更新 更多