Oracleloopsql
❶ Oracle中使用PL/sql怎樣用循環插入多條數據
使用loop循環,比如:
for
item
in
(select
a,b,c
from
table_a
where
條件)
loop
insert
into
table_b(a,b,c)
values
(item.a,item.b,item.c);
end
loop;
也可以使用索引表循環,以上只是一個簡單的例子,需要根據你的具體情況選擇循環方式
❷ oracle菜鳥提問:SQL中 循環的用法
你這個要 定義個 游標, 然後 游標循環
一個游標處理的例子:
SQL> DECLARE
2 v_id INT;
3 v_value VARCHAR(10);
4 -- 定義游標.
5 CURSOR c_test_main IS
6 SELECT id, value FROM test_main;
7 BEGIN
8 -- 打開游標.
9 OPEN c_test_main;
10 -- 填充數據.
11 FETCH c_test_main INTO v_id, v_value;
12 -- 假如檢索到了數據,才處理.
13 WHILE c_test_main%FOUND LOOP
14 dbms_output.put_line(v_value);
15 -- 填充下一條數據.
16 FETCH c_test_main INTO v_id, v_value;
17 END LOOP;
18 -- 關閉游標
19 CLOSE c_test_main;
20 END;
21 /
TWO
THREE
ONE
PL/SQL procere successfully completed.
❸ Oracle PL/SQL求大神指點如何改成while和loop形式(最好注釋下)初學者謝謝
這個還是比較簡單的啊,你看你的例子裡面:
for j in 2..trunc(i/2) loop 就是說用一個計數器j從2到i/2取整(截斷)循環這么多次,end loop就標志這段循環結束了,單獨一句exit;就是從這句跳出循環,你想改成while,while是這么寫的:
while true loop
...;
end loop;
那你可以仿造這個for,你在declare部分加一個j的申明並初始化,for循環開頭就寫成
while j < trunc(i/2) loop
其他都不用變了,具體這個條件怎麼寫,是要和你初始化j同步的,要保證和原來的循環次數一樣,假如說你的j也初始化為2,那麼條件就是j !> trunc(i/2),外層i循環同理
❹ oracle中超難的sql,橫向統計,需要大俠們幫幫,讓所有疑問的人都能得到幫助,回答請給出例子
主要目的動態拼出如下sql
select tb.time,
max(case
when tb.id = 1 then
user1
end) as a001,
max(case
when tb.id = 2 then
user1
end) as a002,
max(case
when tb.id = 3 then
user1
end) as a003
from tb
group by tb.time;
--以下為測試部分
create table ta (id int,name varchar2(20));
create table tb (id1 int,time varchar2(20),user1 varchar2(20),id int);
insert into ta values(1,'a001');
insert into ta values(2,'a002');
insert into ta values(3,'a003');
insert into tb values(1,'2011-01-01','u001',1);
insert into tb values(2,'2011-01-01','u002',2);
insert into tb values(3,'2011-01-01','u003',3);
insert into tb values(4,'2011-01-02','u004',1);
insert into tb values(5,'2011-01-02','u001',2);
insert into tb values(6,'2011-01-02','u001',3);
create or replace procere test_p
as
sql_str varchar2(10000);
begin
for rec in ( select * from ta ) loop
sql_str := sql_str||'max(case when tb.id = '||rec.id||' then user1 end) as '|| rec.name ||',' ;
end loop;
sql_str := 'select tb.time, '||rtrim(sql_str,',')||' from tb group by tb.time';
--dbms_output.put_line(sql_str);
execute immediate sql_str;
end;
最後執行test_p 就能達到你想要的效果了。
❺ 在oracle中創建一個存儲過程,來循環獲取 a表中存放的查詢sql語句 並一條一條的執行該sql語句並存下來。
CREATE
OR
REPLACE
PACKAGE
BODY
PKG_A_TESTPACKAGE
IS
PROCEDURE
PKG_A_TESTPROCEDURE(PRM_參數
IN
VARCHAR2,
PRM_返回值
OUT
NUMBER,
PRM_錯誤信息
OUT
VARCHAR2)
IS
TYPE
CURSOR_TYPE
IS
REF
CURSOR;
CUR_SQL
CURSOR_TYPE;
TYPE
TYP_REC_INFO
IS
RECORD(
COLUMN
VARCHAR2(1000));
LREC_INFO
TYP_REC_INFO;
BEGIN
PRM_返回值
:=
0;
--
循環獲取查詢SQL
FOR
REC_SQL
IN
(SELECT
查詢SQL
FROM
存放SQL的表
WHERE
條件)
LOOP
BEGIN
OPEN
CUR_SQL
FOR
REC_SQL.查詢SQL;
LOOP
--
獲取查詢的信息
FETCH
CUR_SQL
INTO
LREC_INFO;
--存放查詢結果,這里只針對單列的查詢結果
--
如果沒有取到退出
EXIT
WHEN
CUR_SQL%NOTFOUND;
END
LOOP;
CLOSE
CUR_SQL;
END;
END
LOOP;
EXCEPTION
WHEN
OTHERS
THEN
PRM_返回值
:=
-1;
PRM_錯誤信息
:=
'執行PKG_A_TESTPROCEDURE出錯';
END
PKG_A_TESTPROCEDURE;
END
PKG_A_TESTPACKAGE;
按照你的思路寫的,具體需要根據你自己實際需求修改擴充一下
❻ oracle sql 管道函數是什麼
oracle管道函數是一類特殊的函數,關鍵字PIPELINED表明這是一個oracle管道函數,oracle管道函數返回值類型必須為集合。
例子:
create or replace function f_pipeline_test
return MsgType
PIPELINED
as
begin
for i in 1 .. 10
loop
pipe row( 'Iteration ' || i || ' at ' || systimestamp );
dbms_lock.sleep(1);
end loop;
pipe row( 'All done!' );
return;
end;
/
❼ oracle存儲過程循環執行SQL語句
實現方式錯了,批量移動數據應該使用Cursor,而不是像分頁那樣每次都查詢。
每次都查詢可能會導致重復數據。
正確方式應該是打開一個Cursor,循環Cursor來插入,使用計數器來控制每次COMMIT的行數:
declare
TYPE R_CURSOR IS REF CURSOR;
i number;
a1_cursor R_CURSOR;
a1_row A1%ROWTYPE;
begin
open a1_cursor FOR
select ID, NAME from A1;
i := 0;
loop
fetch a1_cursor
into a1_row;
exit when a1_cursor%notfound;
INSERT INTO A2 VALUES a1_row;
i := i + 1;
if i >= 5 then
commit;
i := 0;
end if;
end loop;
close a1_cursor;
commit;
end;
❽ Oracle中使用PL/SQL怎樣用循環插入多條數據
使用loop循環,比如:
for item in (select a,b,c from table_a where 條件) loop
insert into table_b(a,b,c) values (item.a,item.b,item.c);
end loop;
也可以使用索引表循環,以上只是一個簡單的例子,需要根據你的具體情況選擇循環方式。
❾ 如何使用oracle提供的SQL
Sql性能非常差的時候,oracle提供了SQL_TRACE來跟蹤sql的執行情況。
註:分析sql的方式比較多,還有根據優化器、sql執行計劃來分析。
SQL_TRACE能夠將sql執行的過程輸出到一個trace文件裡面。
首先設置自己定義的trace文件的標識方便查找。
alter session set tracefile_identifier='mytest';
然後對當前會話啟動SQL_TRACE,最好不要一直打開該開關,代價比較大。
alter session set sql_trace=true;
然後我們執行一條sql語句。
最後關閉該開關的狀態。
alter session set sql_trace=false;
我們可以從目錄%ORACLE_BASE%/diag/rdbms/orcl/orcl/trace(11g版本的路徑,如果是10g的應該不一樣)中
找到自己定義的trace文件。
原始的trace文件的可讀性不高,我們一般使用oracle自帶的工具,tkprof來處理這個trace文件。我們可以查看tkprof的幫助。
tkprof orcl_ora_3820_mytest.trc out.txt
我們來看剛才生成的trace文件,頭部信息描述了tkprof 的版本以及報告中一些列的含義,對於任何一條sql語句,都應該包含Parse—sql分析階段,Execute—sql執行階段,Fetch—數據提取階段,橫向的列如圖所示,包含消耗cpu時間0.00秒,操作總耗時0.04秒,物理讀取了0個數據塊,沒有發生current方式的讀取(一般在update會發生),一共提取記錄1條。
Misses in library cache ring parse: 0表示這是一次軟分析(關於硬分析和軟分析下面會接著談到)
Optimizer mode: ALL_ROWS表示oracle的優化器模式為ALL_ROWS。這也就是前面提到的另外的分析方式優化器。
下面是sql執行的具體計劃,可以看到執行計劃選擇的是全表掃描。
經過處理以後的trace文件的確比較容易看明白,它有助於我們分析sql的性能問題。
下面我通過一個trace實例來解釋一下,為什麼OLTP系統中需要變數綁定機制。
當用戶和資料庫建立連接,並發送一條sql語句以後,oracle會對該sql進行hash函數運算(hash演算法提供了一種快速存取數據的方法,它用一種演算法建立鍵值與真實值之間的對應關系,每一個真實值只能有一個鍵值,但是一個鍵值可以對應多個真實值,以方便存取),得到一個hash值,然後到共享池中尋找是否有匹配的hash值的sql存在,如果有,就直接使用該sql的執行計劃去執行sql。如果沒有,oracle就會認為這是一條新的sql語句,然後按照語法分析,語義分析,生成執行計劃,執行sql這些步驟來執行最終把結果返回給用戶。這些步驟也被成為硬分析,可以想像,如果減少硬分析,能夠大大降低資料庫花費在sql解析上的資源開銷。
我們先執行一條sql 1000次,比較綁定變數和不綁定變數的差異。得到結果以後,要計算實際的消耗,我們需要把OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS以及OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS的時間累計起來,前者表示數據字典表的相關的信息,包含許可權控制等,後者表示sql所衍生出的遞歸sql語句的信息。可以看到綁定變數的,整條語句執行時間為0.22+0.02=0.24秒,CPU時間0.18+0.03=0.21秒,分析次數3次,執行次數1003次。而不綁定變數的時候,整條語句執行時間為0.28+1.29=1.57秒,CPU時間0.31+1.26=1.57秒,分析次數1002次,執行次數1003次。可見綁定變數的確能夠帶來更低的開銷。(如何設計資料庫中使用綁定變數也是和系統息息相關的,很多資料庫問題都是在設計以後就已經存在的)
應用級調優分析:
就通常所說的三層架構來說,中間件這一層能夠起到一個緩沖池的作用,如果並發用戶數到3000這個數量級的時候,中間件能夠控制不是所有的用戶都能直接連接到資料庫,當然這里的程序會快速響應用戶請求,保證緩沖池的隊列等待不會很久。
對應用這一級別的調優,主要集中在app程序,中間件的監控,集群配置等方面。如果是發現應用級別的問題,首先要分析是配置問題,還是程序本身的問題。如果並發用戶數很大,中間件的線程池最大值配置過小,會導致在請求隊列堆積,表現就是線程監控視圖中,請求的隊列堆積比較多,一般可以調整線程池最大值來解決。我們來看看weblogic的監控視圖。
考慮到如果為每一個請求都創建一個新線程來處理的話,那麼我們難以在系統中實現足夠數量的線程。不受限制的創建線程可能耗盡系統資源,因此引入了線程池。線程池的思想是在進程開始時創建一定數量的線程並將它們置入一個池(pool)中,線程在這個池中等待工作。當伺服器接收到一個請求時,它就從池中喚醒一個線程(如果有可用的線程),由它來處理請求。一旦線程服務完畢,它就返回線程池等待後面的工作。
線程池利用已存在的線程服務請求要比等待創建一個線程要快,並且線程池限制了線程的數量。
如果懷疑是程序的問題,我們一般可以通過java自帶的工具來幫助分析,工具很多。這里我主要提到一個jdk1.6以後附帶的jvisualvm。
我們打開jdk1.6,找到並運行jvisualvm.exe。
我們發現應用程序分為本地,遠程兩部分。本地包含本地運行的java進程,遠程能夠通過配置連接到遠程伺服器上的java進程。我們先啟動一個tomcat。可以看到本地應用程序已經打開了一個帶有tomcat以及進程標識id的菜單。雙擊打開。這里我們一般關心2個視圖。監視、線程。
其中監視視圖比較關心垃圾回收活動(顧名思義,回收那些在程序裡面不再使用到的內存空間),堆內存變化。如果在壓力測試過程中,堆內存變化是一個逐漸上漲的趨勢,並且經過多次手動gc回收,還是保持這個趨勢,說明內存泄漏的可能性很大。如果猜測有內存泄漏,可以通過分析java的heap mp。JVM (java虛擬機)記錄下問題發生時系統的運行狀態並將其存儲在轉儲(mp)文件中。Heap mp就是這樣一種文件形式。
線程視圖比較關心線程的當前執行狀態,這里可以生成另一種轉儲文件 Java mp。Java mp,也叫做 Thread mp,是 JVM 故障診斷中最重要的轉儲文件之一。JVM 的許多問題都可以使用這個文件進行診斷,其中比較典型的包括線程阻塞,CPU 使用率過高,JVM Crash,堆內存不足,和類裝載等問題。其中線程阻塞更加常見。
原文轉自:http://blog.csdn.net/xuyubotest/article/details/8158241
❿ oracle sql怎麼寫循環語句
declare
sql_tem Varchar2(4000);
a number;
b number;
i number;
begin
a := 1;
for i in 1 .. 3 loop
b := a + 4;
sql_tem := 'insert into A2 (ID,NAME) (select ID,NAME from A1 WHERE ROWNUM between :1 and :2)';
EXECUTE IMMEDIATE sql_tem
USING a, b;
commit;
a := a + 5;
end loop;
end;
試試上面的代碼看一下能不能滿意你的要求先唄。。。