在使用存儲過程的時候,有時候會需要傳一個列表型的參數,比如我想要查詢2013、2014、2015這三年的銷售記錄。通常的解決辦法是將傳進來的序列進行字符串拼接,並用逗號進行分隔,比如"2013,2014,2015",然后就需要一個將字符串進行拆分的function。
CREATE FUNCTION FNC_SPLIT(@MYSTR VARCHAR(500), @DELIMITER CHAR(1)) RETURNS @MYTBL TABLE (idx smallint, value varchar(8000)) AS BEGIN DECLARE @RET VARCHAR(500) DECLARE @INDEX INT DECLARE @COUNTER smallint --Get the first position of delimiter in the main string SET @INDEX = CHARINDEX(@DELIMITER,@MYSTR) SET @COUNTER = 0 --Loop if delimiter exists in the main string WHILE @INDEX > 0 BEGIN --extract the result substring before the delimiter found SET @RET = SUBSTRING(@MYSTR,1, @INDEX-1 ) --set mainstring right part after the delimiter found SET @MYSTR = SUBSTRING(@MYSTR,@INDEX+1 , LEN(@MYSTR) - @INDEX ) --increase the counter SET @COUNTER = @COUNTER + 1 --add the result substring to the table INSERT INTO @MYTBL (idx, value) VALUES (@COUNTER, @RET) --Get the next position of delimiter in the main string SET @INDEX = CHARINDEX(@DELIMITER,@MYSTR) END --if no delimiter is found then simply add the mainstring to the table IF @INDEX = 0 BEGIN SET @COUNTER = @COUNTER + 1 INSERT INTO @MYTBL (idx, value) VALUES (@COUNTER, @MYSTR) END RETURN END GO SELECT value FROM FNC_SPLIT('2013,2014,2015',',') GO DROP FUNCTION FNC_SPLIT
運行結果圖:
然后將得到的臨時表和數據表進行Join就能拿到想要的數據了。
這里介紹一種的方式:OPENXML,需要用到sp_xml_preparedocument和sp_xml_Removedocument這兩個存儲過程。
DECLARE @xml varchar(max) DECLARE @doc int SET @xml =' <?xml version="1.0" encoding="UTF-8"?> <Request> <Date Year="2013"/> <Date Year="2014"/> <Date Year="2015"/> </Request>' EXEC sp_xml_preparedocument @doc OUTPUT, @xml CREATE TABLE #Temp([Year] varchar(100)) INSERT INTO #Temp SELECT [Year] FROM OPENXML (@doc, '/Request/Date', 1) WITH (Year varchar(100)) EXEC sp_xml_Removedocument @doc SELECT * FROM #Temp Drop Table #Temp
運行結果圖:
結果和上面是一樣的,但是使用XML數據作為參數比拼接字符串要更靈活一些。
比如我傳入的XML是這樣的:
SET @xml =' <?xml version="1.0" encoding="UTF-8"?> <Request> <Date Year="2013" Date="10"/> <Date Year="2014" Date="10"/> <Date Year="2015" Date="10"/> </Request>'
我的臨時表就可以是這樣的:



