以表和列列表为参数的SQL函数

时间:2018-10-05 20:05:44

标签: sql-server function constraints

我有一个带有许多映射表的数据库。

每个映射表都包含一组键列,一个映射值和一个适用映射的日期范围。

例如

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
)

我在这里吗?我宁愿走这条路,因为这样就不必为每个表创建函数了。

1 个答案:

答案 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
  )