如何在名称作为参数提供的用户定义函数中加入表?

Posted

技术标签:

【中文标题】如何在名称作为参数提供的用户定义函数中加入表?【英文标题】:How to join a table within a user defined function whose name is provided as parameter? 【发布时间】:2017-08-12 17:23:51 【问题描述】:

上下文

我的 SQL Server 数据库中有三个表:1) School、2) College、3) University。

然后我有另一个表:标签。

三个表(School、College、University)中的每一个都可以有与之关联的标签。为此,我有三个关联表:SchoolTags、CollegeTags、UniversityTags

问题

我正在尝试创建一个用户定义的函数,它将关联表的名称作为参数(即“SchoolTags”)和实体的 ID(学校/学院/大学),并将返回关联的标签列表使用那个 entityId

我遇到的问题是我必须将 Tags 与一个名称将作为参数传入的表连接起来。为此,我正在创建一个动态查询。而且我们不能在 SQL Server 用户定义的函数中运行动态查询。

问题

知道如何实现吗?

注意:我想要创建单独的关联表,并且不想将它们转换为通用关联表,并且我不想在我的函数中根据表名添加If-Else,这样如果一个新的关联表已创建,我不需要更新我的函数。

我正在使用 Microsoft SQL Server。

【问题讨论】:

用您正在使用的数据库标记您的问题。 您是否在每个关联表中使用identity int 作为PK? 【参考方案1】:

无论您使用哪种语言,您都可能会使用if

begin
    if table = 'school' then
    begin
        . . .
    end;
    else if table = 'college' then
    . . .
end;

确切的语法取决于您使用的数据库的脚本语言。

【讨论】:

【参考方案2】:

你想要的都是不可能的。您不能将表名作为参数传递给 UDF,然后在 UDF 中使用动态 sql 来创建和执行特定于作为参数传递的表的语句。您已经知道您别无选择,只能在 UDF 中使用 if-else 语句来实现您的目标 - 这是您的梦想:“当架构更改时,永远不必更新(或验证)您的代码”(是的 - 我改写它以使您的问题更加明显)这是一个问题。

可能还有其他方法可以实现一些有用的功能 - 但我建议您想得太远,并试图在没有明确目的的情况下实现通用功能。这是一条非常困难且容易出问题的路径,需要复杂的 tsql 技能。

并且要重新迭代先前的响应,您遇到了架构问题。您特意创建了三个不同的实体 - 现在您想要一个通用函数与它们中的任何一个一起使用。因此,在您花很多时间在这个特定方面之前,您应该花一些时间仔细考虑您打算如何使用(即,针对这些表编写查询)。如果您发现自己经常使用联合将这些实体组合成一个公共结果集,那么您的实际业务与其模型(模式)之间可能存在不匹配。

【讨论】:

【参考方案3】:

考虑在 one EducationInstitution 表和 one JoinEducTags 表的相关逻辑分组中规范化您的数据库。这些表听起来像它们保持相同的结构但具有不同的类型,因此应该将 SchoolCollege 保存在一个具有不同 Type 字段的表中, 大学

然后,为所有三个集合之间的一对多关系添加必要的约束、主键/外键:

您永远不想为每种新类型不断重构架构(即添加表)。使用这种方法,您的用户定义函数只需要接收值参数而不是标识符,例如要在动态查询中运行的表。最后,这种方法可以通过有效的存储更好地扩展。正如您将看到的,规范化节省了复杂的查询。

【讨论】:

我完全同意你的观点,但不幸的是我不想在这个阶段更改架构。 为什么不呢?根据您的说明,您计划使用其他机构表和标签表更改架构(添加表)?您是否有大型代码库会发生变化。现在真的要注意这一点,而不是在路上头疼。合并所有表并创建表并不难。

以上是关于如何在名称作为参数提供的用户定义函数中加入表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 3 中加入表并计算记录?

在数据库架构中加入表?

如何在用户定义的函数中将数据库列作为参数传递?

如何在vbScript中加扰函数名称[关闭]

函数如何将数组或设置值作为 PostgreSQL 中用户定义函数的参数 (IN)

我如何在控制器函数中加载目录作为视图:Codeigniter