我有两个数据集:
匹配的键会定期更新,我想创建 Dog 数据集的视图(或实现相同目的的东西),它总是连接到 最新的 匹配键。此外,我需要能够内联引用它 - 就好像它是一个表。
查找表中的匹配更新通过其架构名称来区分,因此要获取最新的,我只需识别最新的架构名称并将其从查询中交换出来。
鉴于视图和表值函数都禁止动态 SQL,并且存储过程不能像表一样引用,我怎样才能仅用 SQL 来实现这一点?
查找表中的匹配更新通过其架构名称来区分,因此要获取最新的,我只需识别最新的架构名称并将其从查询中交换出来。
您可以使用视图来解决这个问题,但是每当新数据输入数据库时,您需要某种方法来更改它。
我假设每当创建新模式时,也会在该模式中创建一个新表,但表名及其列名始终相同。请注意,这个假设对于我即将提出的解决方案至关重要 - 该解决方案是使用 DDL 触发器侦听数据库级别的
create_table
事件来更改您的视图,以便它将引用新的模式创建表。
我所做的另一个假设是您已经拥有初始视图,或者您正在使用 SQL Server 2016 或更高版本(允许创建或更改语法)。
首先,让我们创建初始视图:
CREATE VIEW dbo.TheView
AS
SELECT NULL As Test
GO
然后,我添加了 DML 触发器,它根据新创建表的架构创建并执行动态
alter view
语句:
CREATE TRIGGER AlterViewWhenSchemaChanges
ON DATABASE
FOR CREATE_TABLE
AS
DECLARE @Sql nvarchar(max),
@NewTableName sysname,
@NewSchemaName sysname;
SELECT @NewSchemaName = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(255)'),
@NewTableName = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)');
-- We only want to alter the view when this specific table is created!
IF @NewTableName = 'TableName'
BEGIN
SELECT @Sql =
'ALTER VIEW dbo.TheView
AS
SELECT Col as test
FROM '+ QUOTENAME(@NewSchemaName) +'.'+ QUOTENAME(@NewTableName) +';'
EXEC(@Sql)
END
GO
这样,每当创建具有特定名称(在我的示例中为
TableName
)的新表时,视图都会更改为引用最后创建的TableName
(显然是在最新模式中创建的)。
测试脚本:
SELECT * FROM dbo.TheView;
GO
结果:
Test
NULL
使用表创建新架构
TableName
CREATE SCHEMA SchemaName
CREATE TABLE SchemaName.TableName (Col int);
GO
-- insert some data
INSERT INTO SchemaName.TableName(Col) VALUES (123);
-- get the data from the altered view
SELECT * FROM dbo.TheView
结果:
test
123