如何从 UDF 参数提供 SELECT 语句的 FROM 子句

Posted

技术标签:

【中文标题】如何从 UDF 参数提供 SELECT 语句的 FROM 子句【英文标题】:How do I supply the FROM clause of a SELECT statement from a UDF parameter 【发布时间】:2008-12-08 16:30:36 【问题描述】:

在我正在移植到 Web 的应用程序中,我们目前在运行时根据指定的“模板”字符串在运行时动态访问不同的表。既然我们正在迁移到 SQL 服务器,我想将执行此操作的负担移回数据库,因此我不必弄乱动态 GridView。我想编写一个表值 UDF,其中一个参数用于表名,一个用于查询 WHERE 子句。

我为我的 UDF 输入了以下内容,但显然它不起作用。有什么方法可以获取某种类型的 varchar 或字符串并获得可以在 FROM 子句中使用的表引用?

CREATE FUNCTION TemplateSelector 
(   
@template varchar(40),
@code varchar(80)
)
RETURNS TABLE 
AS
RETURN 
(
SELECT * FROM @template WHERE ProductionCode = @code
)

或通过其他方式获得与此类似的结果集。基本上表中的所有记录都由 varchar @template 与 @code 的匹配 ProductionCode 指示。

我收到错误“必须声明表变量“@template””,因此 SQL 服务器可能是我试图从表变量中选择的东西。

编辑时:是的,我不需要在函数中执行此操作,我可以运行存储过程,我之前没有编写过任何一个。

【问题讨论】:

【参考方案1】:
CREATE PROCEDURE TemplateSelector 
(   
    @template varchar(40),
    @code varchar(80)
)

AS
EXEC('SELECT * FROM ' + @template + ' WHERE ProductionCode = ' + @code)

这可行,虽然它不是 UDF。

【讨论】:

危险会鲁滨逊!检测到sql注入! :P @Chris Lively - 好久不见!无论如何,你是怎么进入这个声名狼藉的工作的? 它对我有用。并且提供的模板值是从下拉列表中选择的,所以我认为它不能被注入 它肯定很容易受到 SQL 注入的影响,特别是如果它是一个 Web 应用程序。下拉菜单没有保护作用。【参考方案2】:

执行此操作的唯一方法是使用 exec 命令。

此外,您必须将其移出存储过程而不是函数。显然函数不能执行动态sql。

【讨论】:

要么,要么 sp_executesql。但是,是的,你是对的。您必须使用动态 SQL。【参考方案3】:

实现这一点的唯一方法是使用动态 SQL,但是,函数中的 SqlServer 不支持动态 SQL。

很抱歉,我很确定不可能在函数中执行此操作。

如果您使用的是存储过程,那将是可能的。

【讨论】:

【参考方案4】:

另外,应该注意的是,替换查询中的表名,破坏了 SQL Server 缓存查询执行计划的能力。这几乎将使用 UDF 或 SP 的优势降低到零。您不妨直接调用 SQL 查询。

【讨论】:

缓存执行计划的优势并不是 UDF 或 SP 的主要优势。【参考方案5】:

我希望能够处理的表数量有限,因此我可以使用 IF 编写一些东西,测试 @template 是否与多个值匹配,并为每个匹配运行

SELECT * FROM TEMPLATENAME WHERE ProductionCode = @code

听起来这是一个更好的选择

【讨论】:

如果你打算走这条路(这比动态 SQL 好一百倍)并且如果你将它封装在一个 SP 中而不是在前端进行测试,那么一定要对存储过程使用 WITH RECOMPILE 选项。由于缓存计划将关闭,其他性能可能会受到影响。【参考方案6】:

如果您有许多具有相同结构的表,这通常意味着您没有以正常形式设计数据库。您应该将这些统一到一张表中。您可能需要为该表多提供一个属性列来区分数据集。

【讨论】:

它们的结构不一样,都有ProductionCode和TestTime,但之后各有自己的数据

以上是关于如何从 UDF 参数提供 SELECT 语句的 FROM 子句的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SELECT 或 UPDATE 语句中使用 T-SQL UDF?

如何命名 UDF 的参数?

从标量 UDF 引用表 - 绑定到模式名称?

执行从 UDF 返回的语句时出现问题 - 没有结果集

在 SELECT 语句中使用 UDF

在 SQL SELECT 语句中未找到 UDF