亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

PL SQL語言

2024-07-21 02:52:41
字體:
來源:轉載
供稿:網友

4.1 PL/SQL簡介

4.1.1 PL/SQL概述

PL/SQL是Oracle在標準SQL語言上的過程性擴展,它允許嵌入SQL語句、定義變量和常量、使用過程語言結構(條件分支語句和循環語句)、使用異常來處理Oracle錯誤等。在任何運行Oracler的平臺上,應用開發人員都可以使用PL/SQL。通過使用PL/SQL,可以在一個PL/SQL塊中包含多條SQL語句和PL/SQL語句。PL/SQL可以用于創建存儲過程、觸發器和程序包等,也可以用于處理業務規則、數據庫事件或為SQL命令的執行添加程序邏輯。

PL/SQL是一種可移植的高性能事務處理程序,它支持SQL和面向對象編程,提供了良好的性能和高效的處理能力,具有以下6個方面的優點。

1.提高應用程序的運行性能

在編寫OracoeOracle數據庫應用程序時,開發人員可以直接將PL/SQL塊內嵌到應用程序中,其最大的優點是可以降低網絡開銷、提高應用程序性能。對于其他異構數據庫(例如SQL Server、Sybase、DB2等),當應用程序訪問RDBMS時,每次只能發送單條SQL語句。而對于Oracle數據庫而言,通過使用PL/SQL塊,可以將多條SQL語句組織到同一個PL/SQL塊中,從而降低網絡開銷,提高應用程序的性能。

2.提供模塊化的程序設計功能

當開發數據庫應用程序時,為了簡化客戶端應用程序的開發和維護工作,可以首先將企業規則或商業邏輯集成到PL/SQL子程序(過程、函數和包)中,然后在應用程序中調用子程序實現相應的程序功能。

3.允許定義標識符

當使用PL/SQL開發應用模塊時,為了使應用模塊與應用環境實現數據交互,需要定義變量、常量、游標等各種標識符。例如,函數get_sal中的no為輸入參數,用于接收雇員編號的輸入值,而salary變量則用于臨時存儲雇員工資。

4.具有過程語言控制結構

PL/SQL是Oracle在標準SQL上的過程性擴展,它不僅允許在PL/SQL塊中嵌入SQL語句,而且允許在PL/SQL塊中使用各種類型的條件分支語句和循環語句。

5.具有良好的兼容性

PL/SQL是Oracle提供的用于實現應用模塊的語言,在允許運行Oracle的任何平臺上都可以使用PL/SQL。例如,在Oracle數據庫中使用PL/SQL開發數據庫端的過程、函數和觸發器,以及在Oracle提供的應用開發工具Developer中使用PL/SQL開發客戶端的過程、函數和觸發器。

6.處理運行錯誤

當設計并開發應用程序時,為了提高應用程序的健壯性,可以使用PL/SQL提供的異常處理(EXCEPTION)集中處理各種Oracle錯誤和PL/SQL錯誤,從而簡化錯誤處理。

4.1.2 PL/SQL塊

所有的PL/SQL程序都以塊作為基本單位組成。塊中包含過程化語句和SQL的DML語句。這些塊可以按順序出現,也可以相互嵌套(一個塊在別一個塊的內部)。按是否帶有名稱以及在數據庫中的存儲方式,塊可以分為以下5種。

1.匿名塊

匿名塊是出現在應用程序中的沒有名稱且不存儲到數據庫中的塊。匿名塊可以出現在SQL語句出現的地方,它們可以調用其他程序,卻不能被其他程序調用。

2.命名塊

命名塊是一種帶有標簽的匿名塊,標簽為塊指定了一個名稱。

3.子程序

子程序是存儲在數據庫中的過程(PRocedure)、函數(function),生成之后可以被多次執行。

4.程序包

程序包是存儲在數據庫中的一組子程序、變量定義。程序包中的子程序可以被其他程序包或者子程序調用。如果聲明為局部子程序,則只能在定義該局部子程序的塊中被調用該局部子程序。

5.觸發器

觸發器是一種存儲在數據庫中的命名塊,生成之后可以被多次執行。在相應的觸發器事件發生之前或之后就會被執行一次或多次(每行記錄一次)。觸發器事件一般是指對特定的數據庫表、視圖進行的操作,如INSERT、UPDATE和DELETE等(被稱為DML觸發器);或者對數據庫級的操作,如關閉、啟動、登錄、退出數據庫,創建對象、修改對象、刪除對象等(稱為系統觸發器)。

4.2 程序結構

4.2.1 組成部分和注釋

PL/SQL程序塊由3個部分組成:定義部分、執行部分和異常處理部分。其中,定義部分用于定義常量、變量、游標、異常和復雜數據類型等;執行部分用于實現應用模塊功能,該部分包含需要執行的PL/SQL語句和SQL語句;異常處理部分用于處理執行部分可能出現的運行錯誤。PL/SQL塊的基本結構如下:

DECLARE

   定義部分

BEGIN

   執行部分

EXCEPTION

   異常處理部分

END;

其中,定義部分以DECLARE開始,該部分是可選的;執行部分以BEGIN開始,該部分是必須的;異常處理部分以EXCEPTION開始,該部分是可選的;END則是PL/SQL程序塊的結束標記。以下示例創建匿名程序塊,用于接收用戶輸入的員工編號,輸出該員工的姓名,以及處理用戶輸入的員工編號不存在的異常

注意

DECLAREE、BEGIN和EXCEPTION后面沒有“;”(分號),而END后則必須要帶“;”(分號)。

在PL/SQL程序中加入注釋可以幫助理解程序,PL/SQL編譯器在編譯時會忽略注釋,PL/SQL的注釋分為單行注釋和多行注釋。

1.單行注釋

單行注釋可以放在一行的任何地方,由兩條短橫線(--)開始。

2.多行注釋

多行注釋“/*”開始、“*/”結束,可以跨越多行,但不允許嵌套。

在調試PL/SQL程序時,完全可以使用單行或多行注釋來將暫時不需要或不正確的語句進行注釋或禁用。

4.1.1 常量與變量

在聲明部分中可以聲明需要使用的常量、變量、函數、游標、異常處理名稱等。

1.聲明

聲明常量、變量的語法如下:

語法:

Iidentifier_name  [CONSTANT]  data_type [NOTNULL][:=value_expression]|[DEFAULT value_expression]

其中,identifier_name指定需要聲明的常量、變量的名稱;data_type指定數據類型;“:=”是賦值運算符(或使用DEFAULT);value_expression是賦值表達式。如果語句中有CONSTANT,則表明聲明的是一個常量;如果有NOT NULL,則表明聲明的變不能為空(即在聲明時必須賦值)。聲明常量時應該立即賦值,如果沒有賦值則表示初始化為NULL。

注意:

在PL/SQL中,每一行中能聲明一個常量或變量。在引用一個常量或變量之前,必須先對其進行聲明。

2.使用SELECT INTO語句為變量賦值

除了可以使用常量為變量賦值之外,還可以將從數據庫表中查詢獲得的值賦給變量。通過SELECT INTO語句可以從數據庫表中查詢的結果賦予變量,根據雇員編號獲得雇員工資、補助和總工資,代碼如圖4.1.1所示。該示例代碼中,從數據庫中根據員工編號查詢員工姓名,并把員工姓名賦給變量v_ename。

4.1.1 數據類型

編寫PL/SQL程序時,若臨時存儲數值,則必須定義變量和常量;若在應用環境和子程序之間傳遞數據,則必須為子程序指定參數。而在PL/SQL程序中定義變量、常量和參數時,必須為它們指定PL/SQL數據類型。常見的數據類型如表14-1-1所示。

14-1-1 部分數據類型及說明

數據類型

說明

char

表示固定長度字符串,長度不夠時使用空格來補充,最多可以存儲2000字節。

varchar2

表示可變長字符串,最多可以存儲4000字節。

number

可以存儲正數、負數、零、定點數和精度為38的浮點數。其格式為:number(m,n),其中m表示精度代表數字的總位數;n表示小數點右邊數字的位數。

date

用于存儲表中的日期和時間數據,取值范圍是公元前4712年1月1日到公元9999年12月31日。Date類型的長度是7,7個字節分別表示世紀、年、月、日、時、分和秒。

timestamp

用戶存儲日期的年、月、日、小時、分和秒值。其中,秒值精確到小數點后6位數,該數據類型同時包含時區信息。

clob

用于存儲可變長度的字符數據,最多可存儲4GB。該數據類型用于存儲varchar2類型不能存儲的長文本信息。

blob

用于存儲較大的二進制對象,如圖形、視頻剪輯和聲音剪輯等,該類型最多可存儲4GB數據。

PL/SQL中的數據類型除了表1-1-1所列出的以外還有以下常用的類型:

1.%TYPE

當定義PL/SQL變量存放值時,必須確保變量使用合適的數據類型和長度,否則可能在運行過程中出現PL/SQL運行錯誤。此時,可以使用%TYPE屬性來定義變量。當使用%TYPE屬性定義變量時,Oracle會自動地按照數據庫列或其他變量來確定新變量的類型和長度。圖4.1.3演示了使用%TYPE定義變量的過程。

2.%ROWTYPE

如果一張表中包含較多的列,則可以使用%ROWTYPE來定義一個表示表中一行記錄的變量,這樣比分別使用%TYPE來定義表示表中各個列的變量更加簡潔。為了使一個變量的數據類型與一張表中記錄的各個列的數據類型對應一致,Oracle提供了%ROWTYPE定義定議方式。

在圖4.1.3中,根據輸入的員工編號查詢該員工姓名、部門編號,并將查詢結果存儲在變量v_ename、v_deptno中。然后根據根據部門編號查詢一條部門信息并將該信息存入變量v_dept_row中。

3.RECORD

PL/SQL記錄類似于高級語言中的結構,每個PL/SQL記錄一般都包含多個成員。當使用PL/SQL記錄時,首先需要在定義部分定義記錄類型和記錄變量,然后在執行部分引用該記錄變量。當引用記錄成員時,必須將記錄變量作為前綴,格式為“記錄變量.記錄成員”。

語法:

Type  record_name is record

(

V1  data_type1  [not null] [:=default_value],

V2  data_type2  [not null] [:=default_value],

Vndata_typen  [not null] [:=default_value]

);

4.TABLE

索引表相當于一個鍵值集合,鍵是唯一的,用于查找對應的值。鍵可以是整數或字符串。

語法:

Type  table_name  is  table  of   element_type [not null]

index  by [binary_integer |  pls_integer  |varchar2]  

關鍵字INDEX BY表示創建一個主鍵索引,以便引用記錄表變量中的特定行。

4.1 流程控制

流程控制是PL/SQL對SQL最重要的擴展,流程控制結構包括條件控制、循環控制和順序控制。

4.1.1 條件控制

在許多情況中,需要按照某種條件來選擇執行某些語句段。條件控制先測試一個條件,然后根據測試的結果選擇、運行不同的語句段。條件結構中允許嵌套。

1.IF…THEN…END IF結構

最簡單的條件控制結構。

語法:

If IF  條件表達式  THEN

語句段

END  IF;

2.IF…THEN…ELSE…END IF結構

二重條件分支結構。如果滿足條件則執行一組操作,不滿足條件則執行另外一操作。

語法:

IF  條件表達式  THEN

語句段1

ELSE

語句段2

END  IF;

3.IF…THEN…ELSIF…END IF結構

多重條件分支結構。如果滿足第一個條件,則執行第一種操作;如果不滿足第一個條件,則檢查是否滿足第二個條件,如果滿足則執行第二種操作;如果不滿足第二個條件,則檢查是否滿足第三個條件……依此類推。

語法:

IF  表達式1   THEN

語句段1

ELSIF 條件表達式2  THEN

語句段2

……

ELSIF  條件表達式n   THEN

語句段n

ELSE

語句段

END  IF ;

CASE結構

CASE結構是在Oracle 9i中引的另一種邏輯判斷結構,它提供了另一種邏輯判斷的實現方法。

語法:

CASE 表達式

WHEN 條件表達式結果1   THEN

語句段1;

WHEN 條件表達式結果2   THEN

語句段2;

…...

ELSE

語句段n;

   END  CASE;

CASE結構的另一種語法格式被稱為CASE搜索結構,語法如下:

語法:

CASE

WHEN  條件表達式結果1   THEN

語句段1;

WHEN  條件表達式結果2    THEN

語句段2;

……

ELSE

語句段n;

END  CASE;

其中,CASE結構非常適用于從多個值中選擇一個,以決定需要執行的語句段。在實際應用中,CASE結構的可讀性及有效性更高,盡量將很長的IF…THEN…ELSIF…END IF語句改寫成CASE結構。

4.1.1 循環控制

為了在編寫的PL/SQL塊中重復執行一條語句或者一組語句,可以使用循環控制結構。編寫循環控制結構時,用戶可以使用基本循環、WHILE循環和FOR循環等類型的循環語句。

1.基本循環

在PL/SQL中,格式最簡單的循環語句是基本循環語句,它以LOOP開始,以END LOOP結束。

語法:

LOOP

語句段;

EXIT  [WHEN 條件表達式]

END  LOOP;

上述語法中,當使用基本循環時,無論是否滿足條件,語句至少會被執行一次。當條件表達式為TRUE時,會退出循環,并執行END LOOP后的操作。

注意:

EXIT語句必須放在循環體內,且只能退出循環體,不能退出PL/SQL塊。當需要退出PL/SQL塊時,應該使用RETURN語句。

WHILE循環

基本循環至少需要執行一次循環體內的語句,而WHILE循環中,只有當條件為TRUE時,才會執行循環體內的語句。我們改造圖4.1.9的示例,使用while循環來實現

FOR循環

當使用基本循環或WHILE循環時,需要定義循環控制變量。循環控制變量不僅可以使用NUMABENUMBER類型,還可以使用其他數據類型。當使用FOR循環時,Oracle會隱含定義循環變量。

默認情況下,當使用FOR循環時,每循環,控制變量會自動增加1;如果指定了REVERSE選項,則每次循環時循環控制變量會自動減少1。在循環體內部可以引用循環變量,但不能對其賦值。

4.1 異常處理

PL/SQL異常是指通過編譯的PL/SQL程序在運行時產生的錯誤。導致異常的原因較多,如內存用盡、硬件故障、違反表的完整性約束、設計缺陷等。PL/SQL提供了異常錯誤處理機制,可以幫助實現對錯誤的捕獲和處理。當異常發生時,PL/SQL會自動地捕獲異常并將程序控制流程轉移到異常處理部分部會的程序。

語法:

EXCEPTION

WHEN 異常錯誤名稱1 [OR  異常錯誤名稱2……]  THEN

語句段1;

WHEN 異常錯誤名稱3  [OR  異常錯誤名稱4…… ]  THEN

語句段2;

……

WHEN  OTHERS  THEN

語句段3;

 

上述語法中,異常處理部分以保留字EXCEPTION開始,可以使用WHEN子句按“異常錯誤名稱”捕獲各種異常錯誤,其他沒有預計到的異常錯誤可以使用WHEN OTHERS子句進行捕獲。

4.1.1 預定義異常

針對一些常見的錯誤,PL/SQL預定義了一些異常錯誤。當PL/SQL程序違反了Oracle的規定或超出了系統規定的限制時,就會隱含地引發一個預定義的錯誤。PL/SQL在程序包STANDARD中包含了這些預定義異常,常用的預定義異常錯誤見表4-1-2所示。

1.1.14-1-2 PL/SQL預定義異常

異常

ORACLE錯誤

描述

access_into_null

ora-6530

試圖訪問一個未初始化的對象

case_not_found

ora-6592

case語句中的選項與用戶輸入的數據不匹配

cursor_already_open

ora-6511

試圖打開一個已打開的游標

dup_val_on_index

ora-0001

試圖破壞一個唯一性約束

invalid_cursor

ora-1001

試圖打開一個無效的游標

invalid_number

ora-1722

試圖對非數字值進行數字操作

login_denied

ora-1017

無效的用戶名或者口令

no_data_found

ora-1403

查詢未找到數據

not_logged_on

ora-1012

還未連接就試圖數據庫操作

program_error

ora-6501

內部錯誤

rowtype_mismatch

ora-6504

主變量的游標的類型不兼容

storage_error

ora-6500

內部錯誤

timeout_on_resource

ora-0051

發生超時

too_many_rows

ora-1422

select  into 命令返回多行

transaction_backed_out

ora-006

由于死鎖提交被退回

value_error

ora-6502

轉換或者裁剪錯誤

zero_divide

ora-1476

試圖被除零

4.1.1 自定義異常

預定義異常都是由Oracle判斷的異常錯誤。在實際的PL/SQL程序開發過程中,為了具體的業務規則、編程和調試的需要,程序員可以自定義一些異常。自定義異常必須進行聲明,并且必須使用RAISE語句顯式地觸發。

在刪除表中的數據時,如果沒有符合條件的記錄,則不會刪除數據。因為這不是錯誤,所以不會有任何的錯誤提示,但可以使用自定義錯誤的方法來提示。例如,通過判斷來獲知是否存在該記錄,并使用自定義異常的方法進行提示,代碼如圖14.1.13所示。其中sql代表隱含游標。

4.1 什么是事務(Transaction)

設想網上購物的一次交易,其付款過程至少包括以下幾步數據庫操作:

? 更新客戶所購商品的庫存信息

? 保存客戶付款信息--可能包括與銀行系統的交互

? 生成訂單并且保存到數據庫中

? 更新用戶相關信息,例如購物數量等等

正常的情況下,這些操作將順利進行,最終交易成功,與交易相關的所有數據庫信息也成功地更新。但是,如果在這一系列過程中任何一個環節出了差錯,例如在更新商品庫存信息時發生異常、該顧客銀行帳戶存款不足等,都將導致交易失敗。一旦交易失敗,數據庫中所有信息都必須保持交易前的狀態不變,比如最后一步更新用戶信息時失敗而導致交易失敗,那么必須保證這筆失敗的交易不影響數據庫的狀態--庫存信息沒有被更新、用戶也沒有付款,訂單也沒有生成。否則,數據庫的信息將會一片混亂而不可預測。

數據庫事務正是用來保證這種情況下交易的平穩性和可預測性的技術。

事務用于保證數據的一致性,它由一組相關的dml語句組成,該組的dml(數據操作語言insert delete update)語句要么全部成功,要么全部失敗。

4.1.1 事務的ACID特性  

  對一組SQL語句操作構成事務,數據庫操作系統必須確保這些操作的原子性,一致性,隔離性,持久性.  

1、  原子性(Atomicity)  

    事務的原子性是指事務中包含的所有操作要么全做,要么不做,也就是說所有的活動在數據庫中要么全部反映,要么全部不反映,以保證數據庫的一致性。  

2、  一致性(Consistency)  

    事務的一致性是指數據庫在事務操作前和事務處理后,其中數據必須滿足業務的規則約束。  和我們的規則預期一致。 不會出現一個加 一個沒減

3、  隔離性(Isolation)  

   隔離性是指數據庫允許多個并發的事務同時對其中的數據進行讀寫或修改的能力,隔離性可以防止多個事務的并發執行時,由于它們的操作命令交叉執行而導致數據的不一致性。   Oracle支持 read commited 和序列化

4、  持久性(durability)  

    事務的持久性是指在事務處理結束后,它對數據的修改應該是永久的。即便是系統在遇到故障的情況下也不會丟失,這是數據的重要性決定的。

4.1.2 事務的控制語句  

   在Oracle數據庫中,沒有提供開始事務處理語句,所有的事務都是隱式開始的,也就是說在oracle中,用戶不可以顯示使用命令來開始一個事務.oracle任務第一條修改數據庫的語句,或者一些要求事務處理的場合都是事務的隱式開始。但是當用戶想要終止一個事務處理時,必須顯示使用commit和rollback語句結束。  

   Savepoint 在事務中建立一個存儲的點.當事務處理發生異常而回滾事務時,可指定事務回滾到某存儲點.然后從該存儲點重新執行。  

   Rollback 回滾事務 取消對數據庫所作的任何操作  

   Commit 提交事務 對數據庫的操作做持久的保存。

 

實例4.14:設置自動提交

SET AUTOCOMMIT {ON | OFF | IMMEDIATE | n}

IMMEDIATE選項的功能與ON相同

n表示當Oracle數據庫成功執行了n條insert,update,delete或PL/SQL程序塊時自動提交事務

SQL> set autocommit on;

SQL>show autocommit;

Commit語句用于提交事務

使用ROLLBACK語句可以將事務回滾到事務的起點或某個保存點開始

定義保存點

保存點定義了事務中的一個位置,使用Rollback語句可以將數據會滾到保存點的位置,從而實現事務的部分回滾功能。

savepoint <回滾點>

rollback to <回滾點>

查看事務信息

查看事務信息使用視圖V$TRANSACTION,這個視圖必須使用sys或system訪問,因為當前事務是匿名事務,所以name字段值為空

前面的實例都是匿名事務,其實可以給事務命名

SET TRANSACTION NAME '事務名稱'

通過plsql塊 演示事務declarebegin insert into dept values(33,'xx','ss');insert into dept values(10,'xx','ss');commit;exception when others thenrollback;end;

4.1.1 事務和鎖

當多個用戶同時訪問Oracle數據庫,執行事務操作(dml語句)時,同時可能有多個用戶訪問同一個數據庫資源,Oracle會自動在被作用的表上加鎖,防止其他用戶的事務改表的數據,這里對我們用戶來說是非常重要的,它會避免使用的數據產生邏輯錯誤。

例如轉賬 可能出現負值。

如果沒有鎖定且多個用戶同時訪問一個數據庫,則當他們的事務同時使用相同的數據時可能會發生問題。由于并發操作帶來的數據不一致性包括:丟失數據修改、讀”臟”數據(臟讀)、不可重復讀、產生幽靈數據。   

(1)丟失數據修改   

當兩個或多個事務選擇同一行,然后基于最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最后的更新將重寫由其它事務所做的更新,這將導致數據丟失。如上例。   再例如,兩個編輯人員制作了同一文檔的電子復本。每個編輯人員獨立地更改其復本,然后保存更改后的復本,這樣就覆蓋了原始文檔。最后保存其更改復本的編輯人員覆蓋了第一個編輯人員所做的更改。如果在第一個編輯人員完成之后第二個編輯人員才能進行更改,則可以避免該問題。

(2)讀“臟”數據(臟讀)   

讀“臟”數據是指事務T1修改某一數據,并將其寫回磁盤,事務T2讀取同一數據后,T1由于某種原因被除撤消,而此時T1把已修改過的數據又恢復原值,T2讀到的數據與數據庫的數據不一致,則T2讀到的數據就為“臟”數據,即不正確的數據。   例如:一個編輯人員正在更改電子文檔。在更改過程中,另一個編輯人員復制了該文檔(該復本包含到目前為止所做的全部更改)并將其分發給預期的用戶。此后,第一個編輯人員認為目前所做的更改是錯誤的,于是刪除了所做的編輯并保存了文檔。分發給用戶的文檔包含不再存在的編輯內容,并且這些編輯內容應認為從未存在過。如果在第一個編輯人員確定最終更改前任何人都不能讀取更改的文檔,則可以避免該問題。   

( 3)不可重復讀   

指事務T1讀取數據后,事務T2執行更新操作,使T1無法讀取前一次結果。不可重復讀包括三種情況:   事務T1讀取某一數據后,T2對其做了修改,當T1再次讀該數據后,得到與前一不同的值。   

扣款。

(4)產生幽靈數據   

按一定條件從數據庫中讀取了某些記錄后,T2刪除了其中部分記錄,當T1再次按相同條件讀取數據時,發現某些記錄消失   T1按一定條件從數據庫中讀取某些數據記錄后,T2插入了一些記錄,當T1再次按相同條件讀取數據時,發現多了一些記錄。

 

 

 

 

數據庫是一個多用戶使用的共享資源。當多個用戶并發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對并發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。 加鎖是實現數據庫并發控制的一個非常重要的技術。當事務在對某個數據對象進行操作前,先向系統發出請求,對其加鎖。加鎖后事務就對該數據對象有了一定的控制,在該事務釋放鎖之前,其他的事務不能對此數據對象進行更新操作。

使用鎖解決不可重復讀 和丟失數據修改!!

 

在數據庫中有兩種基本的鎖類型:排它鎖(Exclusive Locks,即X鎖)和共享鎖(Share Locks,即S鎖)。當數據對象被加上排它鎖時,其他的事務不能對它讀取和修改。加了共享鎖的數據對象可以被其他事務讀取,但不能修改。數據庫利用這兩種基本的鎖類型來對數據庫的事務進行并發控制。

Oracle數據庫的鎖類型

根據保護的對象不同,Oracle數據庫鎖可以分為以下幾大類:DML鎖(data locks,數據鎖),用于保護數據的完整性;DDL鎖(dictionary locks,字典鎖),用于保護數據庫對象的結構,如表、索引等的結構定義;內部鎖和閂(internal locks and latches),保護數據庫的內部結構。

DML鎖的目的在于保證并發情況下的數據完整性,本文主要討論DML鎖。在Oracle數據庫中,DML鎖主要包括TM鎖和TX鎖,其中TM鎖稱為表級鎖,TX鎖稱為事務鎖或行級鎖。 粒度

當Oracle執行DML語句時,系統自動在所要操作的表上申請TM類型的鎖 用來預防其他事務使用ddl語句來修改表結構 刪除表等。當TM鎖獲得后,系統再自動申請TX類型的鎖,并將實際鎖定的數據行的鎖標志位進行置位。這樣在事務加鎖前檢查TX鎖相容性時就不用再逐行檢查鎖標志,而只需檢查TM鎖模式的相容性即可,大大提高了系統的效率。TM鎖包括了SS、SX、S、X等多種模式,在數據庫中用0-6來表示。不同的SQL操作產生不同類型的TM鎖。

在數據行上只有X鎖(排他鎖)。在 Oracle數據庫中,當一個事務首次發起一個DML語句時就獲得一個TX鎖,該鎖保持到事務被提交或回滾。當兩個或多個會話在表的同一條記錄上執行DML語句時,第一個會話在該條記錄上加鎖,其他的會話處于等待狀態。當第一個會話提交后,TX鎖被釋放,其他會話才可以加鎖。

當Oracle數據庫發生TX鎖等待時,如果不及時處理常常會引起Oracle數據庫掛起,或導致死鎖的發生,產生ORA-60的錯誤。這些現象都會對實際應用產生極大的危害,如長時間未響應,大量事務失敗等。

 

 

示例4.20:死鎖實例

因為大型數據庫應用系統存在并發機制,也就是說可能同時有多個會話訪問同一個數據,這時可能不可避免出現死鎖。例如有兩個事務A和B,如果事務A已經鎖定了數據庫對象A(數據庫對象A可能是一張表或表中的幾條記錄)。如果事務B也已經鎖定了數據庫對象B(數據庫對象B可能是一張表或表中的幾條記錄)。此時事務A再去申請鎖定數據庫對象B,而同時時事務B再去申請鎖定數據庫對象A。兩者互不相讓,就產生了死鎖,嚴重影響性能。

示例4.21:jdbc中的死鎖public static void main(String[] args) {		Connection ct = null;		try {			// 1、加在驅動			Class.forName("oracle.jdbc.driver.OracleDriver");			// 得到連接			ct = DriverManager					.getConnection(					"jdbc:oracle:thin:@localhost:1521:orcl","scott","tiger");			// 從下面開始和sql一樣			// 加入事務處理			ct.setAutoCommit(false);			Statement sm = ct.createStatement();			sm.executeUpdate("update dept set loc='shanghai' where deptno=10");			Thread.sleep(4000);			sm.executeUpdate("update dept set loc='beijing' where deptno=20");					} catch (Exception e) {			e.printStackTrace();		}		finally{			System.out.println("事務1結束?。。?!");			try {				ct.commit();			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}	}

創建第二個main函數,將Statement類對象sm執行的SQL語句調換一下,就可以模擬死鎖。

也可以設置隔離級別來達到控制并發的目的 其實隔離級別的原理就是使用不同的鎖策略來達到目的:

Read commited : 這種隔離級別指的是,事務只能讀取已經提交的數據,(但是支持可重復讀與幻讀)是oracle數據庫默認的隔離模式。

 SEAIALIZABLE:不允許臟讀,重復讀與幻想讀,最高的隔離級別。這種隔離級別標明事務A在操作數據庫的時候好像就只有事務A在操作,沒有其他事務在操作數據庫一樣。

     Oracle 中是這樣實現 SERIALIZABLE 事務的:原本通常在語句級得到的讀一致性現在可以擴展到事務級。也就是在事務執行的那一刻,將這個事務將要操作的數據拍了一張照片。

級別越高 并發性越低 完整性一致性越高。

 SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

l         SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

 

 

 

 

? 本章總結

? PL/SQL是Oracle在標準SQL語言上的過程性擴展,它允許嵌入SQL語句、定義變量和常量、使用過程語言結構(條件分支語句和循環語句)、使用異常來處理Oracle錯誤等

? PL/SQL塊可以分為匿名塊、命名塊、子程序、程序包,觸發器5種

? 針對一些常見的錯誤,PL/SQL預定義了一些異常錯誤。當PL/SQL程序違反了Oracle的規定或超出了系統規定的限制時,就會隱含地引發一個預定義的錯誤

? 為了具體的業務規則、編程和調試的需要,程序員可以自定義一些異常。自定義異常必須進行聲明,并且必須使用RAISE語句顯式地觸發。

? 事務用于保證數據的一致性,它由一組相關的dml語句組成,該組的dml(數據操作語言insert delete update)語句要么全部成功,要么全部失敗。

? 事務控制語句包括commit,rollback,savepoint

任務實訓部分

1:PL/SQL塊中數據類型的使用

訓練技能點

? PL/SQL塊程序結構中的數據類型

需求說明

在使用記錄變量插入數據和更新數據時,需注意列的順序、個數、類型必須與記錄成員

的順序、個數、類型完全匹配。現要求實現:使用記錄變量的方式來插入部門信息。

實現思路

(1) 定義一個關于dept部門表的%ROWTYPE變量。

(2) 為其中的deptno部門編號、部門名稱及地址賦值。

(3) 然后通過INSERT語句插入數據。

關鍵代碼

PL/SQL塊中流程控制語句的使用

訓練技能點

? FOR循環的使用

需求說明

在PL/SQL中,可以使用FOR循環直接訪問SELECT查詢獲得的結果。要求查詢出各個部

門工資最高的雇員信息。

實現思路

(1) 通過FOR循環訪問各個部門,輸出dept表中所有部門的名稱

(2) 根據各個部門提供的部門編號(deptno)查詢emp表中該部門工資最高的雇員。

(3) 輸出該雇員信息。

通過For循環查詢獲得各個部門工資最高的雇員信息

異常處理

訓練技能點

? 異常處理

需求說明

使用非預定義異常,更新特定雇員的部門號,并處理ORA-02291錯誤。當定義Oracle錯誤和異常之間的關聯關系時,需要使用偽過程EXCEPTION_INIT。

實現思路

(1) 首先的定義部分定義異常。

(2) 使用progma exception_init(exception_name,exception_number)在異常和oracle錯誤之間建立關聯,這時要求用戶知道可能出現的錯誤號。

(3) 最終在異常處理部分捕捉并處理異常。

鞏固練習

一.選擇題

1. 數據庫中有兩種基本的鎖類型是(     )

    A. 排它鎖

    B. 共享鎖

    C. 只讀鎖

    D. 更新鎖 

2. 下列選項中,不能直接嵌入PL/SQL塊中的語句有(    )。

A.SELECT

B.INSERT

C.CREATE TABLE

D.GRANT

E.COMMIT

3. 當SELECT INTO語句沒有返回行時,觸發的異常(    )。

A.TOO_MANY_ROWS

B.VALUE_ERROR

C.NO_DATA_FOUND

    D.不會觸發任何異常

4. 以下PL/SQL塊的輸出結果是(  )

DECLARE

v_1 NUMBER(2);

         v_2 NUMBER(3);

BEGIN

v_2:=CASE WHEN v_1 IS NULL THEN 10 ELSE 20 end;

DBMS_OUTPUT.PUT_LINE(‘v_2:’||v_2);

END;

A.10

B.0

C.20

    D.語法錯誤

5. 以下PL/SQL塊的輸出結果是(    )

BEGIN

    FOR I IN 1..5 LOOP

   DBMS_OUTPUT.PUT_LINE(‘*’);

    END LOOP;

END;

A.**

B.***

C.*

    *

    *

D.不會觸發任何異常

 

二.操作題上機練習

由用戶輸入一個雇員編號,要求在emp表中查找是否存在與輸入的雇員編號對應的雇員。

1.如果存在,則有以下操作:

(1)輸出“查到此雇員”,并判斷其部門是否為“SALES”部門。

(2)如果是“SALES”部門,則輸出“此雇員屬于SALES部門”,并刪除對應的記錄;否則輸出“此雇員不屬于SALES部門,不能刪除!”。

2.如查不存在,則輸出“找不到此雇員!”。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕视频在线免费欧美日韩综合在线看| 成人免费看黄网站| 性色av一区二区三区红粉影视| 亚洲男人天堂网| 亚洲图片欧美日产| 欧美巨乳美女视频| 欧美大片在线看免费观看| 日韩av在线精品| 国产精品视频一区国模私拍| 2019中文字幕在线| 亚洲a级在线播放观看| 少妇精69xxtheporn| 91精品国产91久久久久久吃药| 国产精品日韩专区| 亚洲国产成人精品电影| 另类图片亚洲另类| 国内精品国产三级国产在线专| 国产成人91久久精品| 国产精品精品视频一区二区三区| 国产亚洲精品一区二区| 91免费在线视频网站| 日韩激情第一页| 91成人在线观看国产| 亚洲一品av免费观看| 日韩精品中文字幕久久臀| 97色在线视频| 国产欧美日韩中文字幕| 热久久美女精品天天吊色| 精品国偷自产在线视频99| 亚洲第一网中文字幕| 亚洲一区精品电影| 97精品视频在线| 欧美激情第一页xxx| 国产成人精品在线播放| 国产精品久久久久7777婷婷| 欧美视频中文字幕在线| 国产精品你懂得| 日韩女优人人人人射在线视频| 国产精品99免视看9| 精品日韩中文字幕| 欧美超级乱淫片喷水| 久久久电影免费观看完整版| 欧美日韩国产综合新一区| 成人自拍性视频| 亚洲自拍欧美另类| 国产亚洲欧美日韩一区二区| 亚洲最大在线视频| 久久午夜a级毛片| 久久青草精品视频免费观看| 中文字幕欧美在线| 日韩一区视频在线| 日韩综合视频在线观看| 国产福利视频一区二区| 成人美女免费网站视频| 色无极影院亚洲| 亚洲电影在线看| 最近2019中文字幕mv免费看| 亚洲欧美日韩成人| 68精品久久久久久欧美| 亚洲欧洲av一区二区| 亚洲国产小视频在线观看| 欧美巨乳在线观看| 亚洲欧美国产精品va在线观看| 91欧美激情另类亚洲| 国产欧美一区二区三区四区| 亚洲精品日韩激情在线电影| 国产精品一区二区久久| 国产女精品视频网站免费| 2019亚洲男人天堂| 久久精品国产视频| 欧美激情一区二区三区在线视频观看| 日本久久久久久久| 国产精品免费一区豆花| 国产欧美在线视频| 亚洲人成网在线播放| 国产成人97精品免费看片| 欧美洲成人男女午夜视频| 日韩禁在线播放| 中文字幕亚洲欧美日韩2019| 国外视频精品毛片| 国产日韩精品视频| 亚洲在线免费视频| 久久亚洲国产精品成人av秋霞| 日韩av在线导航| 久久777国产线看观看精品| 亚洲欧美一区二区三区在线| 中文字幕一区二区精品| 97久久精品视频| 在线视频精品一| 中文字幕亚洲欧美一区二区三区| 奇米成人av国产一区二区三区| 国产精品国模在线| 色琪琪综合男人的天堂aⅴ视频| 国产成人精品av| 亚洲最大福利视频| 国产欧美久久久久久| 精品国产依人香蕉在线精品| 亚洲最大的免费| 69久久夜色精品国产69乱青草| 国产欧美中文字幕| 亚洲男人第一网站| 成人精品在线视频| 日韩大片免费观看视频播放| 欧美激情极品视频| 亚洲性69xxxbbb| 欧洲成人免费aa| 欧美激情一二区| 精品国产一区二区三区久久狼5月| 国产精品久久久久久久久久久新郎| 国产亚洲精品综合一区91| 久久精品视频免费播放| 亚洲在线第一页| 97超碰蝌蚪网人人做人人爽| 欧美高跟鞋交xxxxxhd| 九九九热精品免费视频观看网站| 久久精品国产成人| 亚洲区bt下载| 日韩欧美在线视频免费观看| 中文字幕欧美日韩精品| 国产主播在线一区| 欧美肥臀大乳一区二区免费视频| 国产精品自产拍在线观看| 97香蕉超级碰碰久久免费软件| 草民午夜欧美限制a级福利片| 欧美视频在线看| 国产亚洲精品一区二555| 欧美日韩在线一区| 欧美日韩午夜剧场| 97成人超碰免| 精品国产视频在线| 日本久久亚洲电影| 亚洲偷熟乱区亚洲香蕉av| 亚洲激情免费观看| 日韩高清有码在线| 亚洲精品成人久久电影| 欧美另类暴力丝袜| 日韩电影中文字幕在线观看| 国产成人精品亚洲精品| 一个人看的www欧美| 色妞久久福利网| 久久亚洲国产精品成人av秋霞| 国产精品久久久久9999| 欧美人与性动交a欧美精品| 亚洲欧美日韩精品久久| 欧美一级成年大片在线观看| 97国产精品免费视频| 久久久国产精品视频| 亚洲最大的免费| 欧美一区二区三区……| 成人精品aaaa网站| 国产一区二区三区在线观看网站| 亚洲va久久久噜噜噜久久天堂| 亚洲97在线观看| 永久555www成人免费| 欧美性jizz18性欧美| 亚洲欧美日韩视频一区| 色播久久人人爽人人爽人人片视av| 日本韩国欧美精品大片卡二| 国产精品日韩欧美大师| 欧美成人免费小视频| 91久久国产精品91久久性色| 亚洲高清久久网| 亚洲精品一区二三区不卡| 亚洲国产欧美一区二区三区久久|