昨天在寫語句的時候,遇到了一個現象,其實就是使用 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用法不清晰導致了……╮(╯_╰)╭~
為大家獻丑了
新聞熱點
疑難解答