SQL Server中的常见TVF可以从不同的模式中获取结果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server中的常见TVF可以从不同的模式中获取结果相关的知识,希望对你有一定的参考价值。

我过去一个月一直在使用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函数

注意事项

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

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

您应始终在查询中对模式限定对象,因为您没有这样做,SQL Server首先在程序所在的同一模式中查找festivals,如果找不到,则检查dbo模式,如果在dbo中找不到它,提出错误。

在您的情况下,过程驻留在dbo模式中,因此只检查dbo模式以查找festivals

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

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

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

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

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

以上是关于SQL Server中的常见TVF可以从不同的模式中获取结果的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - where + TVF/SVF、交叉应用、T-SQL

Flink SQL 窗口表值函数 Window TVF 实战

为啥 MySQL 和 SQL Server 中的“模式”不同?

当表在不同的架构中时,如何从 SQL Server 导入所有带有 sqoop 的表?

为啥在事务范围内调用 SQL Server 2008 中的全文搜索失败?

具有不同所有者的 SQL Server 所有权链跨架构,用于从多个架构中选择视图