㈠ oracle資料庫中表、段、區、塊是什麼意思
oracle的邏輯結構包括表空間(tablespace),段(segment),區(extent),數據塊(data block)x0dx0aoracle資料庫在邏輯上是由多個表間組成的,表空間中存儲的對象叫段,比如數據段,索引段,和回退段。段由區組成,區是磁碟分配的最小單位。段的增大是通過增加區的個數來實現的。每個區的大小是數據塊大小的整數倍,區的大小可以不相同;數據塊是資料庫中最小的I/O單位,同時也是內存數據緩沖區的單位,及數據文件存儲空間單位。塊的大小由參數DB_BLOCK_SIZE設置,其值應設置為操作系統塊大小的整數倍。x0dx0a表空間x0dx0a表空間是Oracle資料庫最大的邏輯結構,一個Oracle資料庫在邏輯上由多個表空間組成,一個表空間只隸屬於一個資料庫。Oracle中有一個稱為SYSTEM的表空間,這個表空間是在創建或安裝資料庫時自動創建的。主要用於存儲系統的數據字典,過程,函數,觸發器等;也可以存儲用戶的表,索引等。一個表空間可以有多數據文件,但是一個數據文件只能屬於一個表空間。x0dx0a一個表空間就是一片磁碟區域,他由一個或者多個磁碟文件組成,一個表空間可以容納許多表、索引或者簇等。每個表空間有一個預制的磁碟區域稱為初始區間(initial extent)用完這個區間後再用下一個,直到用完表空間,這時候需要對表空間進行擴展,增加數據文件或者擴大已經存在的數據文件x0dx0a段x0dx0aOracle中的段可以分成4種類型:數據段、索引段、回滾段、臨時段。x0dx0a數據段用來存儲用戶的數據,每個表都有一個對應的回滾段,其名稱和數據表的名字相同。索引段用來存儲系統、用戶的索引信息。回滾段用來存儲用戶數據修改前的值,回退段與事務是一對多的關系,一個事務只能使用一個回退段,而一個回退段可存放一個或多個事務的回退數據。臨時段用於order by語句的排序以及一些匯總。x0dx0a區x0dx0a區是磁碟空間分配的最小單位。磁碟按區劃分,每次至少分配一個區。區存儲於段中,它由連續的數據塊組成。區的分配過程中,每次至分配5個區。如果所剩的空閑空間不夠5個區,就會出現錯誤:ORA-0。可以通過字典dba_tablespaces查詢表空間中區的信息。可以通過字典user_tables查詢段中區的信息。可以通過字典user_extents查詢區的分配狀況。我們可以通過以下sql語句分別查詢表空間、段、區中區的分配信息x0dx0aSQL>select * from dba_tablespaces;x0dx0aSQL>select table_name, tablespace_name, min_extents, max_extents from user_tables; x0dx0aSQL>select * from user_extents;x0dx0a數據塊x0dx0a數據塊是數據中中最小的數據組織單位與管理單位,是數據文件磁碟存儲空間單位,也是資料庫I/O 的最小單位,數據塊大小由DB_BLOCK_SIZE參數決定,不同的oracle版本DB_BLOCK_SIZE的默認值是不同的。
㈡ Oracle游標sql語句代碼塊的優化
游標操作的優化:
-- 有一個表格,存儲的是用戶的名字,將 emp 表中所有的用戶名轉換成小寫,再寫入這個表格
create table ename_emp(
ename varchar2(50)
);
-- 下面這個游標的操作,需要 43s時間才能完成
declare
begin
for i in (select ename from emp_liebiao) loop
insert into ename_emp values(lower(i.ename));
commit;
end loop;
end;
-- 因為游標是以行為單位進行數據的操作的,所有游標的效率是比較慢的,而且游標需要消耗的內存也是比較多的,我們需要將游標以行進行操作的方式,修改成一次性操作所有數據的批量的方式。
批量操作在游標裡面 叫做 bulk collect
第一步,創建一個表類型
type 表類型的名字 is table of 表名.列名 %type;
變數名 表類型的名字;
第三步,創建一個游標,讀取某個查詢的結果
cursor 游標名字 is select 查詢語句 ;
第四步,打開游標
open 游標名字;
第五步,捕獲游標的數據,將內容給到表類型的變數進行保存
fetch 游標名字 bulk collect into 變數名字 ;
第六步,使用 forall 語句,對數據進行批量的操作
forall i in 變數 .first .. 變數 .last DML 語句操作 ;
第七步,關閉游標
close 游標名字 ;
declare
-- 創建表類型
type biao is table of emp_liebiao.ename%type;
b biao;
-- 創建游標
cursor m is select ename from emp_liebiao;
begin
-- 打開游標
open m;
-- 將游標的內容批量的給到變數
fetch m bulk collect into b;
-- 使用forall批量修改數據
forall i in b.first .. b.last insert into ename_emp values(lower(b(i)));
commit;
-- 關閉游標
close m;
end;
練習:批量修改用戶的編號,讓編號+工資等級+部門,形成一個新的編號,存入下面的表格中,使用 bulk collect 來實現。
2000以下是 C ,2000-3000是 B ,3000以上是 A ,
例如 SMITH , 新編號應該是 7369_C_20
create table empno_emp(
empno varchar2(50)
);
declare
type biao is table of emp_liebiao%rowtype;
b biao;
cursor m is select * from emp_liebiao;
begin
open m;
fetch m bulk collect into b;
forall i in b.first..b.last
insert into empno_emp values(
b(i).empno||'_'||decode(sign(b(i).sal-2000)+sign(b(i).sal-3000),-2,'C',2,'A','B')||'_'||b(i).deptno
);
commit;
close m;
end;
㈢ 執行一個Oracle PLSQL塊,直接報ORA-24337: statement handle not prepared
ORA-24337表面上的意思是pl/sql塊中的寫法有問題,但如果在其他機器上執行沒有問題,而在你這里有問題,因此可以判斷pl/sql塊本身的寫法沒有錯誤,問題估計出在你的機器上。
所以建議你按如下方向排查:
1.你使用的oracle用戶是否與其他人一致,如果不一致,檢查你的許可權是否足夠
2.如果Oracle用戶一致,檢查你機器的環境變數設置
查過這兩點,估計問題就能解決。
㈣ oracle存儲過程報937錯誤
oracle存儲過程報937錯誤的處理辦法如下:
(一)Oracle 存儲過程異常處理
1、異常的優點
使用異常,可以方便處理錯誤,而且異常處理程序與正常的事務邏輯分開,提高了可讀性,如
BEGIN
SELECT ...
SELECT ...
SELECT ...
...
EXCEPTION
WHEN NO_DATA_FOUND THEN -- catches all 』no data found』 errors
2、異常的分類
有兩種類型的異常,一種為內部異常,一種為用戶自定義異常.
內部異常是執行期間返回到PL/SQL塊的ORACLE錯誤或由PL/SQL代碼的某操作引起的錯誤,如除數為零或內存溢出的情況。用戶自定義異常由開發者顯示定義,在PL/SQL塊中傳遞信息以控制對於應用的錯誤處理。
每當PL/SQL違背了ORACLE原則或超越了系統依賴的原則就會隱式的產生內部異常。因為每個ORACLE錯誤都有一個號碼並且在PL/SQL中異常通過名字處理,ORACLE提供了預定義的內部異常。如SELECT INTO 語句不返回行時產生的ORACLE異常NO_DATA_FOUND。對於預定義異常,現將最常用的異常列舉如下:
exception oracle error sqlcode value condition
no_data_found ora-01403 +100 select into 語句沒有符合條件的記錄返回
too_many_rows ora-01422 -1422 select into 語句符合條件的記錄有多條返回
p_val_on_index ora-00001 -1 對於資料庫表中的某一列,該列已經被限制為唯一索引,程序試圖存儲兩個重復的值
value_error ora-06502 -6502 在轉換字元類型,截取或長度受限時,會發生該異常,如一個字元分配給一個變數,而該變數聲明的長度比該字元短,就會引發該異常
storage_error ora-06500 -6500 內存溢出
zero_divide ora-01476 -1476 除數為零
case_not_found ora-06592 -6530 對於選擇case語句,沒有與之相匹配的條件,同時,也沒有else語句捕獲其他的條件
cursor_already_open ora-06511 -6511 程序試圖打開一個已經打開的游標
timeout_on_resource ora-00051 -51 系統在等待某一資源,時間超時
如果要處理未命名的內部異常,必須使用OTHERS異常處理器或PRAGMA EXCEPTION_INIT。PRAGMA由編譯器控制,或者是對於編譯器的注釋。PRAGMA在編譯時處理,而不是在運行時處理。EXCEPTION_INIT告訴編譯器將異常名與ORACLE錯誤碼結合起來,這樣可以通過名字引用任意的內部異常,並且可以通過名字為異常編寫一適當的異常處理器。
在子程序中使用EXCEPTION_INIT的語法如下:
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);
在該語法中,異常名是聲明的異常,下例是其用法:
DECLARE
deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
BEGIN
... -- Some operation that causes an ORA-00060 error
EXCEPTION
WHEN deadlock_detected THEN
-- handle the error
END;
對於用戶自定義異常,只能在PL/SQL塊中的聲明部分聲明異常,異常的名字由EXCEPTION關鍵字引入:
reserved_loaned Exception
產生異常後,控制傳給了子程序的異常部分,將異常轉向各自異常控制塊,必須在代碼中使用如下的結構處理錯誤:
Exception
When exception1 then
Sequence of statements;
When exception2 then
Sequence of statements;
When others then
3、異常的拋出
由三種方式拋出異常
1. 通過PL/SQL運行時引擎
2. 使用RAISE語句
3. 調用RAISE_APPLICATION_ERROR存儲過程
當資料庫或PL/SQL在運行時發生錯誤時,一個異常被PL/SQL運行時引擎自動拋出。
異常也可以通過RAISE語句拋出
RAISE exception_name;
顯式拋出異常是程序員處理聲明的異常的習慣用法,但RAISE不限於聲明了的異常,它可以拋出任何任何異常。例如,你希望用TIMEOUT_ON_RESOURCE錯誤檢測新的運行時異常處理器,你只需簡單的在程序中使用下面的語句:
RAISE TIMEOUT_ON_RESOUCE;
比如下面一個訂單輸入的例子,若當訂單小於庫存數量,則拋出異常,並且捕獲該異常,處理異常
DECLARE
inventory_too_low EXCEPTION;
---其他聲明語句
BEGIN
IF order_rec.qty>inventory_rec.qty THEN
RAISE inventory_too_low;
END IF
EXCEPTION
WHEN inventory_too_low THEN
order_rec.staus:='backordered';
END;
RAISE_APPLICATION_ERROR內建函數用於拋出一個異常並給異常賦予一個錯誤號以及錯誤信息。自定義異常的預設錯誤號是+1,預設信息是User_Defined_Exception。RAISE_APPLICATION_ERROR函數能夠在pl/sql程序塊的執行部分和異常部分調用,顯式拋出帶特殊錯誤號的命名異常。 Raise_application_error(error_number,message[,true,false]))
錯誤號的范圍是-20,000到-20,999。錯誤信息是文本字元串,最多為2048位元組。TRUE和FALSE表示是添加(TRUE)進錯誤堆(ERROR STACK)還是覆蓋(overwrite)錯誤堆(FALSE)。預設情況下是FALSE。
如下代碼所示:
IF proct_not_found THEN
RAISE_APPLICATION_ERROR(-20123,'Invald proct code' TRUE);
END IF;
4、異常的處理
PL/SQL程序塊的異常部分包含了程序處理錯誤的代碼,當異常被拋出時,一個異常陷阱就自動發生,程序控制離開執行部分轉入異常部分,一旦程序進入異常部分就不能再回到同一塊的執行部分。下面是異常部分的一般語法:
EXCEPTION
WHEN exception_name THEN
Code for handing exception_name
[WHEN another_exception THEN
Code for handing another_exception]
[WHEN others THEN
code for handing any other exception.]
用戶必須在獨立的WHEN子串中為每個異常設計異常處理代碼,WHEN OTHERS子串必須放置在最後面作為預設處理器處理沒有顯式處理的異常。當異常發生時,控制轉到異常部分,ORACLE查找當前異常相應的WHEN..THEN語句,捕捉異常,THEN之後的代碼被執行,如果錯誤陷阱代碼只是退出相應的嵌套塊,那麼程序將繼續執行內部塊END後面的語句。如果沒有找到相應的異常陷阱,那麼將執行WHEN OTHERS。在異常部分WHEN 子串沒有數量限制。
EXCEPTION
WHEN inventory_too_low THEN
order_rec.staus:='backordered';
replenish_inventory(inventory_nbr=>
inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
WHEN discontinued_item THEN
--code for discontinued_item processing
WHEN zero_divide THEN
--code for zero_divide
WHEN OTHERS THEN
--code for any other exception
END;
當異常拋出後,控制無條件轉到異常部分,這就意味著控制不能回到異常發生的位置,當異常被處理和解決後,控制返回到上一層執行部分的下一條語句。
BEGIN
DECLARE
bad_credit exception;
BEGIN
RAISE bad_credit;
--發生異常,控制轉向;
EXCEPTION
WHEN bad_credit THEN
dbms_output.put_line('bad_credit');
END;
--bad_credit異常處理後,控制轉到這里
EXCEPTION
WHEN OTHERS THEN
--控制不會從bad_credit異常轉到這里
--因為bad_credit已被處理
END;
當異常發生時,在塊的內部沒有該異常處理器時,控制將轉到或傳播到上一層塊的異常處理部分。
BEGIN
DECLARE ---內部塊開始
bad_credit exception;
BEGIN
RAISE bad_credit;
--發生異常,控制轉向;
EXCEPTION
WHEN ZERO_DIVIDE THEN --不能處理bad_credite異常
dbms_output.put_line('divide by zero error');
END --結束內部塊
--控制不能到達這里,因為異常沒有解決;
--異常部分
EXCEPTION
WHEN OTHERS THEN
--由於bad_credit沒有解決,控制將轉到這里
END;
5、異常的傳播
沒有處理的異常將沿檢測異常調用程序傳播到外面,當異常被處理並解決或到達程序最外層傳播停止。在聲明部分拋出的異常將控制轉到上一層的異常部分。
BEGIN
executable statements
BEGIN
today DATE:='SYADATE'; --ERRROR
BEGIN --內部塊開始
dbms_output.put_line('this line will not execute');
EXCEPTION
WHEN OTHERS THEN
--異常不會在這里處理
END;--內部塊結束
EXCEPTION
WHEN OTHERS THEN
處理異常
END
(二)網上的解決方法是
set serveroutput on size 100000 (相當於把緩存設置大一點),但是我執行時候報錯 ORA-00922: missing or invalid option,之後還是修改了自己的語句,既然是輸出過多導致,我就將數據語句放在循環外面,這樣只要輸出語句小於緩存就可以了。
㈤ oracle pl/sql塊
..這個不用游標什麼的都可以
begin
update emp set 工資+100 where 部門號=10;
update emp set 工資+200 where 部門號=20;
update emp set 工資+300 where 部門號 !=10 or 部門號 !=2;
commit;
end;
㈥ Oracle資料庫如何在SQL代碼塊中用游標DROP多個表
修改如下:
㈦ 在oracle中 PL/sql程序塊必須包括哪幾部分
PL/SQL塊的結構如下:
DECLARE
/* 聲明部分: 在此聲明PL/SQL用到的變數,類型及游標,以及局部的存儲過程和函數 */
BEGIN
/* 執行部分: 過程及SQL 語句 , 即程序的主要部分 */
EXCEPTION
/* 執行異常部分: 錯誤處理 */
END;
其中 執行部分是必須的
㈧ oracle的plsql塊,存儲過程,函數怎麼寫增刪改查
首先在PL/SQL的左側資源欄中展開Proceres項(圖中位置1),然後再其上面的搜索框中(圖中位置2)輸入存過名稱的關鍵詞,按回車鍵搜索要調試的存過,不停的回車,直到找到想要調試的存過。
找到想要調試的存過,左鍵單擊選中該存過(圖中位置1),然後右鍵單擊該存過,從彈出菜單中選擇「Test」項(圖中位置2)。
單擊「Test」後,PL\SQL會打開調試界面,圖中位置1的按鈕就是開始調試的按鈕,在調試之前要填寫存過的參數,位置2就是填寫參數的地方,如果有多個參數,會有多行參數框,按參數名填寫相應的參數即可。
填寫完參數,單擊開始調試按鈕後,調試的界面會發生一些變化。圖中位置1的變化,說明存過已經處於執行狀態,別人不能再編譯或者執行。位置2的按鈕就是執行按鈕,單擊這個按鈕存過會執行完成或者遇到bug跳出,否則是不會停下來的,調試時不會用這個按鈕的。位置3的按鈕才是關鍵——單步執行,就是讓代碼一行一行的執行,位置4的按鈕是跳出單步執行,等待下一個指令。
單擊「單步執行」,存過開始單步執行。界面中每一次執行的代碼會高亮顯示(圖中位置1),如果想要看某個變數具體的值,就在位置2的地方輸入該變數名,然後變數的值會顯示在位置3的地方。
調試的時候,每一次單步執行的時候要記一下執行代碼的行數,圖中位置3的數字就是當前執行代碼的行數,就是第幾行。如果過程單步執行到某行後,再單步執行的時候,存過就退出,那麼錯誤就在該行的下一行。
代碼執行到24行,在往下執行時,直接轉到exception的地方,也就是異常處理的部分。
這說明我們代碼中的錯誤在24和25行上,我們打開存過,瀏覽到24行和25行附近,發現25行和24行使用了兩個變數,記住那兩個變數。重新開始調試過程。
單步的執行時候把剛才那兩個變數名填寫到變數查看框,一邊觀察變數值變化,一邊單步執行,執行到24行的時候,發現一個變數已經有值了,而另一個變數的值為null。錯誤原因明朗了吧?就是變數沒有賦值或者初始話,給該變數賦值後存過就不報錯了。