SQL Server游標

来源:https://www.cnblogs.com/yoga21/archive/2018/04/23/8922364.html
-Advertisement-
Play Games

轉載自:http://www.cnblogs.com/knowledgesea/p/3699851.html。 什麼是游標 結果集,結果集就是select查詢之後返回的所有行數據的集合。 游標則是處理結果集的一種機制吧,它可以定位到結果集中的某一行,多數據進行讀寫,也可以移動游標定位到你所需要的行中 ...


轉載自:http://www.cnblogs.com/knowledgesea/p/3699851.html。

什麼是游標                                                                                   

結果集,結果集就是select查詢之後返回的所有行數據的集合。

游標則是處理結果集的一種機制吧,它可以定位到結果集中的某一行,多數據進行讀寫,也可以移動游標定位到你所需要的行中進行操作數據。

一般複雜的存儲過程,都會有游標的出現,他的用處主要有:

  1. 定位到結果集中的某一行。
  2. 對當前位置的數據進行讀寫。
  3. 可以對結果集中的數據單獨操作,而不是整行執行相同的操作。
  4. 是面向集合的資料庫管理系統和麵向行的程式設計之間的橋梁。

游標的分類                                                                                    

根據游標檢測結果集變化的能力和消耗資源的情況不同,SQL Server支持的API伺服器游標分為一下4種:

  • 靜態游標: 靜態游標的結果集,在游標打開的時候建立在TempDB中,不論你在操作游標的時候,如何操作資料庫,游標中的數據集都不會變。例如你在游標打開的時候,對游標查詢的數據表數據進行增刪改,操作之後,靜態游標中select的數據依舊顯示的為沒有操作之前的數據。如果想與操作之後的數據一致,則重新關閉打開游標即可。
  • 動態游標:這個則與靜態游標相對,滾動游標時,動態游標反應結果集中的所有更改。結果集中的行數據值、順序和成員在每次提取時都會變化。所有用戶做的增刪改語句通過游標均可見。如果使用API函數或T-SQL Where Current of子句通過游標進行更新,他們將立即可見。在游標外部所做的更新直到提交時才可見。
  • 只進游標:只進游標不支持滾動,只支持從頭到尾順序提取數據,資料庫執行增刪改,在提取時是可見的,但由於該游標只能進不能向後滾動,所以在行提取後對行做增刪改是不可見的。
  • 鍵集驅動游標:打開鍵集驅動游標時,該有表中的各個成員身份和順序是固定的。打開游標時,結果集這些行數據被一組唯一標識符標識,被標識的列做刪改時,用戶滾動游標是可見的,如果沒被標識的列增該,則不可見,比如insert一條數據,是不可見的,若可見,須關閉重新打開游標。

靜態游標在滾動時檢測不到表數據變化,但消耗的資源相對很少。動態游標在滾動時能檢測到所有表數據變化,但消耗的資源卻較多。鍵集驅動游標則處於他們中間,所以根據需求建立適合自己的游標,避免資源浪費。

游標的生命周期                                                                             

游標的生命周期包含有五個階段:聲明游標、打開游標、讀取游標數據、關閉游標、釋放游標。

 1.聲明游標,語法

複製代碼
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] 
     [ FORWARD_ONLY | SCROLL ] 
     [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] 
     [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] 
     [ TYPE_WARNING ] 
     FOR select_statement 
     [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
複製代碼

參數說明:

  • cursor_name:游標名稱。
  • Local:作用域為局部,只在定義它的批處理,存儲過程或觸發器中有效。
  • Global:作用域為全局,由連接執行的任何存儲過程或批處理中,都可以引用該游標。
  • [Local | Global]:預設為local。
  • Forward_Only:指定游標智能從第一行滾到最後一行。Fetch Next是唯一支持的提取選項。如果在指定Forward_Only是不指定Static、KeySet、Dynamic關鍵字,預設為Dynamic游標。如果Forward_Only和Scroll沒有指定,Static、KeySet、Dynamic游標預設為Scroll,Fast_Forward預設為Forward_Only
  • Static:靜態游標
  • KeySet:鍵集游標
  • Dynamic:動態游標,不支持Absolute提取選項
  • Fast_Forward:指定啟用了性能優化的Forward_Only、Read_Only游標。如果指定啦Scroll或For_Update,就不能指定他啦。
  • Read_Only:不能通過游標對數據進行刪改。
  • Scroll_Locks:將行讀入游標是,鎖定這些行,確保刪除或更新一定會成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
  • Optimistic:指定如果行自讀入游標以來已得到更新,則通過游標進行的定位更新或定位刪除不成功。當將行讀入游標時,sqlserver不鎖定行,它改用timestamp列值的比較結果來確定行讀入游標後是否發生了修改,如果表不行timestamp列,它改用校驗和值進行確定。如果已修改改行,則嘗試進行的定位更新或刪除將失敗。如果指定啦Fast_Forward,則不能指定他。
  • Type_Warning:指定將游標從所請求的類型隱式轉換為另一種類型時向客戶端發送警告信息。
  • For Update[of column_name ,....] :定義游標中可更新的列。

2.聲明一個動態游標

declare orderNum_02_cursor cursor scroll
for select OrderId from bigorder where orderNum='ZEORD003402'

3.打開游標

--打開游標語法
open [ Global ] cursor_name | cursor_variable_name

cursor_name:游標名,cursor_variable_name:游標變數名稱,該變數引用了一個游標。

--打開游標
open orderNum_02_cursor

4.提取數據

複製代碼
--提取游標語法
Fetch
[ [Next|prior|Frist|Last|Absoute n|Relative n ]
from ]
[Global] cursor_name
[into @variable_name[,....]]
複製代碼

參數說明:

  • Frist:結果集的第一行
  • Prior:當前位置的上一行
  • Next:當前位置的下一行
  • Last:最後一行
  • Absoute n:從游標的第一行開始數,第n行。
  • Relative n:從當前位置數,第n行。
  • Into @variable_name[,...] : 將提取到的數據存放到變數variable_name中。

例子:

複製代碼
--提取數據
fetch first from orderNum_02_cursor
fetch relative 3 from orderNum_02_cursor
fetch next from orderNum_02_cursor
fetch absolute 4 from orderNum_02_cursor
fetch next from orderNum_02_cursor
fetch last from orderNum_02_cursor 
fetch prior from orderNum_02_cursor
select * from bigorder where orderNum='ZEORD003402'
複製代碼

結果(對比一下,就明白啦):

例子:

--提取數據賦值給變數
declare @OrderId int
fetch absolute 3 from orderNum_02_cursor into @OrderId
select @OrderId as id
select * from bigorder where orderNum='ZEORD003402'

結果:

通過檢測全局變數@@Fetch_Status的值,獲得提取狀態信息,該狀態用於判斷Fetch語句返回數據的有效性。當執行一條Fetch語句之後,@@Fetch_Status可能出現3種值:0,Fetch語句成功。-1:Fetch語句失敗或行不在結果集中。-2:提取的行不存在。

這個狀態值可以幫你判斷提取數據的成功與否。

複製代碼
declare @OrderId int
fetch absolute 3 from orderNum_02_cursor into @OrderId
while @@fetch_status=0  --提取成功,進行下一條數據的提取操作
 begin
   select @OrderId as id
   fetch  next from orderNum_02_cursor into @OrderId  --移動游標
 end 
複製代碼

5.利用游標更新刪除數據 

--游標修改當前數據語法
Update 基表名 Set 列名=值[,...] Where Current of 游標名
--游標刪除當前數據語法
Delete 基表名  Where Current of 游標名
複製代碼
---游標更新刪除當前數據
---1.聲明游標
declare orderNum_03_cursor cursor scroll
for select OrderId ,userId from bigorder where orderNum='ZEORD003402'
--2.打開游標
open orderNum_03_cursor
--3.聲明游標提取數據所要存放的變數
declare @OrderId int ,@userId varchar(15)
--4.定位游標到哪一行
fetch First from orderNum_03_cursor into @OrderId,@userId  --into的變數數量必須與游標查詢結果集的列數相同
while @@fetch_status=0  --提取成功,進行下一條數據的提取操作 
 begin
   if @OrderId=122182
     begin
     Update bigorder Set UserId='123' Where Current of  orderNum_03_cursor  --修改當前行
     end
   if @OrderId=154074
      begin
      Delete bigorder Where Current of  orderNum_03_cursor  --刪除當前行
      end
   fetch next from orderNum_03_cursor into @OrderId ,@userId  --移動游標
 end  
複製代碼

6.關閉游標

 游標打開後,伺服器會專門為游標分配一定的記憶體空間存放游標操作的數據結果集,同時使用游標也會對某些數據進行封鎖。所以游標一旦用過,應及時關閉,避免伺服器資源浪費。

--關閉游標語法
close [ Global ] cursor_name | cursor_variable_name
--關閉游標
close orderNum_03_cursor

7.刪除游標

刪除游標,釋放資源

--釋放游標語法
deallocate  [ Global ] cursor_name | cursor_variable_name
--釋放游標
deallocate orderNum_03_cursor

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 隨著雲伺服器的普及,購入雲伺服器的門檻越來越低,對一個程式員來說,很多人會購買一款雲伺服器。以前買過兩年windows伺服器(沒有什麼實際用途,就是為了玩),最近有機會接觸一下linux伺服器,選擇了系統為centos7的阿裡雲伺服器,下麵和大家一起來學習一下linux伺服器的各種操作(純新手)。 ...
  • 官方參考文檔:docs.ansible.com 第一講:ansible簡介及Iventory Ansible基本架構: Ansible基本組成: Ansible工作原理: Ansible安裝: 配置好epel源,yum install -y ansible ansible主要文件和命令: Ansib ...
  • 用ssh連其他linux機器,會等待10-30秒才有提示輸入密碼。嚴重影響工作效率。登錄很慢,登錄上去後速度正常,這種情況主要有兩種可能的原因: 1. DNS反向解析的問題 OpenSSH在用戶登錄的時候會驗證IP,它根據用戶的IP使用反向DNS找到主機名,再使用DNS找到IP地址,最後匹配一下登錄 ...
  • 寫作背景: 項目是基於java、weblogic及timer的處理模式,每次服務部署之後timer的整體狀態是一個盲區,因為100多個進程,是否有啟動遺漏或者啟動重覆的,想做到一目瞭然是件困難的事情。所以我考慮用shell腳本的文件查找與匹配方法來解決這個問題,簡單記錄下,僅供參考。 程式說明: 1 ...
  • 非常強大的文本操縱工具,sed,awk,grep 這個三個命令 都是操作文本文件的unix系統有幾個非常命令的特點:1. 對於內核而言,unix文件都是位元組序列。io設備也是文件。2. 至於文件的含義交由應用程式來解釋。其中文本文件非常重要,因為unix提供 很多了實用程式(utility),這些程 ...
  • 在VMware workstation12上新建虛擬機,發現無法連接網路。然後查了一些資料,知道了怎樣配置網路,記錄一下。 1、首先用ifconfig命令查看虛擬機的IP地址及網關信息 觀察顯示內容,查看虛擬機的網關名稱ens33是否有IP地址 2、如果沒有,使用vi /etc/sysconfig/ ...
  • 設計好處 良好的資料庫邏輯設計和物理設計師資料庫獲得高性能的基礎 範式化設計和反範式化設計(減少冗餘、減少異常、讓數據組織的更加和諧) 優化目的 減少數據冗餘(儘量) 儘量避免數據維護中出現更新、插入和刪除等異常 插入:如果表中的某個實體隨著另一個實體而存在 更新:如果更改表中的某個實體的單獨屬性時 ...
  • 使用變數並不能完全滿足SQL語句嚮應用程式輸出數據的要求的,一組變數只能存放一條記錄,而查詢結果的記錄數是不確定的,所以才有了游標的概念。 基本原理 在PL/SQL中執行select、insert、update和delete語句時,oracle會在記憶體中分配上下文區,即一個緩衝區。而游標就是指向該區 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...