SQL 服务器中的通用 TVF 从不同模式获取结果

Common TVF in SQL Server to get results from different schema

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

下面的table只是为了解释我正在寻找的想法。

我在不同的架构中有 tables:

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

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

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()

它 return 是 dbo.festivals 而不是 india.festivals 的节日。

我知道虽然是同义词,但我们创建它只是在 dbo 模式上下文中而不是在 india 模式上下文中执行 select 查询。

我想要关于如何拥有一个通用 table 值函数的建议,该函数将根据前缀模式进行查询,即 MyDB.India.getFestivals() 应该从印度获取节日,MyDB.USA.getFestivals() 应该 return 来自美国的节日。

问题

  1. 有什么方法可以让我得到一个 table 值函数,它可以根据架构上下文进行查询。

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

注意事项

  1. 我只能坚持使用 table 值函数,上面的用例是解释我的问题的示例场景

I understand that though the synonyms, we've created it just executes the select query in the dbo schema context and not in india schema context.

您应该始终在查询中对对象进行架构限定,因为您没有这样做,SQL 服务器首先在过程所在的同一架构中查找 festivals,如果找不到则dbo 架构已检查,如果在 dbo 中也未找到,则会引发错误。

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

如果创建了很多"similar" table而不是一个table可能是错误的设计,你能不能把它们合并成一个table加上country_id区分国家?

如果没有,您至少可以将此字段添加到每个 table 吗?如果是这样,只需在每个 table 中添加国家字段,在此字段上添加检查约束以反映存储在每个 table 中的唯一国家,然后在您的 partitioned view 中使用功能。

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

所以你可以改变你的函数来接受唯一的参数,即国家,它只会读取一个 table 对应于传递的参数。

更多关于分区视图的信息:使用分区视图