我有一个带有许多映射表的数据库。
每个映射表都包含一组键列,一个映射值和一个适用映射的日期范围。
例如
mappingtable_a (
acol,
bcol,
ccol,
mapped,
startdate,
enddate
)
我可以通过以下方式使用
select
a.acol,
a.bcol,
a.ccol,
m.mapped
from
atable a left join
mappingtable_a m on (
a.acol = m.acol and
a.bcol = m.bcol and
a.ccol = m.ccol and
a.adate >= m.startdate and
a.adate <= m.enddate
)
我想对这些表进行约束检查,以确保映射列组合的日期范围绝不重叠。
如果我为约束所在的每个表创建了一个约束检查函数,那么对于单个表来说,这似乎相当简单。
function checkrange_mappingtable_a(
acol_value,
bcol_value,
ccol_value,
startdate_value,
enddate_value
) {
--find all date ranges for this combination in mappingtable_a
--verify the new range doesn't overlap
}
我想知道是否可以创建一个函数来处理所有映射表,而不是单独处理。
类似
function checkrange (
thetable,
columnlist,
valuelist,
startdate_value,
enddate_value
) {
--find all date ranges in thetable where columnlist=valuelist
--verify the new range doesn't overlap
}
然后可以为mappingtable_a
传递类似的信息。
checkrange(
'mappingtable_a',
['acol','bcol','ccol'],
[acol_value,bcol_value,ccol_value],
startdate_value,
enddate_value
)
我在这里吗?我宁愿走这条路,因为这样就不必为每个表创建函数了。
答案 0 :(得分:0)
不,您将无法创建一个一般可处理多个表的函数,因为这将需要动态sql,并且用户定义的函数中不允许动态sql。
替代方案:将所有映射日期范围放在一个表格中。由于相邻的表可能并不总是具有相同数量的键列,因此这意味着某些映射在某些键列中将具有NULL,但是无论如何您都将忽略该表的JOIN中的那些列。您还必须在映射表中添加TableName列,以使TableA / ColumnA映射与TableB / ColumnA映射分开,但是我认为这没什么大不了的。
因此,您将在一个表中拥有日期范围约束,并且可以像这样将任何表联接到该表:
select
a.acol,
a.bcol,
a.ccol,
m.mapped
from
atable a left join
mappingtable m on (
m.TableName = 'atable' and
a.acol = m.acol and
a.bcol = m.bcol and
a.ccol = m.ccol and
a.adate >= m.startdate and
a.adate <= m.enddate
)