標籤:
昨天在寫語句的時候,遇到了一個現象,其實就是使用 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, 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條資料呢?就會變成這樣了。明明說好的 Cross Apply會將不返回產生結果集的行喔!!為啥還會這樣呢!?
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*/
-------------------------------------------這是描述我是一個逗比的分割線--------------------------------------------------------------------------------------------------------------
重新看了下聯機文檔裡面的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 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*/
一個有返回,另外一個沒有返回哦~~這個就知道為什麼能交叉到值出來了吧。
--------------------------------------------------------------------------------------這是證明我不認真的打臉分割線------------------------------------------------------------------------------------------------------------------------
發現了這個問題,純粹是因為對 Apply用法不清晰導致了……╮(╯_╰)╭~
為大家獻醜了
使用For XML PATH 會影響Cross Apply 返回