微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用For XML PATH 会影响Cross Apply 返回

昨天在写语句的时候,遇到了一个现象,其实就是使用 Cross Apply做一个拼接字符串的而已。比如
CREATE TABLE GoodsCatalog 
(ID INT,Name NVARCHAR(50))    

CREATE TABLE Goods
(ID INT,GoodsCatalogID INT,Name NVARCHAR(50))  


INSERT INTO GoodsCatalog
        ( ID,Name )
VALUES  ( 1,'水果'),( 2,'体育用品')

INSERT INTO Goods
        ( ID,GoodsCatalogID,Name )
VALUES  (1,1,'苹果'),(2,'香蕉'),(3,2,'足球'),(4,'篮球')


SELECT a.*,STUFF(B.GoodName,'') AS GoodName
    FROM GoodsCatalog a
        CROSS APPLY (SELECT '-' + b.Name
                            FROM Goods b
                                WHERE b.GoodsCatalogID = a.ID FOR XML PATH('')) AS B(GoodName)
                             
/*
ID    Name    GoodName
1    水果    苹果-香蕉
2    体育用品    足球-篮球
*/

很平常是吧?但是如果在GoodsCatalog 表里面添加多2条数据呢?就会变成这样了。明明说好的 Cross Apply会将不返回生成结果集的行喔!!为啥还会这样呢!?

INSERT INTO GoodsCatalog
        ( ID,Name )
VALUES  ( 3,'海鲜'),( 4,'衣服')

SELECT a.*,'') AS GoodName
    FROM GoodsCatalog a
        CROSS APPLY (SELECT '-' + b.Name
                            FROM Goods b
                                WHERE b.GoodsCatalogID = a.ID FOR XML PATH('')) AS B(GoodName)

/* ID Name GoodName 1 水果 苹果-香蕉 2 体育用品 足球-篮球 3 海鲜 NULL 4 衣服 NULL */






-------------------------------------------这是描述我是一个逗比的分割线--------------------------------------------------------------------------------------------------------------

重新看了下联机文档里面的Apply 的用法

使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

就是说,无论是 Cross Apply 还是 Outer Apply 后面都是跟随一个表值函数,会与左边的输入表每一行进行交叉。所以是否返回应该看 ()里面的语句本身。

这里我又有疑问了,Goods 表里面没有 3,4 的结果啊,为什么还能显示

这个就是函数的问题了。假如写2个表值函数对比一下就很清晰了

CREATE FUNCTION TestXML
(@GoodsCatalogID INT)
RETURNS @TABLE TABLE
(
    GoodName varchar(200)
)
AS    
begin
    ;WITH CTE(GoodName) AS
    (SELECT '-' + Name FROM Goods
        WHERE GoodsCatalogID = @GoodsCatalogID FOR XML PATH(''))
    INSERT INTO @TABLE (GoodName)
    SELECT GoodName 
        FROM CTE
    RETURN
END

CREATE FUNCTION TestTable
(@GoodsCatalogID INT)
RETURNS @TABLE TABLE
(
    GoodName varchar(200)
)
AS    
begin
    INSERT INTO @TABLE (GoodName)
    SELECT  Name FROM Goods
        WHERE GoodsCatalogID = @GoodsCatalogID
    RETURN
END

SELECT *
    FROM dbo.TestXML(3)

/*
GoodName
NULL
*/


SELECT * 
    FROM dbo.TestTable(3)

/*
GoodName
*/

一个有返回,另外一个没有返回哦~~这个就知道为什么能交叉到值出来了吧。

--------------------------------------------------------------------------------------这是证明我不认真的打脸分割线------------------------------------------------------------------------------------------------------------------------

发现了这个问题,纯粹是因为对 Apply用法不清晰导致了……╮(╯_╰)╭~

为大家献丑了

原文地址:https://www.jb51.cc/xml/295265.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。