一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫(kù)技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫(kù) - Sql Server - 不固定參數(shù)的存儲(chǔ)過(guò)程實(shí)現(xiàn)代碼

不固定參數(shù)的存儲(chǔ)過(guò)程實(shí)現(xiàn)代碼

2019-12-01 13:58MSSQL教程網(wǎng) Sql Server

我們知道存儲(chǔ)過(guò)程是不支持不固定參數(shù)情況的(包括數(shù)組參數(shù)),可是有時(shí)候我們的參數(shù)又必須是不固定的,怎么辦呢?

我想此時(shí)不妨使用字符串參數(shù)來(lái)幫助我們解決這種情況,利用字符串分割的方法將一個(gè)參數(shù)分割成數(shù)個(gè)參數(shù)來(lái)解決。下面我們看一個(gè)例子: 

假設(shè)現(xiàn)在給你一個(gè)產(chǎn)品信息列表(顯示出各個(gè)商品的基本信息),現(xiàn)在我想要根據(jù)所選擇商品進(jìn)行統(tǒng)計(jì)(任意選擇幾種),例如統(tǒng)計(jì)出價(jià)格<10,11-20,21-30,31-40,41-50,50以上的商品個(gè)有多少個(gè)(姑且認(rèn)為就統(tǒng)計(jì)這些)。此時(shí)如果使用存儲(chǔ)過(guò)程就勢(shì)必需要傳入所選商品的id作為參數(shù),但是id個(gè)數(shù)是不固定的。此時(shí)估計(jì)會(huì)有人這樣寫: 

復(fù)制代碼代碼如下:


SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author: jianxin160 
-- Create date: 2010.11.05 
-- Description: 統(tǒng)計(jì)商品 
-- ============================================= 
ALTER PROCEDURE StatProductInfo 

@ids VARCHAR(8000) 

AS 
BEGIN 
DECLARE @followingTen INT 
DECLARE @elevenToTwenty INT 
DECLARE @twentyOneToThirty INT 
DECLARE @thirtyOneToFourty INT 
DECLARE @fourtyOneToFifty INT 
DECLARE @fiftyOrMore INT 

SELECT @followingTen=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice<10 

SELECT @elevenToTwenty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice BETWEEN 11 AND 20 

SELECT @twentyOneToThirty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice BETWEEN 21 AND 30 

SELECT @thirtyOneToFourty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice BETWEEN 31 AND 40 

SELECT @fourtyOneToFifty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice BETWEEN 41 AND 50 

SELECT @fiftyOrMore=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(@ids) AND UnitPrice>50 

SELECT @followingTen AS '<$10',@elevenToTwenty AS '$11-$20', 
@twentyOneToThirty AS '$21-$30',@thirtyOneToFourty AS '$31-$40', 
@fourtyOneToFifty AS '$41-$50',@fiftyOrMore AS '>$50' 
END 
GO 


其實(shí)如果你測(cè)試一下(例如:EXEC dbo . StatProductInfo '3,4,8,10,22' )是有問(wèn)題的,sql server認(rèn)為這整個(gè)是一個(gè)參數(shù),轉(zhuǎn)換時(shí)出錯(cuò)。此時(shí)我們想一下如果這些字段在一個(gè)虛表中就容易操作多了,但是一般虛表是有其他表通過(guò)查詢得到,現(xiàn)在根本無(wú)法查詢又哪來(lái)的虛表呢?聰明的朋友或許已經(jīng)想到可以使用"表值函數(shù)"。對(duì),答案就是使用"表值函數(shù)"。我們知道"表值函數(shù)"可以返回一個(gè)"Table"類型的變量(相當(dāng)于一張?zhí)摫恚娣庞趦?nèi)存中),我們首先將字符串分割存放到"表值函數(shù)"的一個(gè)字段中,然后我們?cè)購(gòu)?quot;表值函數(shù)"中查詢就可以了(這個(gè)例子也是"表值函數(shù)"的一個(gè)典型應(yīng)用)。具體sql如下: 

復(fù)制代碼代碼如下:


SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author: cmj 
-- Create date: 2010.11.05 
-- Description: 返回一個(gè)Table,只有一列,每一行的數(shù)據(jù)就是分割好的字符串 
-- ============================================= 
CREATE FUNCTION GetSplitFieldsByString 

@toSplitString varchar(1000), 
@splitChar varchar(10) 

RETURNS 
@tb TABLE(sp varchar(100)) 
AS 
BEGIN 
DECLARE @i INT 
SET @toSplitString=RTRIM(LTRIM(@toSplitString)) 
SET @i=CHARINDEX(@splitChar,@toSplitString) 
WHILE @i>0 
BEGIN 
INSERT @tb VALUES(LEFT(@toSplitString,@i-1)) 
SET @toSplitString=RIGHT(@toSplitString,LEN(@toSplitString)-@i) 
SET @i=CHARINDEX(@splitChar,@toSplitString) 
END 
IF LEN(@toSplitString)>0 
INSERT @tb VALUES(@toSplitString) 
RETURN 
END 
GO 


然后我們稍微修改一下存儲(chǔ)過(guò)程: 

復(fù)制代碼代碼如下:


SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author: jianxin160 
-- Create date: 2010.11.05 
-- Description: 統(tǒng)計(jì)商品 
-- ============================================= 
ALTER PROCEDURE StatProductInfo 

@ids VARCHAR(8000) 

AS 
BEGIN 
DECLARE @followingTen INT 
DECLARE @elevenToTwenty INT 
DECLARE @twentyOneToThirty INT 
DECLARE @thirtyOneToFourty INT 
DECLARE @fourtyOneToFifty INT 
DECLARE @fiftyOrMore INT 

SELECT @followingTen=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice<10 

SELECT @elevenToTwenty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice BETWEEN 11 AND 20 

SELECT @twentyOneToThirty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice BETWEEN 21 AND 30 

SELECT @thirtyOneToFourty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice BETWEEN 31 AND 40 

SELECT @fourtyOneToFifty=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice BETWEEN 41 AND 50 

SELECT @fiftyOrMore=COUNT(*) 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) AND UnitPrice>50 

SELECT @followingTen AS '<$10',@elevenToTwenty AS '$11-$20',@twentyOneToThirty AS '$21-$30', 
@thirtyOneToFourty AS '$31-$40',@fourtyOneToFifty AS '$41-$50',@fiftyOrMore AS '>$50' 
END 
GO 


這樣通過(guò)執(zhí)行EXEC dbo . StatProductInfo '3,4,8,10,22' 就可以得到想要的結(jié)果了: 
不固定參數(shù)的存儲(chǔ)過(guò)程實(shí)現(xiàn)代碼
試試這樣會(huì)不會(huì)快一些 

復(fù)制代碼代碼如下:


SELECT SUM(CASE WHEN UnitPrice < 10 THEN 1 ELSE 0 END) '<$10', 
SUM(CASE WHEN UnitPrice BETWEEN 11 AND 20 THEN 1 ELSE 0 END) '$11-$20', 
SUM(CASE WHEN UnitPrice BETWEEN 21 AND 30 THEN 1 ELSE 0 END) '$21-$30', 
... 
SUM(CASE WHEN UnitPrice > 50 THEN 1 ELSE 0 END) '>$10' 
FROM dbo.Products 
WHERE ProductID IN(SELECT sp FROM dbo.GetSplitFieldsByString(@ids,',')) 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 香蕉精品 | yy111111影院理论大片 | 黑人日白人| 欧美一级片免费看 | 免费视频片在线观看 | 人人揉揉香蕉 | a v在线男人的天堂观看免费 | 99久久免费国内精品 | 疯狂伦交1一6 小说 风间由美在线 | 成人 在线欧美亚洲 | 亚洲国产成人在人网站天堂 | 91嫩草私人成人亚洲影院 | 9191视频 | 欧美日韩专区国产精品 | 久久久精品成人免费看 | 精品一久久香蕉国产线看播放 | 91欧洲在线视精品在亚洲 | 国产品精人成福利视频 | 亚洲AV 中文字幕 国产 欧美 | 国产va免费精品高清在线观看 | 俄罗斯美女毛茸茸bbwbbw | 成人曼画 | 99热精品久久 | 美日韩在线观看 | tube4欧美4| 粗暴hd另类另类 | 性鸥美 | 国产成人亚洲精品91专区手机 | 美女扒开粉嫩尿口漫画 | 午夜免费无码福利视频麻豆 | 和肥岳在厨房激情 | 好湿好滑好硬好爽好深视频 | 强女明星系列小说 | 3344在线看片 | 欧美成人中文字幕在线看 | 久久毛片免费看一区二区三区 | 亚洲国产精品无码中文字幕 | 亚洲欧美韩国日产综合在线 | 大伊香蕉精品视频一区 | 万域之王动漫在线观看全集免费播放 | 天天色踪合 |