我有两个数据集:
匹配键会定期更新,我想创建一个Dog数据集的视图(或具有相同目的的东西),该数据集始终连接到最新匹配键上。此外,它可以像表一样被内联引用。
查找表中的匹配更新由它们的架构名称区分,因此要获取最新的名称,我只需要标识最新的架构名称并将其交换出查询即可。
鉴于视图和表值函数均禁止动态SQL,并且不能像表一样引用存储过程,这是怎么能仅用SQL来实现的呢?
答案 0 :(得分:2)
查找表中的匹配更新因其架构名称而有所不同,因此,要获取最新的名称,我只需标识最新的架构名称并将其交换出查询即可。
您可以使用视图解决此问题,但是每当将新数据输入数据库时,都需要某种更改方法。
我假设每当创建一个新的架构时,也会在该架构中创建一个新表,但是表名和它的列名总是相同的。请注意,此假设对我将要提出的解决方案至关重要-该解决方案是使用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 '+ @NewSchemaName +'.'+ @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