sqlserver遊標概念與例項全面解說
引言
我們先不講遊標的什麼概念,步驟及語法,先來看一個例子:
表一 OriginSalary 表二 AddSalary
現在有2張表,一張是OriginSalary表--工資表,有三個欄位0_ID 員工號(NVARCHAR)、O_Name員工姓名(NVARCHAR)、O_Salary工資(FLOAT)。
另一張表AddSalary表—加薪表。有2個欄位,O_ID員工號、A_Salary增加工資。兩張表的O_ID是一一對應的,現在求將加薪的工資+原來的工資=現在的工資,也就是O_Salary=O_Salary+A_Salary,修改表OriginSalary的工資欄位。
對於一些不熟悉遊標的程式設計師來說,這個並不是什麼很難的問題,這個問題用程式來實現可能也很簡單。我先說說,用ASP.NET程式解決這個問題的思路:
1. 先獲得表OriginSalary的記錄數,寫個迴圈。
2. 寫SQL語句“select * from dbo.OriginSalary as A left join dbo.AddSalary as B on A.O_ID=B.O_ID”獲得檢視。
3. 使用Dataset獲得O_Salary=O_Salary+A_Salary。
4. 寫UPDATE語句“update OriginSalary set O_Salary=”相加的值” where O_ID=”獲得值”
5. 迴圈3次,完成此功能。
還有一種方法就是寫儲存過程,在這裡我就不列出來了。
我想大家在學習遊標之前好好想想這個問題,及一些批量處理的例子。可能有的人會說:“難道資料庫不能一行一行的處理資料嗎?將表AddSalary的資料逐行的取出,然後表 OriginSalary資料逐行的修改?”答案當然是肯定。這就是遊標概念。接下來的一章我們會好好的講講什麼是遊標?我會用遊標來解決剛才留給大家的問題。
1.1遊標的概念
遊標(Cursor)它使使用者可逐行訪問由SQL Server返回的結果集。使用遊標(cursor)的一個主要的原因就是把集合操作轉換成單個記錄處理方式。用SQL語言從資料庫中檢索資料後,結果放在記憶體的一塊區域中,且結果往往是一個含有多個記錄的集合。遊標機制允許使用者在SQL server內逐行地訪問這些記錄,按照使用者自己的意願來顯示和處理這些記錄。
1.2 遊標的優點
從遊標定義可以得到遊標的如下優點,這些優點使遊標在實際應用中發揮了重要作用:
1)允許程式對由查詢語句select返回的行集合中的每一行執行相同或不同的操作,而不是對整個行集合執行同一個操作。
2)提供對基於遊標位置的表中的行進行刪除和更新的能力。
3)遊標實際上作為面向集合的資料庫管理系統(RDBMS)和麵向行的程式設計之間的橋樑,使這兩種處理方式通過遊標溝通起來。
1.3 遊標的使用
講了這個多遊標的優點,現在我們就親自來揭開遊標的神祕的面紗。
使用遊標的順序: 聲名遊標、開啟遊標、讀取資料、關閉遊標、刪除遊標。
1.3.1宣告遊標
最簡單遊標宣告:DECLARE <遊標名>CURSOR FOR<SELECT語句>;
其中select語句可以是簡單查詢,也可以是複雜的接連查詢和巢狀查詢
例子:[已表2 AddSalary為例子]
Declare mycursor cursor for select * from AddSalary
這樣我就對錶AddSalary申明瞭一個遊標mycursor
【高階備註】
DECLARE <遊標名> [INSENSITIVE] [SCROLL] CURSORFOR<SELECT語句>
這裡我說一下游標中級應用中的[INSENSITIVE]和[SCROLL]
INSENSITIVE
表明MS SQL SERVER 會將遊標定義所選取出來的資料記錄存放在一臨時表內(建立在tempdb 資料庫下)。對該遊標的讀取操作皆由臨時表來應答。因此,對基本表的修改並不影響遊標提取的資料,即遊標不會隨著基本表內容的改變而改變,同時也無法通過遊標來更新基本表。如果不使用該保留字,那麼對基本表的更新、刪除都會反映到遊標中。
另外應該指出,當遇到以下情況發生時,遊標將自動設定INSENSITIVE 選項。
a.在SELECT 語句中使用DISTINCT、 GROUP BY、 HAVING UNION 語句;
b.使用OUTER JOIN;
c.所選取的任意表沒有索引;
d.將實數值當作選取的列。
SCROLL
表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用該保留字,那麼只能進行NEXT 提取操作。由此可見,SCROLL 極大地增加了提取資料的靈活性,可以隨意讀取結果集中的任一行資料記錄,而不必關閉再
重開遊標。
1.3.2 開啟遊標
非常簡單,我們就開啟剛才我們宣告的遊標mycursor
OPEN mycursor
1.3.3讀取資料
FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 遊標名 | @遊標變數名 } [ INTO @變數名 [,…] ]
引數說明:
NEXT 取下一行的資料,並把下一行作為當前行(遞增)。由於開啟遊標後,行指標是指向該遊標第1行之前,所以第一次執行FETCH NEXT操作將取得遊標集中的第1行資料。NEXT為預設的遊標提取選項。
INTO @變數名[,…] 把提取操作的列資料放到區域性變數中。列表中的各個變數從左到右與遊標結果集中的相應列相關聯。各變數的資料型別必須與相應的結果列的資料型別匹配或是結果列資料型別所支援的隱性轉換。變數的數目必須與遊標選擇列表中的列的數目一致。
現在我們就取出mycursor遊標的資料吧!
當遊標被開啟時,行指標將指向該遊標集第1行之前,如果要讀取遊標集中的第1行資料,必須移動行指標使其指向第1行。就本例而言,可以使用下列操作讀取第1行資料:
Eg: Fetch next from mycursor 或則 Fetch first from mycursor
這樣我就取出了遊標裡的資料,但是光光這樣可不夠,我們還需要將取出的資料賦給變數
//宣告2個變數
declare @O_ID NVARCHAR(20)
declare @A_Salary float
//將取出的值傳入剛才宣告的2個變數
Fetch next from mycursor into @ O_ID,@ A_Salary
1.3.4關閉遊標
CLOSE mycursor
1.3.5刪除遊標
DEALLOCATE mycursor
1.3.6 例項訓練
如上我介紹完了遊標使用的5個步驟,那現在我們就來上上手,練習用遊標取出表2 AddSalary的資料。
為了執行我們自己建立的遊標,我們將遊標寫在儲存過程裡,方便我們看到遊標的整個使用過程。
在sqlserver2000中新建一個儲存過程:
CREATE PROCEDURE PK_Test
AS
//宣告2個變數
declare @O_ID nvarchar(20)
declare @A_Salary float
//宣告一個遊標mycursor,select語句中引數的個數必須要和從遊標取出的變數名相同
declare mycursor cursor for select O_ID,A_Salary from AddSalary
//開啟遊標
open mycursor
//從遊標裡取出資料賦值到我們剛才宣告的2個變數中
fetch next from mycursor into @O_ID,@A_Salary
//判斷遊標的狀態
//0 fetch語句成功
//-1 fetch語句失敗或此行不在結果集中
//-2被提取的行不存在
while (@@fetch_status=0)
begin
//顯示出我們每次用遊標取出的值
print '遊標成功取出一條資料'
print @O_ID
print @A_Salary
//用遊標去取下一條記錄
fetch next from mycursor into @O_ID,@A_Salary
end
//關閉遊標
close mycursor
//撤銷遊標
deallocate mycursor
GO
通過上面的註釋,我想大家都明白了整個遊標的建立過程了吧。但是我們現在還是一個抽象的瞭解,我們學任何知識,都要用於實踐,這樣才能使抽象的東西變的具體。
那我們就執行這個儲存過程,看看遊標到底是怎麼取值的:
我們開啟SQLSERVER2000的查詢分析器,制定好資料庫後,我們執行儲存過程
Exec PK_Test
讓我看看效果吧(如圖)
通過例項我們可以看到遊標逐行逐行都把值都取出來了。那麼我請大家先不看下面的答案,在引言部分我剛才留個大家的問題試一下能不能解決?
現在我們寫一個儲存過程解決剛才我留下來的問題吧
CREATE PROCEDURE PK_SalaryAdd
AS
declare @O_ID nvarchar(20),@A_Salary float
declare mycursor cursor for select O_ID,A_Salary from AddSalary
open mycursor
fetch next from mycursor into @O_ID,@A_Salary
while(@@fetch_status = 0)
begin
Update OriginSalary set
fetch next from mycursor into @O_ID,@A_Salary
end
close mycursor
deallocate mycursor
GO
按照老方法,我們用查詢分析器來執行我們的儲存過程,看看結果是怎麼樣的?
Exec PK_SalaryAdd
讓我看看效果吧(如圖)
執行儲存過程,看到我們影響了3行資料
用sql語句,看看錶OriginSalary現在的結果:
1.4 結束語
很高興大家能把這個教程看完,其實這只是遊標的最最基礎的一個應用,顯示生活的邏輯的關係中,可能有更復雜的遊標。但是我們只有學會走路,才能跑步嘛,o(∩_∩)o…。
相關推薦
sqlserver遊標概念與例項全面解說
引言 我們先不講遊標的什麼概念,步驟及語法,先來看一個例子: 表一 OriginSalary 表二 AddSalary 現在有2張表,一張是OriginS
【轉載】RTL 與 technology schematic的區別,包含概念與例項
下面是xilinx官網上的問答貼: The difference between RTL and technology schematic Description After XST synthesis is completed, I am able t
【資料庫】SQLServer遊標概念和作用
遊標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制。遊標充當指標的作用。儘管遊標能遍歷結果中的所有行,但他一次只指向一行。 概括來講,SQL的遊標是一種臨時的資料庫物件,既可以用來存放資料庫表中的資料行副本,也可以指向儲存在資料庫中的資料行的指
UML簡單介紹(十九)——部署圖的基本概念與例項介紹
1、部署圖 部署圖用於靜態建模,是表示執行時過程節點結構、構件例項及其物件結構的圖。如果含有依賴關係的構件例項放置在不同節點上,部署檢視可以展示出執行過程中的瓶頸。 部署圖的兩種表現形式:例項層部署圖和描述層部署圖(會在後面的例項中給出)。
C++迭代器理解與例項詳解
定義一個數組:char buff[1024];當我們用指標char *p(char *p = buff)遍歷陣列時,指標p指向一維陣列首元素地址,每次都是從陣列第一個元素的偏移到指定位置,即進行指標運算。例如:訪問p[100]時,需要p+100,這樣浪費時間,影響效率。因
Java執行緒池原理與例項詳解
Wiki 採用new Thread的方式產生多執行緒,可能有以下一些問題: 執行緒的建立和銷燬開銷很大,尤其是有些執行緒的存在時間較短; 執行緒的建立和銷燬過程中伴隨著CPU線上程間的切換,開銷很大; 執行緒池的優點有: 減少了
[譯]例項詳解防抖與節流(乾貨!!!)
lodash原始碼中推薦的文章,為了學習(英語),翻譯了一下~ 原文連結 作者:DAVID CORBACHO 本文來自一位倫敦前端工程師DAVID CORBACHO的技術投稿。我們在之前討論過這個話題(關於防抖與節流),但這次,DAVID CORBACHO通過生動的演示會將它們講的十分清晰,通俗易懂。
例項詳解js閉包(一)閉包基本概念及其作用推導
在學習前端的過程中,不可避免的要學習到js閉包這個知識點,很多朋友感到對閉包很難理解,也不清楚它有什麼用。本文就詳細介紹一下閉包,並通過幾個小例子來說明下閉包的用處。 一、閉包的概念 閉包的英文單詞是Closure,我先給閉包可
log4j.properties配置詳解與例項-全部測試通過[轉]
最近使用log4j寫log時候發現網上的寫的都是千篇一律,寫的好的嘛不全,寫的全一點的嘛沒有一點格式,看著累。這裡把網上收集到的整理了一下,並且全部都在機器上測試成功了。這麼好的文件估計沒有了吧? ###############################################
面向物件—的__new__()方法詳解 [Python] Python 之 __new__() 方法與例項化
[Python] Python 之 __new__() 方法與例項化 __new__() 是在新式類中新出現的方法,它作用在構造方法建造例項之前,可以這麼理解,在 Python 中存在於類裡面的構造方法 __init__() 負責將類的例項化,而在 __init__()
SQLServer 遊標詳解
測試結果 變量 t-sql relative iso 最後一行 for allow sid 一、用到的數據 CREATE TABLE [dbo].[XSB]( [學號] [char](6) NOT NULL, [姓名] [char](8) NOT NULL
SpringCloud微服務之間的通訊,Feign和RestTemplate概念例項詳解
前言: 在springcloud微服務的實際專案開發中,多個微服務之間不僅是相對獨立的,而且也是相對關聯的;也就是說,微服務之間需要相互訪問,多個微服務之間的介面可能會被互相多次呼叫,我們稱之為微服務之間的通訊; 微服務之間的通訊方式有很多,一般使用以下兩種方法:一種是RestT
Java執行緒詳解(1)-概念與原理
一、程序與執行緒 程序是指一個記憶體中執行的應用程式,每個程序都有自己獨立的一塊記憶體空間,即程序空間或(虛空間)。程序不依賴於執行緒而獨立存在,一個程序中可以啟動多個執行緒。比如在Windows系統中,一個執行的exe就是一個程序。 執行
Sqlserver 遊標&儲存過程&臨時表混合使用例項
通過巢狀,根據表中記錄的表名與列名到指定位置取值。 --宣告儲存過程 ProPIMS if (exists (select * from sys.objects where name = 'ProPIMS')) drop proc ProPIMS go create procedure
hashMap詳解與例項
在Java集合類中最常用的除了ArrayList外,就是HashMap了。本文儘自己所能,儘量詳細的解釋HashMap的原始碼。一山還有一山高,有不足之處請之處,定感謝指定並及時修正。 在看HashMap原始碼之前先複習一下資料結構。 Ja
JAVA反射例項詳解與介紹
我們都知道Java反射很重要,這次我來拋個磚頭!!! 一:反射 反射是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。 使用java的反射,一般有下面三步: 1:獲得你想操作類
MyBatis的基本概念與程式例項
MyBatis的基本概念與程式例項 MyBatis優勢 1.和JDBC一樣不遮蔽sql語句,可以直接寫sql語句,比較靈活 2.有對映機制,再組裝各種sql時可以不改變大框架,直接新增對映就可以寫入其他sql 3.對於對映器來說,Mapper提供介面程式設計,只要一個介面和一個x
例項詳解js實現登入與註冊介面
本文主要為大家詳細介紹了js實現登入與註冊介面,具有一定的參考價值,感興趣的小夥伴們可以參考一下,希望能幫助到大家。 完成登入與註冊頁面的HTML+CSS+JS,其中的輸入項檢查包括: 使用者名稱6-12位 首字母不能是數字 只能包含字母和數字
spark log4j.properties配置詳解與例項
################################################################################ #①配置根Logger,其語法為: # #log4j.rootLogger = [level],appen
人工神經網路概念梳理與例項演示
引言 這段時間花了不少精力在瞭解人工神經網路(ANN),對其設計思想和基本演算法有了一定的瞭解,把相關知識整理如下,一方面梳理思路,增強理解,另一方面也希望對想了解ANN的人有點幫助。 1 時代大背景 首先,我們瞭解以下人工神經網路的發展歷史。 19