根据带通配符的列表创建表的动态列表

问题描述

所以我有一个我想要的表格列表(带通配符)

CREATE TABLE [config].[datalist](
    [id] [int] IDENTITY(1,1) NOT NULL,[order] [int] NULL,[dbname] sysname NULL,[schemaname] sysname NULL,[tablename] sysname NULL
) 
GO
SET IDENTITY_INSERT [config].[datalist] ON 
GO
INSERT [config].[datalist] ([id],[order],[dbname],[schemaname],[tablename]) VALUES (1,1,N'TEST',N'audit*',N'*')
GO
INSERT [config].[datalist] ([id],[tablename]) VALUES (7,2,N'conversie',N'BR')
GO
INSERT [config].[datalist] ([id],[tablename]) VALUES (8,3,N'datalibrary',N'T*')
GO
INSERT [config].[datalist] ([id],[tablename]) VALUES (9,N'BIML',N'*',N'*')
GO
SET IDENTITY_INSERT [config].[datalist] OFF
GO

SELECT  [id],[tablename]
  FROM [UITWISSEL].[config].[datalist]

给了我

id  order   dbname  schemaname  tablename
1   1   TEST    audit*  *
7   2   TEST    conversie   BR
8   3   TEST    datalibrary T*
9   3   BIML    *   *

现在我需要的是表 config.datalist

中提到的所有表的列表

所以我想要一个列表:

id 1) 数据库 TEST 中架构名以 audit 开头的所有表

id 7) 架构 TEST数据库 conversie名称BR 的所有表

id 8) 模式“datalibrary”中数据库 TEST名称T 开头的所有表

id 9) 数据库 BIML 中所有模式的所有表

我有以下代码,但我这仅适用于数据库 BIML。 如何让这段代码适用于 config.datalist.dbname 中提到的所有数据库

select distinct  t.name as TableName,'SELECT  * FROM ' + quotename(replace(replace(ds.[dbname],'[',''),']',''))+'.'+
quotename(s.name)+'.'+
quotename(t.name) AS selectquery,s.name as schemaname,ds.[order]
from BIML.sys.schemas s
left join BIML.sys.tables t on s.schema_id = t.schema_id  
inner join [UITWISSEL].[config].[datalist] ds on s.name like  replace(ds.schemaname,'*','%') COLLATE DATABASE_DEFAULT
inner join [UITWISSEL].[config].[datalist] dt on t.name like  replace(ds.tablename,'%') COLLATE DATABASE_DEFAULT
order by ds.[order],s.name,t.name

给了我

TableName   selectquery schemaname  order
connections SELECT  * FROM [BIML].[config].[connections]    config  3
FilesToImport   SELECT  * FROM [BIML].[config].[FilesToImport]  config  3

解决方法

假设您正在对语句进行参数化以获取表列表,那么您可以这样做:

DECLARE @ListID int = 8; --Your parameter

DECLARE @SQL nvarchar(MAX),@CRLF nchar(2) = NCHAR(13) + NCHAR(10);

DECLARE @DatabaseName sysname,@SchemaName sysname,@TableName sysname;

SELECT @DatabaseName = REPLACE(dbname,'*','%'),@SchemaName = REPLACE(schemaname,@TableName = REPLACE(tablename,'%')
FROM config.datalist
WHERE id = @ListID;

SET @SQL = N'SELECT s.[name] AS SchemaName,' + @CRLF +
           N'       t.[name] AS TableName' + @CRLF +
           N'FROM ' + QUOTENAME(@DatabaseName) + N'sys.schemas s' + @CRLF + 
           N'     JOIN ' + QUOTENAME(@DatabaseName) + N'sys.tables t ON s.schema_id = t.schema_id' + @CRLF +
           N'WHERE s.[name] LIKE @SchemaName' + @CRLF +
           N'  AND t.[name] LIKE @TableName;';

PRINT @SQL;
--EXEC sys.sp_executesql @SQL,N'@SchemaName sysname,@TableName sysname',@SchemaName,@TableName; --Uncomment to run
,
declare @i as int = 1
declare @db_list table (id int identity(1,1),dbname sysname,[order] int)
declare @resultlist table ([order] int,schemaname sysname,tablename sysname,selectquery  nvarchar(4000))
declare @act_dbname sysname
declare @act_order int =1
declare @sql as nvarchar(4000)

insert into @db_list 
select distinct dbname,[order] from UITWISSEL.[config].[datalist] order by [order]

while @i <= (select max(id) from @db_list)
BEGIN

set @act_dbname = (select dbname from @db_list where id = @i)
set @act_order = (select [order] from @db_list where id = @i)
set @sql = '

select distinct  
'+ cast(@act_order as varchar(4)) + ' as [order],'''+ @act_dbname +''' as dbname,s.name as schemaname,t.name as tablename,''SELECT  * FROM '' + quotename('''+ @act_dbname + ''')+''.''+
    quotename(s.name)+''.''+
    quotename(t.name) 
AS selectquery 

from  '+ @act_dbname + '.sys.schemas s  
left join '+ @act_dbname + '.sys.tables t on s.schema_id = t.schema_id  
inner join [UITWISSEL].[config].[datalist] ds on s.name like  replace(ds.schemaname,''*'',''%'') COLLATE DATABASE_DEFAULT
inner join [UITWISSEL].[config].[datalist] dt on t.name like  replace(ds.tablename,''%'') COLLATE DATABASE_DEFAULT
order by [order],s.name,t.name
'
print  @sql 
insert into @resultlist exec sp_executesql @sql
set @i = @i+1
END

select * from @resultlist order by [order],schemaname,tablename