【问题标题】:How to return empty row from sql function if no record is found如果找不到记录,如何从 sql 函数返回空行
【发布时间】:2013-08-06 06:29:55
【问题描述】:

我有以下 SQL 函数

ALTER FUNCTION FunctionTEST (@itemID bigint) RETURNS table AS RETURN 
(
  (SELECT top 1 Pic_Path from PictureDetails WHERE PictureDetails.Item_ID = @itemID)
)

如果根据指定的参数找到该函数,该函数将返回第一行。如果没有针对参数找到记录,我希望此函数返回空行。我认为这应该是一个简单的任务,但我不熟悉 SQL 函数。下面是我用来调用函数的实际查询。

SELECT
NewClientTB.FirstName, NewClientTB.LastName, NewClientTB.EMail, NewClientTB.ContactNo,

ADDetails.AD_ID, ADDetails.AD_EXactAddress, 
ADDetails.AD_PostingTime, ADDetails.AD_Description, ADDetails.AD_Title,

ItemDetails.Item_ID, ItemDetails.Item_Price,

Regions.R_Description,

Cities.C_Name,

GCategories.GC_Description,

SCategories.SC_Description,
PictureDetails.Pic_Path

FROM NewClientTB, ADDetails,ItemDetails, Regions, Cities, GCategories, 
SCategories,     PictureDetails
WHERE FREETEXT (ADDetails.AD_Title, 'selling')
 AND FREETEXT (ADDetails.AD_Description, 'selling')
AND ADDetails.AD_PosterID = NewClientTB.UserID
AND ADDetails.AD_ID = ItemDetails.AD_ID
AND Regions.R_ID = ADDetails.AD_Region
AND Cities.R_ID = ADDetails.AD_Region AND Cities.C_ID = ADDetails.AD_City

AND ItemDetails.Item_GCategory = GCategories.GC_ID
AND ItemDetails.Item_SCategory = SCategories.SC_ID AND ItemDetails.Item_GCategory = 
SCategories.GC_ID
AND PictureDetails.Pic_Path =  (select * from dbo.FunctionTEST(ADDetails.AD_ID))

【问题讨论】:

  • 为什么要它返回一个空行?如所写,它返回一个没有行的表,这是有道理的。鉴于您最多只返回一个值,您确定要使用表值函数而不是标量函数吗?
  • 我正在修改上面的问题,请过一分钟看看
  • 空行是什么意思?所有列值都设置为空的行?这个函数返回一个空表,你可以把它当成“空行”,有意义
  • 我的意思是如果项目 (@itemID) 存在但没有针对它的 Pic_Path,那么它应该返回空行,否则返回 Pic_Path 及其数据
  • @user2599269 。 . .您使用该功能的方式,它没有任何区别。如果有一行具有 NULL 值或根本没有行,则比较将失败。

标签: sql database sql-server-2008


【解决方案1】:

如果您需要在 item 存在但没有 Pic_Path 时不返回任何行:

ALTER FUNCTION FunctionTEST (@itemID bigint)
RETURNS table AS RETURN 
(
    SELECT top 1 Pic_Path
    from PictureDetails
    WHERE PictureDetails.Item_ID = @itemID and Pic_Path is not NULL
)

如果您不希望结果中没有Pic_Path 的项目的行,则应使用cross apply 调用上述函数,如果您希望在结果中包含此类行,则应使用outer apply

SELECT
    nctb.FirstName, nctb.LastName, nctb.EMail, nctb.ContactNo,
    addet.AD_ID, addet.AD_EXactAddress, addet.AD_PostingTime,
    addet.AD_Description, addet.AD_Title,
    idet.Item_ID, idet.Item_Price,
    r.R_Description,
    c.C_Name,
    gcat.GC_Description,
    scat.SC_Description,
    pdet.Pic_Path
FROM
    NewClientTB nctb
    join ADDetails addet on addet.AD_PosterID = nctb.UserID
    join ItemDetails idet on idet.AD_ID = addet.AD_ID
    join Regions r on r.R_ID = addet.AD_Region
    join Cities c on c.R_ID = addet.AD_Region AND c.C_ID = addet.AD_City
    join GCategories gcat on gcat.GC_ID = idet.Item_GCategory
    join SCategories scat on scat.SC_ID = idet.Item_SCategory
    cross apply dbo.FunctionTEST(addet.AD_ID) ft
    join PictureDetails pdet on pdet.Pic_Path = ft.Pic_Path
WHERE FREETEXT (addet.AD_Title, 'selling') AND FREETEXT (addet.AD_Description, 'selling')

【讨论】:

  • 它以两种方式提供相同的输出,但感谢您的帮助
  • 我认为它应该可以工作,尽管在我的调用查询中需要进行少量修改。谢谢
  • 是的,这似乎是应用我无法对自己进行的连接的标准方式。感谢这个有用的代码
猜你喜欢
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2015-02-14
相关资源
最近更新 更多