如何創建和使用 SQL 游標

来源:https://www.cnblogs.com/vin-c/archive/2022/05/19/16288637.html
-Advertisement-
Play Games

本文介紹什麼是 SQL 游標,為什麼使用游標,如何使用游標。你使用的 DBMS 可能會提供某種形式的游標,以及這裡沒有提及的功能。更詳細的內容請參閱具體的 DBMS 文檔。 一、游標 SQL 檢索操作返回一組稱為結果集的行,這組返回的行都是與 SQL 語句相匹配的行(零行到多行)。 簡單地使用 SE ...


目錄

本文介紹什麼是 SQL 游標,為什麼使用游標,如何使用游標。你使用的 DBMS 可能會提供某種形式的游標,以及這裡沒有提及的功能。更詳細的內容請參閱具體的 DBMS 文檔。

一、游標

SQL 檢索操作返回一組稱為結果集的行,這組返回的行都是與 SQL 語句相匹配的行(零行到多行)。

簡單地使用 SELECT 語句,沒有辦法得到第一行、下一行或前 10 行。但這是關係 DBMS 功能的組成部分。

結果集(result set)

SQL 查詢所檢索出的結果。

有時,需要在檢索出來的行中前進或後退一行或多行,這就是游標的用途所在。

游標(cursor)是一個存儲在 DBMS 伺服器上的資料庫查詢,它不是一條 SELECT 語句,而是被該語句檢索出來的結果集。

在存儲了游標之後,應用程式可以根據需要滾動或瀏覽其中的數據。

說明:SQLite 支持

SQLite 支持的游標稱為步驟(step),本文講述的基本概念適用於 SQLite 的步驟,但語法可能完全不同。

不同的 DBMS 支持不同的游標選項和特性。常見的一些選項和特性如下。

  • 能夠標記游標為只讀,使數據能讀取,但不能更新和刪除。
  • 能控制可以執行的定向操作(向前、向後、第一、最後、絕對位置和相對位置等)。
  • 能標記某些列為可編輯的,某些列為不可編輯的。
  • 規定範圍,使游標對創建它的特定請求(如存儲過程)或對所有請求可訪問。
  • 指示 DBMS 對檢索出的數據(而不是指出表中活動數據)進行複製,使數據在游標打開和訪問期間不變化。

游標主要用於互動式應用,其中用戶需要滾動屏幕上的數據,並對數據進行瀏覽或做出更改。

二、使用游標

使用游標涉及幾個明確的步驟。

  • 在使用游標前,必須聲明(定義)它。這個過程實際上沒有檢索數據,它只是定義要使用的 SELECT 語句和游標選項。
  • 一旦聲明,就必須打開游標以供使用。這個過程用前面定義的 SELECT 語句把數據實際檢索出來。
  • 對於填有數據的游標,根據需要取出(檢索)各行。
  • 在結束游標使用時,必須關閉游標,可能的話,釋放游標(有賴於具體的 DBMS)。

聲明游標後,可根據需要頻繁地打開和關閉游標。在游標打開時,可根據需要頻繁地執行取操作。

2.1 創建游標

使用 DECLARE 語句創建游標,這條語句在不同的 DBMS 中有所不同。

DECLARE 命名游標,並定義相應的 SELECT 語句,根據需要帶 WHERE 和其他子句。

為了說明,我們創建一個游標來檢索沒有電子郵件地址的所有顧客,作為應用程式的組成部分,幫助操作人員找出空缺的電子郵件地址。

下麵是創建此游標的 DB2、MariaDB、MySQL 和 SQL Server 版本。

DECLARE CustCursor CURSOR
FOR
SELECT * FROM Customers
WHERE cust_email IS NULL;

下麵是 Oracle 和 PostgreSQL 版本:

DECLARE CURSOR CustCursor
IS
SELECT * FROM Customers
WHERE cust_email IS NULL;

在上面兩個版本中,DECLARE 語句用來定義和命名游標,這裡為 CustCursorSELECT 語句定義一個包含沒有電子郵件地址(NULL 值)的所有顧客的游標。

定義游標之後,就可以打開它了。

2.2 使用游標

使用 OPEN CURSOR 語句打開游標,這條語句很簡單,在大多數 DBMS 中的語法相同:

OPEN CURSOR CustCursor

在處理 OPEN CURSOR 語句時,執行查詢,存儲檢索出的數據以供瀏覽和滾動。

現在可以用 FETCH 語句訪問游標數據了。FETCH 指出要檢索哪些行,從何處檢索它們以及將它們放於何處(如變數名)。

第一個例子使用 Oracle 語法從游標中檢索一行(第一行):

DECLARE TYPE CustCursor IS REF CURSOR
    RETURN Customers%ROWTYPE;
DECLARE CustRecord Customers%ROWTYPE
BEGIN
    OPEN CustCursor;
    FETCH CustCursor INTO CustRecord;
    CLOSE CustCursor;
END;

在這個例子中,FETCH 用來檢索當前行(自動從第一行開始),放到聲明的變數 CustRecord 中。對於檢索出來的數據不做任何處理。

下一個例子(也使用 Oracle 語法)中,從第一行到最後一行,對檢索出來的數據進行迴圈:

DECLARE TYPE CustCursor IS REF CURSOR
    RETURN Customers%ROWTYPE;
DECLARE CustRecord Customers%ROWTYPE
BEGIN
    OPEN CustCursor;
    LOOP
    FETCH CustCursor INTO CustRecord;
    EXIT WHEN CustCursor%NOTFOUND;
       ...
    END LOOP;
    CLOSE CustCursor;
END;

與前一個例子一樣,這個例子使用 FETCH 檢索當前行,放到一個名為 CustRecord 的變數中。

但不一樣的是,這裡的 FETCH 位於 LOOP 內,因此它反覆執行。

代碼 EXIT WHEN CustCursor%NOTFOUND 使在取不出更多的行時終止處理(退出迴圈)。

這個例子也沒有做實際的處理,實際例子中可用具體的處理代碼替換省略號。

下麵是另一個例子,這次使用 Microsoft SQL Server 語法:

DECLARE @cust_id CHAR(10),
        @cust_name CHAR(50),
        @cust_address CHAR(50),
        @cust_city CHAR(50),
        @cust_state CHAR(5),
        @cust_zip CHAR(10),
        @cust_country CHAR(50),
        @cust_contact CHAR(50),
        @cust_email CHAR(255)
OPEN CustCursor
FETCH NEXT FROM CustCursor
    INTO @cust_id, @cust_name, @cust_address,
         @cust_city, @cust_state, @cust_zip,
         @cust_country, @cust_contact, @cust_email
   ...
WHILE @@FETCH_STATUS = 0
BEGIN

FETCH NEXT FROM CustCursor
        INTO @cust_id, @cust_name, @cust_address,
             @cust_city, @cust_state, @cust_zip,
             @cust_country, @cust_contact, @cust_email
...
END
CLOSE CustCursor

在此例中,為每個檢索出的列聲明一個變數,FETCH 語句檢索一行並保存值到這些變數中。

使用 WHILE 迴圈處理每一行,條件 WHILE @@FETCH_STATUS = 0 在取不出更多的行時終止處理(退出迴圈)。

這個例子也不進行具體的處理,實際代碼中,應該用具體的處理代碼替換其中的“...”。

2.3 關閉游標

如前面幾個例子所述,游標在使用完畢時需要關閉。此外,SQL Server 等 DBMS 要求明確釋放游標所占用的資源。

下麵是 DB2、Oracle 和 PostgreSQL 的語法。

CLOSE CustCursor

下麵是 Microsoft SQL Server 的版本。

CLOSE CustCursor
DEALLOCATE CURSOR CustCursor

CLOSE 語句用來關閉游標。一旦游標關閉,如果不再次打開,將不能使用。第二次使用它時不需要再聲明,只需用 OPEN 打開它即可。

三、小結

本文介紹了什麼是游標,為什麼使用游標。

你使用的 DBMS 可能會提供某種形式的游標,以及這裡沒有提及的功能。更詳細的內容請參閱具體的 DBMS 文檔。

原文鏈接:https://www.developerastrid.com/sql/sql-cursor/

(完)


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

-Advertisement-
Play Games
更多相關文章
  • 本文例子參考《STM32單片機開發實例——基於Proteus虛擬模擬與HAL/LL庫》 源代碼:https://github.com/LanLinnet/STM33F103R6 項目要求 單片機將由串口收到的1位元組數據存入Flash ROM的指定地址;按下按鈕BTN,單片機將存儲在Flash ROM ...
  • 為什麼要使用Redwood Redwood是一個全棧web框架,旨在幫助你從副業項目發展到創業。Redwood的特色是一個端到端的開發工作流,它將React、GraphQL、Prisma、TypeScript、Jest和Storybook中最好的部分編織在一起。 RedwoodJS 是集成 、Pri ...
  • Termius是微軟的一款SSH終端工具,它支持多平臺。而且操作界面十分ha好看且簡潔,今天分享給大家❤️ 軟體下載 關註下方公眾號,回覆termius獲取下載地址 軟體功能介紹 Termius Mac破解版是一款非常好用而且漂亮的SSH客戶端,能快速遠程式控制制伺服器,可以定製自己喜歡的主題,支持FT ...
  • 一、概述 Impala 直接針對存儲在 HDFS、HBase或 Amazon Simple Storage Service (S3)中的 Apache Hadoop 數據提供快速的互動式 SQL 查詢。Impala是一個基於Hive、分散式、大規模並行處理(MPP:Massively Paralle ...
  • 軟硬體環境 軟體 版本 操作系統 Redhat 7 及以上版本,麒麟V10 DM 資料庫 DM 8.0 及以上版本 CPU 架構 x86、ARM、龍芯、飛騰等國內外主流 CPU DM-Oracle 環境準備 在DM伺服器中完成Dblink環境準備工作。 配置Oracle oci客戶端 在Oracle ...
  • 導讀: 隨著全球數據量的不斷增長,越來越多的業務需要支撐高併發、高可用、可擴展、以及海量的數據存儲,在這種情況下,適應各種場景的數據存儲技術也不斷的產生和發展。與此同時,各種資料庫之間的同步與轉化的需求也不斷增多,數據集成成為大數據領域的熱門方向,於是SeaTunnel應運而生。SeaTunnel是 ...
  • hive 存儲格式有很多,但常用的一般是 TextFile、ORC、Parquet 格式,在我們單位最多的也是這三種 hive 預設的文件存儲格式是 TextFile。 除 TextFile 外的其他格式的表不能直接從本地文件導入數據,要先導入到 TextFile 格式的表中,再從表中用 inser ...
  • 本文介紹 SQL 所涉及的幾個數據處理特性:約束、索引和觸發器。約束是實施引用完整性的重要部分,索引可改善數據檢索的性能,觸發器可以用來執行運行前後的處理。 一、約束 SQL 已經改進過多個版本,成為非常完善和強大的語言。許多強有力的特性給用戶提供了高級的數據處理技術,如約束。 關聯表和引用完整性已 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文將以 C# 語言來實現一個簡單的布隆過濾器,為簡化說明,設計得很簡單,僅供學習使用。 感謝@時總百忙之中的指導。 布隆過濾器簡介 布隆過濾器(Bloom filter)是一種特殊的 Hash Table,能夠以較小的存儲空間較快地判斷出數據是否存在。常用於允許一定誤判率的數據過濾及防止緩存 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 「簡單有價值的事情長期堅持做」 這是成功最簡單,但也最難學的秘訣。不經過訓練,人很難意識到時間複利的威力。 仙劍奇俠傳的「十里坡劍神」和金庸群俠傳的「十級野球拳」,就是簡單的事情持之以恆反覆做,最後就有巨大的威力 唐家三少成為網文收入第一,最重要的一步是十四年從未斷日更 這樣的案例很多,一開始可能成 ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“我愛加班”。 面試開始,直入正題。 面試官: 看你簡歷上面寫著精通MySQL,我先問你事務的特性是什麼? 老生常談,這個還有誰不會背的嗎? 我: ...
  • 基礎知識 python是一門腳本語言,它是解釋執行的。 python使用縮進做為語法,而且python2環境下同一個py文件中不能同時存在tab和空格縮進,否則會出錯,建議在IDE中顯示縮進符。 python在聲明變數時不寫數據類型,可以type(xx)來獲取欄位的類型,然後可以int(),list ...
  • 為什麼要多線程下載 俗話說要以終為始,那麼我們首先要明確多線程下載的目標是什麼,不外乎是為了更快的下載文件。那麼問題來了,多線程下載文件相比於單線程是不是更快? 對於這個問題可以看下圖。 橫坐標是線程數,縱坐標是使用對應線程數下載對應文件時花費的時間,藍橙綠代表下載文件的大小,每個線程下載對應文件2 ...
  • 詳細講解python爬蟲代碼,爬微博搜索結果的博文數據。 爬取欄位: 頁碼、微博id、微博bid、微博作者、發佈時間、微博內容、轉發數、評論數、點贊數。 爬蟲技術: 1、requests 發送請求 2、datetime 時間格式轉換 3、jsonpath 快速解析json數據 4、re 正則表達式提... ...
  • 背景: 一般我們可以用HashMap做本地緩存,但是HashMap功能比較弱,不支持Key過期,不支持數據範圍查找等。故在此實現了一個簡易的本地緩存,取名叫fastmap。 功能: 1.支持數據過期 2.支持等值查找 3.支持範圍查找 4.支持key排序 實現思路: 1.等值查找採用HashMap2 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 本章是系列文章的第八章,用著色演算法進行寄存器的分配過程。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 寄存器分配 寄存器分配是為程式處理的值找到存儲位置的問題 這些值可以存放到寄存器,也可以存放在記憶體中 寄存器更快,但數量有限 記憶體很多,但 ...