过去一个月我一直在使用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()
应该返回来自美国的节日。
问题
有没有办法让我可以根据架构上下文查询表值函数。
我能想到的唯一可行方法是在所有模式中创建相同的TableValue函数
注意事项
答案 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