SQLServer數(shù)據(jù)庫(kù)游標(biāo)的具體使用
游標(biāo)是一種用來(lái)遍歷數(shù)據(jù)庫(kù)結(jié)果集的機(jī)制,它允許用戶逐行處理查詢結(jié)果。在SQL Server中,游標(biāo)是一種可編程的對(duì)象,可以在存儲(chǔ)過(guò)程或觸發(fā)器中使用。
使用游標(biāo)可以逐行處理查詢結(jié)果,執(zhí)行復(fù)雜的邏輯操作,以及在處理數(shù)據(jù)時(shí)進(jìn)行一些特定的操作。游標(biāo)通常用于需要逐行處理數(shù)據(jù)的情況,例如對(duì)每一行數(shù)據(jù)進(jìn)行特定的計(jì)算或更新操作。
一、游標(biāo)的使用場(chǎng)景
需要逐行處理數(shù)據(jù):當(dāng)需要對(duì)查詢結(jié)果集中的每一行數(shù)據(jù)進(jìn)行特定的操作時(shí),游標(biāo)是一種常用的選擇。例如,需要對(duì)每一行數(shù)據(jù)進(jìn)行計(jì)算、更新或刪除操作時(shí),可以使用游標(biāo)來(lái)逐行處理數(shù)據(jù)。
需要在處理數(shù)據(jù)時(shí)進(jìn)行復(fù)雜的邏輯操作:有時(shí)候需要在處理數(shù)據(jù)時(shí)進(jìn)行復(fù)雜的邏輯操作,可能需要使用條件判斷、循環(huán)等結(jié)構(gòu)。游標(biāo)可以幫助實(shí)現(xiàn)這些復(fù)雜的邏輯操作,使得處理數(shù)據(jù)更加靈活。
需要在存儲(chǔ)過(guò)程或觸發(fā)器中使用游標(biāo):游標(biāo)可以在存儲(chǔ)過(guò)程或觸發(fā)器中使用,幫助實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)操作的逐行處理。在這些情況下,游標(biāo)可以提供更加靈活和精細(xì)的數(shù)據(jù)處理方式。
二、語(yǔ)法
1、聲明游標(biāo):
DECLARE cursor_name CURSOR FOR --定義游標(biāo),cursor_name是游標(biāo)名 SELECT column1, column2, ... --與游標(biāo)相連的表,這里就是普通的查詢語(yǔ)句。 FROM table_name WHERE condition;
2、打開游標(biāo):
OPEN cursor_name;
3、獲取游標(biāo)數(shù)據(jù):
FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...; --@variable1, @variable2, ...為數(shù)據(jù)表列名。
4、循環(huán)遍歷游標(biāo)數(shù)據(jù):
WHILE @@FETCH_STATUS = 0 BEGIN -- 執(zhí)行操作 FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...;--這里這段語(yǔ)句和一開始獲取游標(biāo)數(shù)據(jù)一樣 END
(1)、@@FETCH_STATUS 是一個(gè)系統(tǒng)變量,用于表示最近一次 FETCH 操作的狀態(tài)。具體取值如下:
- 0:FETCH 操作成功,已經(jīng)獲取了下一行數(shù)據(jù)。
- -1:FETCH 操作失敗或沒有更多的數(shù)據(jù)可獲取。
- -2:游標(biāo)已經(jīng)到達(dá)結(jié)果集的末尾或游標(biāo)未打開。
- 因此,在游標(biāo)循環(huán)中,
WHILE @@FETCH_STATUS = 0
語(yǔ)句用于判斷是否成功獲取了下一行數(shù)據(jù),如果為0,則表示成功獲取數(shù)據(jù),繼續(xù)循環(huán)處理數(shù)據(jù);如果不為0,則表示已經(jīng)到達(dá)結(jié)果集末尾或出現(xiàn)錯(cuò)誤,結(jié)束循環(huán)。
(2)、FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...
;這段語(yǔ)句出現(xiàn)了兩次。
在游標(biāo)循環(huán)中,FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...;
語(yǔ)句的作用是從游標(biāo)中獲取下一行數(shù)據(jù),并將數(shù)據(jù)存儲(chǔ)在指定的變量中。在游標(biāo)循環(huán)中,這個(gè)語(yǔ)句通常會(huì)出現(xiàn)兩次的原因是:
- 第一次出現(xiàn)在循環(huán)體的開頭,用于獲取游標(biāo)的第一行數(shù)據(jù),開始循環(huán)處理數(shù)據(jù)。
- 第二次出現(xiàn)在循環(huán)體的末尾,用于獲取下一行數(shù)據(jù),繼續(xù)循環(huán)處理下一行數(shù)據(jù)。
這兩次出現(xiàn)的 FETCH 語(yǔ)句配合使用,可以確保在循環(huán)中逐行處理游標(biāo)中的數(shù)據(jù)。第一次獲取第一行數(shù)據(jù),然后在循環(huán)體中處理該行數(shù)據(jù),最后再獲取下一行數(shù)據(jù),直到游標(biāo)遍歷完整個(gè)結(jié)果集。
5、關(guān)閉游標(biāo):
CLOSE cursor_name;
6、釋放游標(biāo):
DEALLOCATE cursor_name;
三、舉例:
1、首先創(chuàng)建測(cè)試表:
CREATE TABLE [dbo].[StudentScores]( [UserName] [NVARCHAR](20) NULL, [Subject] [NVARCHAR](30) NULL, [Score] [FLOAT] NULL ) ON [PRIMARY] GO
2、給測(cè)試表插入數(shù)據(jù):
INSERT INTO [dbo].[StudentScores] ([UserName], [Subject], [Score]) VALUES ('張三', '語(yǔ)文', 80), ('張三', '數(shù)學(xué)', 90), ('張三', '英語(yǔ)', 70), ('張三', '生物', 85), ('李四', '語(yǔ)文', 80), ('李四', '數(shù)學(xué)', 92), ('李四', '英語(yǔ)', 76), ('李四', '生物', 88), ('碼農(nóng)', '語(yǔ)文', 60), ('碼農(nóng)', '數(shù)學(xué)', 82), ('碼農(nóng)', '英語(yǔ)', 96), ('碼農(nóng)', '生物', 78);
3、按照第二步的語(yǔ)法創(chuàng)建游標(biāo)代碼
DECLARE @UserName VARCHAR(10), --定義需要使用的變量 @Subject VARCHAR(10), @Score DECIMAL(10, 2), @Score1 DECIMAL(10,2) CREATE TABLE #Student1 --創(chuàng)建一個(gè)臨時(shí)表,用來(lái)存儲(chǔ)游標(biāo)遍歷過(guò)的數(shù)據(jù) ( username VARCHAR(10), subject VARCHAR(10), score DECIMAL(10, 2) ) DECLARE Student CURSOR --定義游標(biāo),名稱為Student FOR SELECT UserName,Subject,Score FROM dbo.StudentScores --關(guān)聯(lián)數(shù)據(jù)表,這里也可以使用where篩選數(shù)據(jù)。 OPEN Student --打開游標(biāo) FETCH NEXT FROM Student INTO @UserName,@Subject,@Score --獲取數(shù)據(jù),把獲取的數(shù)據(jù)插入到變量里 WHILE @@FETCH_STATUS=0 --設(shè)置循環(huán)條件,@@FETCH_STATUS = 0 語(yǔ)句用于判斷是否成功獲取了下一行數(shù)據(jù)。 BEGIN --這段開始是代碼塊,用來(lái)執(zhí)行想要的操作 SET @Score1=@Score+10 --這里我們?cè)O(shè)置變量@Score1的值為@Score加10(@Score為原先的成績(jī)),用來(lái)實(shí)現(xiàn)將成績(jī)?cè)谠鹊幕A(chǔ)上加上10分的附加分。 INSERT #Student1 VALUES(@UserName,@Subject,@Score1) --這里我將修改后的數(shù)據(jù)插入臨時(shí)表中,也可以使用UPDATE語(yǔ)句直接修改原表,我這里為了方便多次測(cè)試就不修改原表。 FETCH NEXT FROM Student INTO @UserName,@Subject,@Score --這是第二次獲取數(shù)據(jù),用于獲取下一行數(shù)據(jù),繼續(xù)循環(huán)處理下一行數(shù)據(jù)。 END --這里表示代碼塊結(jié)尾 CLOSE Student --關(guān)閉游標(biāo) DEALLOCATE Student --釋放游標(biāo) SELECT * FROM #Student1 --查詢剛剛的臨時(shí)表中所有數(shù)據(jù),就可以看到游標(biāo)的執(zhí)行結(jié)果。 DROP TABLE #Student1 --刪除臨時(shí)表,如果不刪,同一個(gè)窗口再次執(zhí)行會(huì)報(bào)錯(cuò),提示這個(gè)臨時(shí)表已存在。
4、這里我們查看執(zhí)行結(jié)果
第一張是原表里的,第二張是通過(guò)游標(biāo)處理過(guò)的,可以看到第二張已經(jīng)將每個(gè)人的成績(jī)加了10分附加分。
四、總結(jié)
數(shù)據(jù)庫(kù)游標(biāo)主要用于在編程語(yǔ)言中與數(shù)據(jù)庫(kù)進(jìn)行交互。通過(guò)游標(biāo),程序員可以在程序中逐行地訪問(wèn)查詢結(jié)果集,并對(duì)每一行數(shù)據(jù)進(jìn)行操作。數(shù)據(jù)庫(kù)游標(biāo)提供了一種靈活、可控的方式來(lái)處理查詢結(jié)果,使程序員能夠更好地操作和管理數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
在編程中,程序員可以使用游標(biāo)執(zhí)行查詢語(yǔ)句,打開游標(biāo)以獲取結(jié)果集,然后逐行地遍歷結(jié)果集,對(duì)數(shù)據(jù)進(jìn)行處理,最后關(guān)閉游標(biāo)以釋放資源。數(shù)據(jù)庫(kù)游標(biāo)在程序中起到了連接數(shù)據(jù)庫(kù)和程序的橋梁作用,使程序能夠與數(shù)據(jù)庫(kù)進(jìn)行有效的交互。游標(biāo)一般是項(xiàng)目第一次部署,通過(guò)執(zhí)行腳本,根據(jù)遍歷不同設(shè)備數(shù)據(jù),根據(jù)類型的不同去其他表寫入或修改不同數(shù)據(jù)。
盡管游標(biāo)在某些情況下是一種有效的工具,但應(yīng)該謹(jǐn)慎使用。因?yàn)橛螛?biāo)可能會(huì)導(dǎo)致性能問(wèn)題,尤其是在處理大量數(shù)據(jù)時(shí)。在大多數(shù)情況下,可以通過(guò)使用集合操作或者其他SQL語(yǔ)句來(lái)替代游標(biāo),以提高性能并簡(jiǎn)化代碼邏輯。
到此這篇關(guān)于SQLServer數(shù)據(jù)庫(kù)游標(biāo)的具體使用的文章就介紹到這了,更多相關(guān)SQL游標(biāo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL Server Parameter Sniffing及其改進(jìn)方法
這篇文章主要介紹了SQL Server Parameter Sniffing及其改進(jìn)方法,需要的朋友可以參考下2017-06-06SQLServer2019配置端口號(hào)的實(shí)現(xiàn)
這篇文章主要介紹了SQLServer2019配置端口號(hào)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04設(shè)置SQLServer數(shù)據(jù)庫(kù)中某些表為只讀的多種方法分享
在某些情況下需要把SQLServer的表設(shè)為只讀,下面舉出幾種方法,需要的朋友可以參考下2012-06-06