为何自定义SQL函数返回NULL但相同查询语句可得到预期结果?
问题诊断与修复
你的函数调用返回NULL的核心原因是参数定义错误:
你声明@companyId VARCHAR时没有指定长度,在SQL Server中,这种情况下默认长度是1。这意味着你传入的完整UUID字符串'aceaea4b-e4d1-45ea-84f7-8ecda1a0b20e'会被自动截断成仅第一个字符'a',导致WHERE子句里的e.EntityChangedId = @companyId完全匹配不到数据,自然返回NULL——这和你修改返回类型无关,因为查询本身就没找到结果。
修复方案
最合理的修复是直接将参数类型与EntityChangedId的类型(UNIQUEIDENTIFIER)保持一致,同时返回类型也使用UNIQUEIDENTIFIER(因为ec.NewValue在这里是UUID值):
CREATE FUNCTION [dbo].[GetCallFrequencyIdAtDate](@companyId UNIQUEIDENTIFIER, @date DATETIME2) RETURNS UNIQUEIDENTIFIER AS BEGIN RETURN ( select top 1 ec.NewValue from Events e join EventChanges ec on e.Id = ec.EventId where e.EntityChangedId = @companyId and ec.FieldChanged = 'Company.CallFrequencyId' and e.EventDate <= @date order by e.EventDate desc ) END GO -- 调用时直接传入UUID(无需加引号,因为参数是UNIQUEIDENTIFIER类型) SELECT dbo.GetCallFrequencyIdAtDate(aceaea4b-e4d1-45ea-84f7-8ecda1a0b20e, '2022-07-11 15:32:00.0000000 +00:00')
如果你确实需要用字符串类型传递参数,必须指定足够容纳UUID的长度(36位),并在查询中转换类型:
CREATE FUNCTION [dbo].[GetCallFrequencyIdAtDate](@companyId VARCHAR(36), @date DATETIME2) RETURNS UNIQUEIDENTIFIER AS BEGIN RETURN ( select top 1 ec.NewValue from Events e join EventChanges ec on e.Id = ec.EventId where e.EntityChangedId = CAST(@companyId AS UNIQUEIDENTIFIER) and ec.FieldChanged = 'Company.CallFrequencyId' and e.EventDate <= @date order by e.EventDate desc ) END GO -- 调用时传入带引号的字符串 SELECT dbo.GetCallFrequencyIdAtDate('aceaea4b-e4d1-45ea-84f7-8ecda1a0b20e', '2022-07-11 15:32:00.0000000 +00:00')
补充说明
为什么之前修改返回类型没用?因为问题根源是参数被截断导致查询无结果,不管返回类型是VARCHAR还是UNIQUEIDENTIFIER,没有匹配的数据就只能返回NULL。只有修正参数定义,让查询条件能正确匹配到数据,才能得到预期结果。
内容的提问来源于stack exchange,提问作者Bassie
相关产品推荐
相关产品推荐

