昨天在寫語句的時(shí)候,遇到了一個(gè)現(xiàn)象,其實(shí)就是使用 Cross Apply做一個(gè)拼接字符串的而已。比如
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, 1,'香蕉') ,(3, 2,'足球') ,(4, 2,'籃球')SELECT a.*, STUFF(B.GoodName,1,1,'') 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 GoodName1 水果 蘋果-香蕉2 體育用品 足球-籃球*/
很平常是吧?但是如果在GoodsCatalog 表里面添加多2條數(shù)據(jù)呢?就會(huì)變成這樣了。明明說好的 Cross Apply會(huì)將不返回生成結(jié)果集的行喔!!為啥還會(huì)這樣呢!?
INSERT INTO GoodsCatalog ( ID, Name )VALUES ( 3,'海鮮'),( 4,'衣服')SELECT a.*, STUFF(B.GoodName,1,1,'') 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 GoodName1 水果 蘋果-香蕉2 體育用品 足球-籃球3 海鮮 NULL4 衣服 NULL*/
-------------------------------------------這是描述我是一個(gè)逗比的分割線--------------------------------------------------------------------------------------------------------------
重新看了下聯(lián)機(jī)文檔里面的Apply 的用法
使用 APPLY 運(yùn)算符可以為實(shí)現(xiàn)查詢操作的外部表表達(dá)式返回的每個(gè)行調(diào)用表值函數(shù)。表值函數(shù)作為右輸入,外部表表達(dá)式作為左輸入。通過對右輸入求值來獲得左輸入每一行的計(jì)算結(jié)果,生成的行被組合起來作為最終輸出。APPLY 運(yùn)算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
就是說,無論是 Cross Apply 還是 Outer Apply 后面都是跟隨一個(gè)表值函數(shù),會(huì)與左邊的輸入表每一行進(jìn)行交叉。所以是否返回應(yīng)該看 ()里面的語句本身。
這里我又有疑問了,Goods 表里面沒有 3,4 的結(jié)果啊,為什么還能顯示。
這個(gè)就是函數(shù)的問題了。假如寫2個(gè)表值函數(shù)對比一下就很清晰了
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 RETURNENDCREATE FUNCTION TestTable(@GoodsCatalogID INT)RETURNS @TABLE TABLE( GoodName varchar(200))AS begin INSERT INTO @TABLE (GoodName) SELECT Name FROM Goods WHERE GoodsCatalogID = @GoodsCatalogID RETURNENDSELECT * FROM dbo.TestXML(3)/*GoodNameNULL*/SELECT * FROM dbo.TestTable(3)/*GoodName*/
一個(gè)有返回,另外一個(gè)沒有返回哦~~這個(gè)就知道為什么能交叉到值出來了吧。
--------------------------------------------------------------------------------------這是證明我不認(rèn)真的打臉分割線------------------------------------------------------------------------------------------------------------------------
發(fā)現(xiàn)了這個(gè)問題,純粹是因?yàn)閷?Apply用法不清晰導(dǎo)致了……╮(╯_╰)╭~
為大家獻(xiàn)丑了
新聞熱點(diǎn)
疑難解答
圖片精選