在 UDF 中声明表变量以输入表名作为参数

Posted

技术标签:

【中文标题】在 UDF 中声明表变量以输入表名作为参数【英文标题】:Declare table variable in a UDF to enter table name as a parameter 【发布时间】:2016-03-28 00:50:57 【问题描述】:

我正在处理一个查询并创建了一个函数来使用以下代码从outcomes 表中获取结果。

CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
RETURNS TABLE
AS
    RETURN
      SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
             + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
             + ' '
             + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
      FROM   outcomes
      WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 

上面代码的问题是我在执行过程中输入了什么参数都没有关系,只要我输入的参数是数据库中有效的表名,它总是给出结果。

现在我想知道是否可以创建一个参数来将表名输入到FROM 部分,这样只有当我输入outcomes 时才会显示结果。

我尝试使用以下代码声明一个表变量:

declare @ship_outcome table
(   final_work nvarchar(30)
)

insert into @ship_outcome (final_work)
select 
        left(ship, charindex(' ', ship) - 1) + ' ' + 
        replicate('*', charindex(' ', substring(ship, charindex(' ', ship) + 1, len(ship))) + 1 -2) + ' ' +
        reverse(left(reverse(ship), charindex(' ', reverse(ship)) - 1))
from outcomes
where charindex(' ', substring(ship, charindex(' ', ship) + 1, len(ship))) > 1;

select * from @ship_outcome

但是我不确定如何将表变量合并到 UDF 中。请帮忙。

【问题讨论】:

不清楚。您是否只想在@tbl = outcomes 时获得结果? 添加到WHERE' clause AND @tbl = '结果'` 在这种情况下,我建议你不要自己调用这个函数 @Prdp 是的,我打算仅在 @tbl = outcomes 时显示结果。顺便说一句,感谢您昨天提供的查询,这正是 UDF 创建的查询。 【参考方案1】:

您也可以在多语句表值函数中使用 IF 语句来实现结果,如下所述:-

CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
RETURNS @t table
(final_work nvarchar(30))
AS
begin
if @tbl = 'outcomes'
begin
      Insert into @t
      SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
             + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
             + ' '
             + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
      FROM   outcomes
      WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 
end
return
end

注意 - 多语句表值函数的性能对于大型记录来说是可怕的。建议在内联表值函数的 where 子句中使用 @tbl = 'outcomes' 来使用内联函数,例如 -

CREATE FUNCTION dbo.Shippad (@tbl NVARCHAR(30))
RETURNS TABLE
AS
    RETURN
      SELECT LEFT(ship, Charindex(' ', ship) - 1) + ' '
             + Replicate('*', Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) + 1 -2)
             + ' '
             + Reverse(LEFT(Reverse(ship), Charindex(' ', Reverse(ship)) - 1)) as final_work 
      FROM   outcomes
      WHERE  Charindex(' ', Substring(ship, Charindex(' ', ship) + 1, Len(ship))) > 1 and @tbl = 'outcomes'

【讨论】:

感谢您的解决方案。正如您提到的在WHERE 语句中添加条件,我是否只是通过添加AND @tbl = 'outcomes' 来做到这一点? 我在内联表值函数的where子句中添加了条件@tbl = 'outcomes'。请查看我的更新答案 您好,感谢您的更新。我刚刚注意到的另一件事是我猜begin 之后的insert 声明是必要的 是的,你是对的。我忘了输入插入语句。我已经更新了我的答案。

以上是关于在 UDF 中声明表变量以输入表名作为参数的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个以表名作为输入的简单存储过程

使用 Oracle 表作为输入参数编写 Oracle 存储过程

表名作为变量

在 azure synapse 存储过程中将表名作为参数传递时将查询结果分配给变量

如何从 Result 对象中获取 HBase 表名作为 mapreduce 参数?

如何根据表名作为输入在 PL/Sql 中动态创建记录