SQL Server中的常见TVF,用于从不同的模式中获取结果

时间:2017-12-16 06:04:57

标签: sql-server database sql-server-2012 database-schema

过去一个月我一直在使用SQL Server,我需要SQL Server人员的建议来帮助我解决这个用例。

以下表格只是为了解释我正在寻找的想法。

我有不同架构的表格,如下所示:

MyDb.dbo.Festivals
MyDb.India.Festivals
MyDb.China.Festivals
MyDb.USA.Festivals

我正在编写一个表值函数,其中没有任何模式前缀,如

CREATE FUNCTION getFestivals()
RETURNS TABLE
AS
    RETURN
       (SELECT * FROM festivals)

由于我尚未应用任何架构,因此默认为dbo,并将TVF创建为dbo.getFestivals()。现在我已经为所有其他模式创建了同义词

CREATE SYNONYM India.getFestivals FOR dbo.getFestivals; 
CREATE SYNONYM USA.getFestivals FOR dbo.getFestivals; 

我尝试查询

SELECT * 
FROM MyDb.India.getFestivals()

并返回dbo.festivals而不是india.festivals的节日。

我理解虽然是同义词,但我们创建它只是在dbo架构上下文而不是india架构上下文中执行select查询。

我想知道如何设置一个公共表值函数,该函数将根据前缀的模式进行查询,即MyDB.India.getFestivals()应该从印度获得节日,而MyDB.USA.getFestivals()应该返回来自美国的节日。

问题

  1. 有没有办法让我可以根据架构上下文查询表值函数。

  2. 我能想到的唯一可行方法是在所有模式中创建相同的TableValue函数

  3. 注意事项

    1. 我必须坚持使用表值函数,上面的用例是解释我的问题的示例场景

1 个答案:

答案 0 :(得分:0)

  

我理解虽然是同义词,但我们创建它只是执行   dbo架构上下文中的select查询,而不是india架构中的select查询   上下文。

您应该总是在查询中对对象进行构建限定,因为您没有这样做,SQL Server首先在过程所在的同一模式中查找festivals,如果找不到dbo模式如果在dbo中找不到,则会检查错误。

在您的案例中,过程驻留在dbo架构中,因此仅检查dbo架构以查找festivals

如果创建了许多“类似”表而不是一个表,那么设计可能是错误的,你能将它们全部合并到一个表中,添加country_id来区分国家吗?

如果没有,你至少可以在每张桌子上添加这个字段吗?如果是这样,只需在每个表中添加国家/地区的字段,在此字段上添加检查约束以反映每个表中存储的唯一国家/地区,然后在您的函数中使用partitioned view

Partitioned view是由一些具有相同结构的表的union all组成的视图,每个表都在同一列上具有检查约束,该列定义了此列所限制的值。当您将此视图与国家/地区列上的过滤器一起使用时,由于此列上定义了check constraint,因此执行计划中将删除除正确之外的所有表。

所以你可以改变你的函数来接受唯一的参数是country,它只会读取一个与传递的参数对应的表。

有关分区视图的更多信息:Using Partitioned Views