我正在编写脚本,我需要获取在该表上为服务器上的所有数据库创建的所有表记录计数和索引。 我能够实现这个功能,但我必须静态地提到数据库名称。
这是我正在使用的脚本
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个数据库中获取所有记录和索引名称。
但我如何动态地实现此功能,我不需要对数据库名称进行硬编码。
提前致谢
答案 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