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

SQL查询以运行对所有数据库的查询,sql,sql-server,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 @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
declare@TableList表(Id int-IDENTITY(1,1)、DataBaseName-VARCHAR(100)、TableName-VARCHAR(100)、RecordCount-int、nameofinex-VARCHAR(100)、TypeOfIndex-VARCHAR(100))
声明@TableListWithIndex表(Id int-IDENTITY(1,1)、数据库名VARCHAR(100)、表名VARCHAR(100)、索引名VARCHAR(100)、索引类型VARCHAR(100))
插入@TableList(数据库名、表名、记录计数)
选择“DBNAME1”,T.name作为[表名],
I.行作为[行计数]
从DBNAME1.sys.tables中选择T
内部连接DBNAME1.sys.sysindex作为I
在T.object_id=I.id上
I.indid<2
按I.rows DESC订购
插入@TableListWithIndex(数据库名、表名、索引名、索引类型)
挑选
“DBNAME1”,
TableName=t.name,
IndexName=ind.name,
指示类型描述
从…起
DBNAME1.sys.ind索引
内连接
ind.object\u id=ic.object\u id和ind.index\u id=ic.index\u id上的DBNAME1.sys.index\u列
内连接
ic.object\u id=col.object\u id和ic.column\u id=col.column\u id上的DBNAME1.sys.columns列
内连接
ind.object\u id=t.object\u id上的DBNAME1.sys.tables t
哪里
ind.is_primary_key=0
并且ind.is_unique=0
ind.is_unique_constraint=0
t.is_ms_装运=0
订购人
t、 名称,ind.name,ind.index\u id,ic.index\u列\u id
END——对于DBNAME1
更新TL
设置TL.NameOfIndex=TLW.NameOfIndex,TL.TypeOfIndex=TLW.TypeOfIndex
来自@TableList TL
TL.TableName=TLW.TableName上的内部联接@TableListWithIndex TLW
和TL.DataBaseName=TLW.DataBaseName
从@TableList中选择*按Id排序
所以对于Database2,我必须在update语句上面编写完整的代码。。以便从2数据库中获取所有记录和索引名

但是我如何动态地实现这个功能,而不需要硬编码数据库名称


提前感谢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
declare@ds-nvarchar(22);
声明@qry nvarchar(最大值);
set@ds='KaamKaaj';
将@qry=N'选择''+@ds+''作为数据库名,将T.name作为[表名],
I.行作为[行计数]
FROM@ds.sys.tables AS T
内部连接@ds.sys.sysindex作为I
在T.object_id=I.id上
I.indid<2
按I.rows DESC'排序;
设置@qry=REPLACE(@qry,@ds,@ds)
打印@qry;
声明@TableList表(Id int IDENTITY(1,1),DataBaseName VARCHAR(100),TableName VARCHAR(100),RecordCount int,nameofinex VARCHAR(100),TypeOfIndex VARCHAR(100))
插入@TableList(数据库名、表名、记录计数)
执行官(@qry
);
声明@qry2 nvarchar(最大值);
设置@qry2=N'选择
''++@ds+''作为数据库名,
t、 名字,
姓名,
指示类型描述
从…起
@ds.sys.ind索引
内连接
@ind.object\u id=ic.object\u id和ind.index\u id=ic.index\u id上的ds.sys.index\u列
内连接
@ic.object\u id=col.object\u id和ic.column\u id=col.column\u id上的ds.sys.columns列
内连接
@ind.object\u id=t.object\u id上的ds.sys.tables t
哪里
ind.is_primary_key=0
并且ind.is_unique=0
ind.is_unique_constraint=0
t.is_ms_装运=0
订购人
t、 名称,ind.name,ind.index\u id,ic.index\u列\u id
';
设置@qry2=REPLACE(@qry2,@ds',@ds)
声明@TableListWithIndex表(Id int-IDENTITY(1,1)、数据库名VARCHAR(100)、表名VARCHAR(100)、索引名VARCHAR(100)、索引类型VARCHAR(100))
插入@TableListWithIndex(数据库名、表名、索引名、索引类型)
执行官(@qry2)
);
从@TableList中选择*
从@TableListWithIndex中选择*

为了不使用循环,我想用一种非循环的方法来解决这类问题,而之前发布的代码将是一种自然的进展。注意,我不得不将表的数据类型更改为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

您必须使用动态sql。从sys.databases开始,获取所有数据库的列表。是的,我知道。。但问题是数据库名作为变量..谷歌和了解动态SQL。非常感谢..,我已经编辑了脚本的其余部分。。在你的代码的帮助下,它运行得非常完美:)对不起,我来晚了