用于对所有数据库运行查询的SQL查询

时间:2015-07-23 19:03:10

标签: sql sql-server

我正在编写脚本,我需要获取在该表上为服务器上的所有数据库创建的所有表记录计数和索引。 我能够实现这个功能,但我必须静态地提到数据库名称。

这是我正在使用的脚本

declare @TableList TABLE(Id int IDENTITY(1,1),DataBaseName VARCHAR(100),TableName VARCHAR(100),RecordCount INT,NameOfIndex VARCHAR(100),TypeOfIndex VARCHAR(100))
declare @TableListWithIndex TABLE(Id int IDENTITY(1,1),DataBaseName VARCHAR(100),TableName VARCHAR(100),NameOfIndex VARCHAR(100),TypeOfIndex VARCHAR(100))

INSERT INTO @TableList(DataBaseName,TableName,RecordCount)

SELECT 'DBNAME1',T.name AS [TABLE NAME], 
       I.rows AS [ROWCOUNT] 
FROM   DBNAME1.sys.tables AS T 
       INNER JOIN DBNAME1.sys.sysindexes AS I 
               ON T.object_id = I.id 
                  AND I.indid < 2 
ORDER  BY I.rows DESC

INSERT INTO @TableListWithIndex(DataBaseName,TableName,NameOfIndex,TypeOfIndex)

SELECT 
     'DBNAME1',
     TableName = t.name,
     IndexName = ind.name,
     ind.type_desc
FROM 
     DBNAME1.sys.indexes ind 
INNER JOIN 
     DBNAME1.sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id 
INNER JOIN 
     DBNAME1.sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
INNER JOIN 
     DBNAME1.sys.tables t ON ind.object_id = t.object_id 
WHERE 
     ind.is_primary_key = 0 
     AND ind.is_unique = 0 
     AND ind.is_unique_constraint = 0 
     AND t.is_ms_shipped = 0 
ORDER BY 
     t.name, ind.name, ind.index_id, ic.index_column_id 

     END  --FOR DBNAME1

update TL
     SET TL.NameOfIndex = TLW.NameOfIndex,TL.TypeOfIndex = TLW.TypeOfIndex
     from @TableList TL
     INNER JOIN @TableListWithIndex TLW ON TL.TableName = TLW.TableName 
     AND TL.DataBaseName = TLW.DataBaseName

     select * from @TableList order by Id

因此对于Database2我必须在更新语句之上编写整个代码..以便从2个数据库中获取所有记录和索引名称。

但我如何动态地实现此功能,我不需要对数据库名称进行硬编码。

提前致谢

2 个答案:

答案 0 :(得分:1)

FOR MS SQL SERVER:我已经用一个表尝试了你的一个部分,我希望你也会为第二个表执行 对于动态查询,我们必须在一个变量中输出语句并从该变量中替换一些字符串然后执行它

declare @ds  nvarchar(22);
declare @qry  nvarchar(max);
set @ds = 'KaamKaaj';

set @qry = N' SELECT '''+ @ds + ''' as DBName , T.name AS [TABLE NAME], 
       I.rows AS [ROWCOUNT] 
FROM   @ds.sys.tables AS T 
       INNER JOIN @ds.sys.sysindexes AS I 
               ON T.object_id = I.id 
                  AND I.indid < 2 
ORDER  BY I.rows DESC';

SET @qry    =   REPLACE(@qry, '@ds', @ds)
print @qry;

declare @TableList TABLE(Id int IDENTITY(1,1),DataBaseName VARCHAR(100),TableName VARCHAR(100),RecordCount INT,NameOfIndex VARCHAR(100),TypeOfIndex VARCHAR(100))

INSERT INTO @TableList(DataBaseName,TableName,RecordCount)
exec(@qry
);

declare @qry2  nvarchar(max);

set @qry2 =  N'SELECT 
     '''+ @ds + ''' as DBName,
     t.name,
     ind.name,
     ind.type_desc
FROM 
     @ds.sys.indexes ind 
INNER JOIN 
     @ds.sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id 
INNER JOIN 
     @ds.sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
INNER JOIN 
     @ds.sys.tables t ON ind.object_id = t.object_id 
WHERE 
     ind.is_primary_key = 0 
     AND ind.is_unique = 0 
     AND ind.is_unique_constraint = 0 
     AND t.is_ms_shipped = 0 
ORDER BY 
     t.name, ind.name, ind.index_id, ic.index_column_id 

     ';
SET @qry2   =   REPLACE(@qry2, '@ds', @ds)

declare @TableListWithIndex TABLE(Id int IDENTITY(1,1),DataBaseName VARCHAR(100),TableName VARCHAR(100),NameOfIndex VARCHAR(100),TypeOfIndex VARCHAR(100))
INSERT INTO @TableListWithIndex(DataBaseName,TableName,NameOfIndex,TypeOfIndex)
exec(@qry2
);


select * from @TableList
select * from @TableListWithIndex

答案 1 :(得分:0)

仅仅为了不使用以前发布的代码的循环将是一个自然的进展,我想把这种类型的东西放在一个非循环的方法。注意我必须将表的数据类型更改为sysname,因为在某些情况下100个字符不够长。我还使用临时表而不是表变量,因此它将在动态sql的范围内。

if OBJECT_ID('tempdb..#TableList') is not null
    drop table #TableList

create table #TableList
(
    Id int IDENTITY(1,1)
    , DataBaseName sysname
    , TableName sysname
    , RecordCount INT
    , NameOfIndex sysname
    , TypeOfIndex sysname
)

declare @Database sysname
declare @SQL nvarchar(max) = ''

select @SQL = @SQL +
    'SELECT '''
         + name + ''', '
         + 't.name collate SQL_Latin1_General_CP1_CI_AS, '
         + 'ind.name collate SQL_Latin1_General_CP1_CI_AS, '
         + 'ind.type_desc collate SQL_Latin1_General_CP1_CI_AS '
    + 'FROM [' + name + '].sys.indexes ind '
    + 'INNER JOIN [' + name + '].sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id '
    + 'INNER JOIN [' + name + '].sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id '
    + 'INNER JOIN [' + name + '].sys.tables t ON ind.object_id = t.object_id '
    + 'WHERE '
         + 'ind.is_primary_key = 0 '
         + 'AND ind.is_unique = 0 '
         + 'AND ind.is_unique_constraint = 0 '
         + 'AND t.is_ms_shipped = 0 '
    + 'UNION ALL '
from sys.databases           

set @SQL = 'insert #TableList(DatabaseName, TableName, NameOfIndex, TypeOfIndex) ' + left(@SQL, LEN(@SQL) - 10)

exec sp_executesql @SQL

select *
from #TableList
order by DataBaseName, TableName, NameOfIndex