检查值并返回结果的函数

Posted

技术标签:

【中文标题】检查值并返回结果的函数【英文标题】:Function to check value and returns result 【发布时间】:2021-08-28 10:58:50 【问题描述】:

我需要在 SQL 中创建函数来检查变量或参数中的数据,如下所示

@Category  as varchar(50)='ABC,DEF'
@Value as varchar(50)='1,2'

并将@Category 值与表中的类别进行比较,然后从参数返回匹配的值

JOB TABLE ---

JOB   CATEGORY
123   ABC
234   DEF
234   SSS

Select JobNo,FUNCTION(@Category,@Value,CATEGORY) from JOB 


FINAL RESULTS 

JOB   VALUE
123   1
234   2
234   0

如果类别匹配,则从参数返回值,否则返回 0。

【问题讨论】:

我正在使用 SQL Server “功能是出了名的慢”@GeorgeMenoutis,这是一个非常笼统的陈述而不是真的。写得不好的函数,多行函数很慢。例如,编写良好的内联表值函数通常非常快。 @Larnu 我撤回了我的评论,因为它确实太笼统了。不过,对于 OP 想要的,我认为加入一个小型主表仍然是可取的。 是的,带有一些外键约束的“验证表”在这里可以很好地工作。 这个问题完全不清楚:样本数据和预期结果是什么,你有什么查询要让这个函数进入? 【参考方案1】:

如果您不能使用 cmets 中提到的静态查找表(例如,映射可能需要基于应用程序提供的数据是动态的),那么这看起来像是一个表值参数的工作。

现在你有两个参数,但在我看来,参数中的值是相关的。也就是说,现在您有@category = 'ABC,DEF'@value = '1,2',但我认为您打算将逗号分隔的“类别”集中的每个“元素”与逗号分隔的“值”集中的“元素”相关联" 在同一个位置。

现在设计很脆弱,因为如果我使用这样的参数会发生什么:@category = 'ABC,DEF,GHI,JKL', @value = '1'?

因此,您可以使您的代码更持久,并使用在 cmets 中向您推荐的那种“基于连接”的查找表解决方案,方法是使用一个接受表值参数参数的函数。为此,您首先必须在数据库中创建表值参数作为类型。然后我们接受该类型的参数,并加入它。在下面的解决方案中,我“猜测”了 categoryvalue 的数据类型,根据您问题中的示例数据,这似乎是合理的。

另外,我保留了您解决方案的“结构” - 即,函数的编写方式可以单独“应用”到作业中的每一行。我们不必这样做。相反,我们可以只在函数内部执行整个查询(即,包括对job 表的连接),但也许您想对也有cateogry 列的其他表使用该函数?我不会尝试在这里猜测整体设计。但出于性能原因,我会将函数切换为内联表值函数(返回一行一列)而不是标量函数。

-- schema and data to match your question
create table dbo.job (job int, category char(3));
insert dbo.job(job, category) values (123, 'ABC'), (234, 'DEF'), (234, 'SSS');
go

-- solution
create type dbo.CategoryValues as table 
(
   category char(3) unique, 
   [value] int
);
go

create or alter function dbo.MapCategory(@category char(3), @map dbo.CategoryValues readonly) 
returns table as return
(
   select [value] from @map where category = @category
);
go

-- to call the function we need to pass a parameter of type 
-- dbo.CategoryValues with the mappings we desire
declare @map dbo.CategoryValues;
insert @map values ('ABC', 1), ('DEF', 2)

-- outer apply the function to each row in the job table.
select      j.job, [value] = isnull(v.[value], 0)
from        dbo.job                             j
outer apply dbo.MapCategory(j.category, @map)   v

【讨论】:

以上是关于检查值并返回结果的函数的主要内容,如果未能解决你的问题,请参考以下文章

Access 中的自定义函数返回类型转换错误

如何获取 jQuery Confirm (jConfirm) 值并使用该值检查条件

excel满足多个条件后返回固定值并求和怎么用函数实现?

shell脚本调JAVA程序,获取JAVA程序返回值并echo输出

Javascript 在数组中搜索一个值并获取它的键

shell 脚本 变量 获取程序输出结果异常分析