日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

plsql动态的sql

發布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 plsql动态的sql 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


12 動態SQL語句和動態PLSQL語句

?SQL語句 --? 靜態的SQL語句、動態的SQL語句

?靜態的SQL語句? --? 在編譯的時候已經確定的SQL,語法和語義引用也是在編譯的時候確定下來的?? ?
?動態的SQL語句? --? 由字符串組成,在運行的時候編譯和執行

12.1 動態SQL語句

(1) 動態SQL的簡單案例

案例1: 動態創建表示例
?
declare
? dyn_tab_name varchar2(30):='temp';
? dyn_string varchar2(150);
begin
? dyn_string:='create table '||dyn_tab_name||' (col number not null)';
? execute immediate dyn_string;??????????????????? --動態運行,在匿名塊里面調用DDL,要加execute immediate
end;

SQL> desc temp;
Name Type?? Nullable Default Comments
---- ------ -------- ------- --------
COL? NUMBER????????????????????????? ?
?
改寫為存儲過程:
create or replace procedure p21 is
? dyn_tab_name varchar2(30):='temp';
? dyn_string varchar2(150);
begin
? dyn_string:='create taeble '||dyn_tab_name||' (col number not null)'; --有語法錯誤的,但是編譯的時候不會報錯
? execute immediate dyn_string;????????????? ?
end;

SQL> exec p21;????????????? --在執行的時候報錯
BEGIN p21; END;

*
ERROR at line 1:
ORA-00901: invalid CREATE command
ORA-06512: at "PLSQL.P21", line 6
ORA-06512: at line 1

create or replace procedure p21 is
? dyn_tab_name varchar2(30):='temp';
? dyn_string varchar2(150);
begin
? dyn_string:='create table '||dyn_tab_name||' (col number not null)';
? execute immediate dyn_string;????????????? ?
end;

SQL> exec p21;
BEGIN p21; END;

*
ERROR at line 1:
ORA-01031: insufficient privileges????????????? --權限不足
ORA-06512: at "PLSQL.P21", line 6
ORA-06512: at line 1

create or replace procedure p21 authid current_user is????????? --正確的寫法
?--在存儲過程中出現動態SQL的時候,需要在SP的頭部加上authid current_user顯式授權語句,將執行的權限授給當前的用戶
? dyn_tab_name varchar2(30):='temp1';
? dyn_string varchar2(150);
begin
? dyn_string:='create table '||dyn_tab_name||' (col number not null)';
? execute immediate dyn_string;????????????? ?
end;

SQL> exec p21;

PL/SQL procedure successfully completed.

SQL> desc temp1;
?Name?? ??? ??? ??? ??? ??? Null???? Type
?----------------------------------------- -------- ----------------------------
?COL?? ??? ??? ??? ??? ??? NOT NULL NUMBER

總結:在存儲過程中使用動態SQL語句,如果SQL語句語法有問題,在編譯的時候不會報錯,只有在調用SP的時候才會報錯
? 在存儲過程中出現動態SQL的時候,需要在SP的頭部加上authid current_user顯式授權語句,將執行的權限授給當前的用戶

?
案例2:動態創建表

create or replace procedure create_dyn_table(i_region_name in varchar2,retcd out number,errmsg out varchar2) authid current_user is
? dyn_tab_name varchar2(200);
? dyn_string varchar2(2000);
begin
? dyn_string:='';
? dyn_tab_name:='ORDERS_FOR_'||replace(i_region_name,' ','');?? --去掉空格
? dyn_string:='create table '||dyn_tab_name||' (order_id number(10) primary key,order_date date not null,total_qty number,total_price number(15,2))';
? execute immediate dyn_string;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(100);
begin
? create_dyn_table('? u? k? ',v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;

select * from orders_for_uk;

案例3:通過動態SQL給表添加外鍵

create or replace procedure create_dyn_table2(i_region_name in varchar2,retcd out number,errmsg out varchar2) authid current_user is
? dyn_tab_name varchar2(200);
? dyn_string varchar2(2000);
begin
? dyn_tab_name:='ORDERS_ITEMS_FOR_'||replace(i_region_name,' ','');
? dyn_string:='create table '||dyn_tab_name||' (order_id number(10) not null,item_id varchar2(20) not null,unit_pirce number(15,2),quantity number)';
? execute immediate dyn_string;
? dyn_string:='alter table '||dyn_tab_name||' add constraint '||' FK_OIFOR_'||replace(i_region_name,' ','')||' foreign key(order_id) references orders_for_'||replace(i_region_name,' ','')||'(order_id)';
? execute immediate dyn_string;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(100);
begin
? create_dyn_table2('? u? k? ',v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;

select * from orders_items_for_uk;
select * from user_constraints where table_name='ORDERS_ITEMS_FOR_UK';


案例4:按照地區配置表,創建每個銷售區域訂單表跟訂單明細表

地區配置表:
insert into region_tab values(1,'region1');
insert into region_tab values(2,'region2');
insert into region_tab values(3,'region3');
insert into region_tab values(4,'region4');
commit;

select * from region_tab;

region_tab? ->? orders_for_
??????????? ->? orders_items_for_

有四個銷售區域,每個銷售區域需要有訂單表跟訂單明細表,表的結構都是一樣的

create or replace procedure create_dyn_for_all(retcd out number,errmsg out varchar2) authid current_user is
? cursor csr_region is select * from region_tab;
begin
? for idx in csr_region loop
??? create_dyn_table(idx.region_name,retcd,errmsg);
??? if retcd <> 0 then
????? exit;
??? end if;
??? create_dyn_table2(idx.region_name,retcd,errmsg);
??? if retcd <> 0 then
????? exit;
??? end if;
? end loop;
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(100);
begin
? create_dyn_for_all(v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;

select * from user_tables where table_name like 'ORDERS%';????? --查看到新創建了8個表


(2) 動態創建表

? 設計方式--根據配置表動態實現功能,只需要維護外面的配置表的內容,將功能封裝

? 需求:字段名和表名都用配置表來配置,實現動態創建表的過程

? 步驟:

? A 創建表1:配置表名

create table table_config(
tab_id number primary key,
table_name varchar2(20) not null,
crt_flag varchar2(2)
);
?
?B 插入初始化數據:

insert into table_config values(1,'A','0');
insert into table_config values(2,'B','0');
commit;

?C 創建表2:配置字段的表

create table column_config(
col_id number not null,
tab_id number not null,
col_name varchar2(20),
col_type varchar2(20),
col_length number,
col_pre number
);

添加主外鍵:
alter table column_config add constraint PK_COL_CFG primary key(col_id,tab_id);
alter table column_config add constraint FK_COL_CFG foreign key(tab_id) references table_config(tab_id);
?
?D 初始化字段表

insert into column_config values(1,1,'A1','varchar2',20,null);
insert into column_config values(2,1,'A2','char',3,null);
insert into column_config values(3,1,'A3','number',12,null);
insert into column_config values(4,1,'A4','number',11,4);
insert into column_config values(5,1,'A5','date',null,null);

insert into column_config values(6,2,'B1','varchar2',22,null);
insert into column_config values(7,2,'B2','char',13,null);
insert into column_config values(8,2,'B3','number',20,null);
insert into column_config values(9,2,'B4','date',null,null);
insert into column_config values(10,2,'B5','number',12,2);
commit;

E 編寫功能模塊

模塊1:讀取字段配置表進行字段類型串的拼接
?
create or replace function dyn_type(i_type in varchar2,i_length in number,i_pre in number) return varchar2 is
? v_dyn_type varchar2(1000);
begin
? if i_type='varchar2' then
??? v_dyn_type:=i_type||'('||i_length||')';
? elsif i_type='char' then
??? v_dyn_type:=i_type||'('||i_length||')'; ?
? elsif i_type='date' then
??? v_dyn_type:=i_type;
? elsif i_type='number' then
??? if i_length is not null and i_pre is not null then
????? v_dyn_type:=i_type||'('||i_length||','||i_pre||')';
??? elsif i_length is not null and i_pre is null then
????? v_dyn_type:=i_type||'('||i_length||')';
??? elsif i_length is null and i_pre is null then
????? v_dyn_type:=i_type;
??? end if;
? end if;
? return v_dyn_type;
exception when others then
? return '';
end;

模塊2:拼接創建表語句中類型模塊

create or replace procedure dyn_crt_tab(i_tab_name in varchar2,i_crt_string out varchar2,retcd out number,errmsg out varchar2) authid current_user is
? cursor csr_tab is select h.tab_id,h.table_name,o.col_type,o.col_name,o.col_length,o.col_pre
????????????????????? from column_config o,table_config h
???????????????????? where o.tab_id=h.tab_id
?????????????????????? and h.table_name=i_tab_name;
? csr_rec csr_tab%rowtype;
? dyn_col_type varchar2(100);
? dyn_tab_p varchar2(4000);
begin
? open csr_tab;
? dyn_tab_p:='';
? loop
??? fetch csr_tab into csr_rec;
??? exit when (csr_tab%notfound);
??? dyn_col_type:=dyn_type(csr_rec.col_type,csr_rec.col_length,csr_rec.col_pre)||',';?? --調用拼接字段的函數
??? dyn_tab_p:=dyn_tab_p||csr_rec.col_name||' '||dyn_col_type;
? end loop;
??? dyn_tab_p:=substr(dyn_tab_p,1,instr(dyn_tab_p,',',-1,1)-1);? --將最后一個','去掉
??? i_crt_string:=dyn_tab_p;
? close csr_tab;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

模塊3:執行模塊

create or replace procedure dyn_crt(retcd out number,errmsg out varchar2) authid current_user is
? cursor csr_tab is select h.tab_id,h.table_name
????????????????????? from table_config h
???????????????????? where h.crt_flag='0';
? csr_rec csr_tab%rowtype;
? dyn_string varchar2(4000);
? v_crt_table varchar2(4000);
? v_sqlcode number;
? v_sqlerrm varchar2(200);
begin
? open csr_tab;
? dyn_string:='';
? loop
??? fetch csr_tab into csr_rec;
??? exit when(csr_tab%notfound);
??? dyn_crt_tab(csr_rec.table_name,v_crt_table,v_sqlcode,v_sqlerrm);??????????????? --調用表拼接的存儲過程
??? dyn_string:='create table '||csr_rec.table_name||'('||v_crt_table||')';??? ?
??? execute immediate dyn_string;
??? update table_config set crt_flag='1' where tab_id=csr_rec.tab_id;
??? commit;
? end loop;
? close csr_tab;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;


測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(200);
begin
? dyn_crt(v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;


SQL> desc a
?Name?? ??? ??? ??? ??? ??? Null???? Type
?----------------------------------------- -------- ----------------------------
?A1?? ??? ??? ??? ??? ??? ???? VARCHAR2(20)
?A2?? ??? ??? ??? ??? ??? ???? CHAR(3)
?A3?? ??? ??? ??? ??? ??? ???? NUMBER(12)
?A4?? ??? ??? ??? ??? ??? ???? NUMBER(11,4)
?A5?? ??? ??? ??? ??? ??? ???? DATE

SQL> desc b
?Name?? ??? ??? ??? ??? ??? Null???? Type
?----------------------------------------- -------- ----------------------------
?B1?? ??? ??? ??? ??? ??? ???? VARCHAR2(22)
?B2?? ??? ??? ??? ??? ??? ???? CHAR(13)
?B3?? ??? ??? ??? ??? ??? ???? NUMBER(20)
?B4?? ??? ??? ??? ??? ??? ???? DATE
?B5?? ??? ??? ??? ??? ??? ???? NUMBER(12,2)

練習:
?
?A 將上面3個子程序封裝在一個package中存儲,其中函數還有另外一個存儲作為私有對象。

?在包頭加上authid current_user
?存儲過程中authid current_user去掉

?B 開發一個動態drop表的SP封裝在上面創建的包中,要求,在table_config表上添加一個字段,drop_flag varchar2(2)
??? 刪除標記,如果為1,表示要刪除,如果為0表示保留,將所有標記為1的表刪除掉,如果刪除的時候發現已經被刪除了,則要捕獲異常將數據插入到我們之前創建異常監控表中,與此同時創建標記crt_flag置為0

??? alter table table_config add drop_flag varchar2(2);

?C 開發動態刪除和添加字段的模塊,需要在字段配置表上添加刪除和添加的標記字段。
?
??? alter table column_config add add_flag varchar2(2);
??? alter table column_config add del_flag varchar2(2);

包頭:
create or replace package dyn_pkg authid current_user is
? procedure dyn_crt(retcd out number,errmsg out varchar2);
? procedure dyn_drop(retcd out number, errmsg out varchar2);
? procedure dyn_add(retcd out number, errmsg out varchar2);
? procedure dyn_del(retcd out number, errmsg out varchar2);
end dyn_pkg;

包體:

create or replace package body dyn_pkg is

?function dyn_type(i_type in varchar2,i_length in number,i_pre in number)
??? return varchar2 is
??? v_dyn_type varchar2(1000);
? begin
??? if i_type='VARCHAR2' then
????? v_dyn_type:=i_type||'('||i_length||')';
??? elsif i_type='CHAR' then
????? v_dyn_type:=i_type||'('||i_length||')';
??? elsif i_type='DATE' then
????? v_dyn_type:=i_type;
??? elsif i_type='NUMBER' then
????? if i_length is not null and i_pre is not null then
??????? v_dyn_type:=i_type||'('||i_length||','||i_pre||')';
????? elsif i_length is not null and i_pre is? null then
??????? v_dyn_type:=i_type||'('||i_length||')';
????? elsif i_length is? null and i_pre is? null then
??????? v_dyn_type:=i_type;
????? end if;
??? end if;
??? return v_dyn_type;
? exception when others then
??? return '';
? end;


?procedure dyn_crt_tab(i_tab_name in varchar2,i_crt_string out varchar2,retcd out number,errmsg out varchar2) is
??? cursor csr_tab is select h.tab_id,h.table_name,o.col_type,o.col_name,o.col_length,o.col_pre
?????????????? from column_config o,table_config h
????????????? where o.tab_id=h.tab_id
??????????????? and h.table_name=i_tab_name;
??? csr_rec csr_tab%rowtype;
??? dyn_col_type varchar2(100);
??? dyn_tab_p varchar2(4000);
? begin
??? open csr_tab;
??? dyn_tab_p:='';
??? loop
????? fetch csr_tab into csr_rec;
????? exit when(csr_tab%notfound);
????? dyn_col_type:=dyn_type(csr_rec.col_type,csr_rec.col_length,csr_rec.col_pre)||',';?? --調用拼接字段的函數
????? dyn_tab_p:=dyn_tab_p||csr_rec.col_name||' '||dyn_col_type;
??? end loop;
??? dyn_tab_p:=substr(dyn_tab_p,1,instr(dyn_tab_p,',',-1,1)-1);??? --將最后一個‘,’去掉
??? i_crt_string:=dyn_tab_p;
??? close csr_tab;
??? retcd:=0;
??? errmsg:='successful!';
? exception when others then
??? retcd:=sqlcode;
??? errmsg:=sqlerrm;
? end;


?procedure dyn_crt(retcd out number,errmsg out varchar2) is
??? cursor csr_tab is select h.tab_id,h.table_name
???????????????? from table_config h
??????????????? where h.crt_flag='0';
??? csr_rec csr_tab%rowtype;
??? dyn_string varchar2(4000);
??? v_crt_table varchar2(4000);
??? v_retcd number;
??? v_errmsg varchar2(150);
? begin
??? open csr_tab;
??? dyn_string:='';
??? loop
????? fetch csr_tab into csr_rec;
????? exit when(csr_tab%notfound);
????? dyn_crt_tab(csr_rec.table_name,v_crt_table,v_retcd,v_errmsg);??? --調用表拼接的函數
????? dyn_string:='create table '||csr_rec.table_name||'('||v_crt_table||')';
????? execute immediate dyn_string;
????? update table_config set crt_flag='1' where tab_id=csr_rec.tab_id;
????? commit;
??? end loop;
??? close csr_tab;
??? retcd:=0;
??? errmsg:='successful!';
? exception when others then
??? retcd:=sqlcode;
??? errmsg:=sqlerrm;
? end;

? procedure dyn_drop(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_drop is
?? ??? ???? select table_name, tab_id
?? ??? ?????? from table_config
?? ??? ????? where drop_flag = '1';
?? ??? ?csr_rec csr_drop%rowtype;
?? ??? ?dyn_drop_config varchar2(100);
?? ??? ?sqlnotfound exception;
?? ??? ?pragma exception_init(sqlnotfound,-942);
?? ??? ?v_sqlcode number;
?? ??? ?v_sqlerrm varchar2(100);
?? ???? begin
?? ??? ?open csr_drop;
?? ??? ?dyn_drop_config := '';
?? ??? ?loop
?? ??? ???? fetch csr_drop
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_drop%notfound);
?? ??? ???? dyn_drop_config := 'drop table ' || csr_rec.table_name;
?? ??? ???? execute immediate dyn_drop_config;
?? ??? ?end loop;
?? ??? ?close csr_drop;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful';
?? ???? exception
?? ??? ?when sqlnotfound then
?? ??? ?v_sqlcode:=sqlcode;
?? ??? ?v_sqlerrm:=sqlerrm;
?? ??? ???? insert into exception_monitor?? ??? ???? values
?? ??? ???????? (csr_rec.table_name,
?? ??? ????????? csr_rec.tab_id,
?? ??? ????????? upper('dyn_drop'),
?? ??? ????????? upper('sqlnotfound'),
?? ??? ????????? v_sqlcode,
?? ??? ????????? v_sqlerrm,
?? ??? ????????? sysdate);
?? ??? ???? update table_config
?? ??? ??????? set drop_flag = '0'
?? ??? ????? where tab_id = csr_rec.tab_id;
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;

? procedure dyn_add(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_add is
?? ??? ???? select t.table_name,
?? ??? ??????????? t.tab_id,
?? ??? ??????????? c.col_id,
?? ??? ??????????? c.col_name,
?? ??? ??????????? c.col_type,
?? ??? ??????????? c.col_length,
?? ??? ??????????? c.col_pre
包頭:
create or replace package dyn_pkg authid current_user is
? procedure dyn_crt(retcd out number,errmsg out varchar2);
? procedure dyn_drop(retcd out number, errmsg out varchar2);
? procedure dyn_add(retcd out number, errmsg out varchar2);
? procedure dyn_del(retcd out number, errmsg out varchar2);
end dyn_pkg;

包體:

create or replace package body dyn_pkg is

?function dyn_type(i_type in varchar2,i_length in number,i_pre in number)
??? return varchar2 is
??? v_dyn_type varchar2(1000);
? begin
??? if i_type='VARCHAR2' then
????? v_dyn_type:=i_type||'('||i_length||')';
??? elsif i_type='CHAR' then
????? v_dyn_type:=i_type||'('||i_length||')';
??? elsif i_type='DATE' then
????? v_dyn_type:=i_type;
??? elsif i_type='NUMBER' then
????? if i_length is not null and i_pre is not null then
??????? v_dyn_type:=i_type||'('||i_length||','||i_pre||')';
????? elsif i_length is not null and i_pre is? null then
??????? v_dyn_type:=i_type||'('||i_length||')';
????? elsif i_length is? null and i_pre is? null then
??????? v_dyn_type:=i_type;
????? end if;
??? end if;
??? return v_dyn_type;
? exception when others then
??? return '';
? end;


?procedure dyn_crt_tab(i_tab_name in varchar2,i_crt_string out varchar2,retcd out number,errmsg out varchar2) is
??? cursor csr_tab is select h.tab_id,h.table_name,o.col_type,o.col_name,o.col_length,o.col_pre
?????????????? from column_config o,table_config h
????????????? where o.tab_id=h.tab_id
??????????????? and h.table_name=i_tab_name;
??? csr_rec csr_tab%rowtype;
??? dyn_col_type varchar2(100);
??? dyn_tab_p varchar2(4000);
? begin
??? open csr_tab;
??? dyn_tab_p:='';
??? loop
????? fetch csr_tab into csr_rec;
????? exit when(csr_tab%notfound);
????? dyn_col_type:=dyn_type(csr_rec.col_type,csr_rec.col_length,csr_rec.col_pre)||',';?? --調用拼接字段的函數
????? dyn_tab_p:=dyn_tab_p||csr_rec.col_name||' '||dyn_col_type;
??? end loop;
??? dyn_tab_p:=substr(dyn_tab_p,1,instr(dyn_tab_p,',',-1,1)-1);??? --將最后一個‘,’去掉
??? i_crt_string:=dyn_tab_p;
??? close csr_tab;
??? retcd:=0;
??? errmsg:='successful!';
? exception when others then
??? retcd:=sqlcode;
??? errmsg:=sqlerrm;
? end;


?procedure dyn_crt(retcd out number,errmsg out varchar2) is
??? cursor csr_tab is select h.tab_id,h.table_name
???????????????? from table_config h
??????????????? where h.crt_flag='0';
??? csr_rec csr_tab%rowtype;
??? dyn_string varchar2(4000);
??? v_crt_table varchar2(4000);
??? v_retcd number;
??? v_errmsg varchar2(150);
? begin
??? open csr_tab;
??? dyn_string:='';
??? loop
????? fetch csr_tab into csr_rec;
????? exit when(csr_tab%notfound);
????? dyn_crt_tab(csr_rec.table_name,v_crt_table,v_retcd,v_errmsg);??? --調用表拼接的函數
????? dyn_string:='create table '||csr_rec.table_name||'('||v_crt_table||')';
????? execute immediate dyn_string;
????? update table_config set crt_flag='1' where tab_id=csr_rec.tab_id;
????? commit;
??? end loop;
??? close csr_tab;
??? retcd:=0;
??? errmsg:='successful!';
? exception when others then
??? retcd:=sqlcode;
??? errmsg:=sqlerrm;
? end;

? procedure dyn_drop(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_drop is
?? ??? ???? select table_name, tab_id
?? ??? ?????? from table_config
?? ??? ????? where drop_flag = '1';
?? ??? ?csr_rec csr_drop%rowtype;
?? ??? ?dyn_drop_config varchar2(100);
?? ??? ?sqlnotfound exception;
?? ??? ?pragma exception_init(sqlnotfound,-942);
?? ??? ?v_sqlcode number;
?? ??? ?v_sqlerrm varchar2(100);
?? ???? begin
?? ??? ?open csr_drop;
?? ??? ?dyn_drop_config := '';
?? ??? ?loop
?? ??? ???? fetch csr_drop
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_drop%notfound);
?? ??? ???? dyn_drop_config := 'drop table ' || csr_rec.table_name;
?? ??? ???? execute immediate dyn_drop_config;
?? ??? ?end loop;
?? ??? ?close csr_drop;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful';
?? ???? exception
?? ??? ?when sqlnotfound then
?? ??? ?v_sqlcode:=sqlcode;
?? ??? ?v_sqlerrm:=sqlerrm;
?? ??? ???? insert into exception_monitor?? ??? ???? values
?? ??? ???????? (csr_rec.table_name,
?? ??? ????????? csr_rec.tab_id,
?? ??? ????????? upper('dyn_drop'),
?? ??? ????????? upper('sqlnotfound'),
?? ??? ????????? v_sqlcode,
?? ??? ????????? v_sqlerrm,
?? ??? ????????? sysdate);
?? ??? ???? update table_config
?? ??? ??????? set drop_flag = '0'
?? ??? ????? where tab_id = csr_rec.tab_id;
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;

? procedure dyn_add(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_add is
?? ??? ???? select t.table_name,
?? ??? ??????????? t.tab_id,
?? ??? ??????????? c.col_id,
?? ??? ??????????? c.col_name,
?? ??? ??????????? c.col_type,
?? ??? ??????????? c.col_length,
?? ??? ??????????? c.col_pre
?? ??? ?????? from table_config t, column_config c
?? ??? ????? where t.tab_id = c.tab_id
?? ??? ??????? and c.add_flag = '1';
?? ??? ?csr_rec csr_add%rowtype;
?? ??? ?dyn_col_type?? varchar2(200);
?? ??? ?dyn_add_string varchar2(4000);
?? ???? begin
?? ??? ?open csr_add;
?? ??? ?dyn_add_string := '';
?? ??? ?loop
?? ??? ???? fetch csr_add
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_add%notfound);
?? ??? ???? dyn_col_type?? := dyn_type(csr_rec.col_type,
?? ??? ??????????????????????????????? csr_rec.col_length,
?? ??? ??????????????????????????????? csr_rec.col_pre);
?? ??? ???? dyn_add_string := 'alter table ' || csr_rec.table_name ||
?? ??? ?????????????????????? ' add ' || csr_rec.col_name || ' ' ||
?? ??? ?????????????????????? dyn_col_type;
?? ??? ???? execute immediate dyn_add_string;
?? ??? ???? update column_config set add_flag='0' where tab_id=csr_rec.tab_id and col_id=csr_rec.col_id;
?? ??? ?end loop;
?? ??? ?close csr_add;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful!';
?? ???? exception
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;

? procedure dyn_del(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_del is
?? ??? ???? select t.table_name, c.col_name ,t.tab_id , c.col_id
?? ??? ?????? from table_config t, column_config c
?? ??? ????? where t.tab_id = c.tab_id
?? ??? ??????? and c.del_flag = '1';
?? ??? ?dyn_del_string varchar2(4000);
?? ??? ?csr_rec csr_del%rowtype;
?? ???? begin
?? ??? ?open csr_del;
?? ??? ?dyn_del_string := '';
?? ??? ?loop
?? ??? ???? fetch csr_del
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_del%notfound);
?? ??? ???? dyn_del_string := 'alter table ' || csr_rec.table_name ||
?? ??? ?????????????????????? ' drop column ' || csr_rec.col_name;
?? ??? ???? execute immediate dyn_del_string;
?? ??? ???? update column_config set del_flag='0' where tab_id=csr_rec.tab_id and col_id=csr_rec.col_id;
?? ??? ?end loop;
?? ??? ?close csr_del;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful!';
?? ???? exception
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;


end dyn_pkg;
?? ??? ?????? from table_config t, column_config c
?? ??? ????? where t.tab_id = c.tab_id
?? ??? ??????? and c.add_flag = '1';
?? ??? ?csr_rec csr_add%rowtype;
?? ??? ?dyn_col_type?? varchar2(200);
?? ??? ?dyn_add_string varchar2(4000);
?? ???? begin
?? ??? ?open csr_add;
?? ??? ?dyn_add_string := '';
?? ??? ?loop
?? ??? ???? fetch csr_add
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_add%notfound);
?? ??? ???? dyn_col_type?? := dyn_type(csr_rec.col_type,
?? ??? ??????????????????????????????? csr_rec.col_length,
?? ??? ??????????????????????????????? csr_rec.col_pre);
?? ??? ???? dyn_add_string := 'alter table ' || csr_rec.table_name ||
?? ??? ?????????????????????? ' add ' || csr_rec.col_name || ' ' ||
?? ??? ?????????????????????? dyn_col_type;
?? ??? ???? execute immediate dyn_add_string;
?? ??? ???? update column_config set add_flag='0' where tab_id=csr_rec.tab_id and col_id=csr_rec.col_id;
?? ??? ?end loop;
?? ??? ?close csr_add;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful!';
?? ???? exception
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;

??? procedure dyn_del(retcd out number, errmsg out varchar2) is
?? ??? ?cursor csr_del is
?? ??? ???? select t.table_name, c.col_name ,t.tab_id , c.col_id
?? ??? ?????? from table_config t, column_config c
?? ??? ????? where t.tab_id = c.tab_id
?? ??? ??????? and c.del_flag = '1';
?? ??? ?dyn_del_string varchar2(4000);
?? ??? ?csr_rec csr_del%rowtype;
?? ???? begin
?? ??? ?open csr_del;
?? ??? ?dyn_del_string := '';
?? ??? ?loop
?? ??? ???? fetch csr_del
?? ??? ???????? into csr_rec;
?? ??? ???? exit when(csr_del%notfound);
?? ??? ???? dyn_del_string := 'alter table ' || csr_rec.table_name ||
?? ??? ?????????????????????? ' drop column ' || csr_rec.col_name;
?? ??? ???? execute immediate dyn_del_string;
?? ??? ???? update column_config set del_flag='0' where tab_id=csr_rec.tab_id and col_id=csr_rec.col_id;
?? ??? ?end loop;
?? ??? ?close csr_del;
?? ??? ?retcd? := 0;
?? ??? ?errmsg := 'successful!';
?? ???? exception
?? ??? ?when others then
?? ??? ???? retcd? := sqlcode;
?? ??? ???? errmsg := sqlerrm;
?? ???? end;
end dyn_pkg;

###########################################################################################


12.2 動態PLSQL語句

(1) 動態單行select語句

A 錄入訂單表和訂單明細表的初始化數據

insert into orders_for_region1 values(1,sysdate,null,null);
insert into orders_items_for_region1 values(1,'A001',20,13);
insert into orders_items_for_region1 values(1,'A001',23,10);
insert into orders_items_for_region1 values(1,'A001',11,5);
commit;
?
B 創建SP,更新訂單表的值

create or replace procedure update_dyn_table(i_region_name in varchar2,i_order_id in number,retcd out number,errmsg out varchar2) authid current_user is
? dyn_upd_string varchar2(2000);
? dyn_query_string varchar2(1000);
? dyn_tab_name1 varchar2(30);
? dyn_tab_name2 varchar2(30);
? v_total_price number;
? v_total_quantity number;
begin
? dyn_tab_name1:='ORDERS_FOR_'||replace(i_region_name,' ','');
? dyn_tab_name2:='ORDERS_ITEMS_FOR_'||replace(i_region_name,' ','');
? dyn_query_string:='select sum(quantity),sum(quantity*unit_pirce) from '||dyn_tab_name2||' where order_id=:input_order_id';?? --:input_order_id表示綁定變量
? execute immediate dyn_query_string into v_total_quantity,v_total_price using i_order_id;
? dyn_upd_string:='update '||dyn_tab_name1||' set total_qty=:v_total_qty,total_price=:v_total_price where order_id=:input_order_id';
? execute immediate dyn_upd_string using v_total_quantity,v_total_price,i_order_id;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;


測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(200);
begin
? update_dyn_table('region1',1,v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;

查詢:

select * from orders_for_region1;

注意:
?A 動態PLSQL語句中,select語句需要用into來接收參數值
?B 綁定變量在動態PLSQL中,用冒號前置的方式來定義,不需要聲明
?C 執行的時候,綁定變量需要用using關鍵字來賦值

(2) 動態多行的select語句

?A 初始化數據

insert into orders_for_region1 values(2,sysdate,null,null);
insert into orders_items_for_region1 values(2,'A001',30,13);
insert into orders_items_for_region1 values(2,'A001',33,10);
insert into orders_items_for_region1 values(2,'A001',11,7);

insert into orders_for_region1 values(3,sysdate,null,null);
insert into orders_items_for_region1 values(3,'A001',50,13);
insert into orders_items_for_region1 values(3,'A001',63,7);
insert into orders_items_for_region1 values(3,'A001',21,5);

insert into orders_for_region1 values(4,sysdate,null,null);
insert into orders_items_for_region1 values(4,'A001',30,13);
insert into orders_items_for_region1 values(4,'A001',35,10);
insert into orders_items_for_region1 values(4,'A001',12,5);

commit;

?B 編寫SP實現多行的更新

create or replace procedure update_dyn_all_table(i_region_name in varchar2,retcd out number,errmsg out varchar2) authid current_user is
? dyn_upd_string varchar2(1000);
? dyn_query_string varchar2(1000);
? dyn_tab_name varchar2(30);
? v_total_price number;
? v_total_quantity number;
? type csr_dyn is ref cursor;
? csr_dyn1 csr_dyn;
? v_order_id number;
begin
? dyn_tab_name:='ORDERS_ITEMS_FOR_'||replace(i_region_name,' ','');
? dyn_query_string:='select distinct order_id from '||dyn_tab_name;
? open csr_dyn1 for dyn_query_string;?? --動態的方式打開游標
? loop
??? fetch csr_dyn1 into v_order_id;
??? exit when(csr_dyn1%notfound);
??? update_dyn_table(i_region_name,v_order_id,retcd,errmsg);
??? if retcd <> 0 then
????? exit;
??? end if;
? end loop;
? close csr_dyn1;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(200);
begin
? update_dyn_all_table('region1',v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;

驗證:
select * from orders_for_region1;


目前為止只是處理了一個銷售區域,總共有四個銷售區域,怎樣處理四個銷售區域用一個SP
A 初始化

insert into orders_for_region1 values(1,sysdate,null,null);
insert into orders_items_for_region1 values(1,'A001',30,13);
insert into orders_items_for_region1 values(1,'A001',33,10);
insert into orders_items_for_region1 values(1,'A001',11,7);

insert into orders_for_region1 values(2,sysdate,null,null);
insert into orders_items_for_region1 values(2,'A001',30,13);
insert into orders_items_for_region1 values(2,'A001',33,10);
insert into orders_items_for_region1 values(2,'A001',11,7);

insert into orders_for_region1 values(3,sysdate,null,null);
insert into orders_items_for_region1 values(3,'A001',50,13);
insert into orders_items_for_region1 values(3,'A001',63,7);
insert into orders_items_for_region1 values(3,'A001',21,5);

insert into orders_for_region1 values(4,sysdate,null,null);
insert into orders_items_for_region1 values(4,'A001',30,13);
insert into orders_items_for_region1 values(4,'A001',35,10);
insert into orders_items_for_region1 values(4,'A001',12,5);
commit;



insert into orders_for_region2 values(1,sysdate,null,null);
insert into orders_items_for_region2 values(1,'A001',30,13);
insert into orders_items_for_region2 values(1,'A001',33,10);
insert into orders_items_for_region2 values(1,'A001',11,7);

insert into orders_for_region2 values(2,sysdate,null,null);
insert into orders_items_for_region2 values(2,'A001',30,13);
insert into orders_items_for_region2 values(2,'A001',33,10);
insert into orders_items_for_region2 values(2,'A001',11,7);

insert into orders_for_region2 values(3,sysdate,null,null);
insert into orders_items_for_region2 values(3,'A001',50,13);
insert into orders_items_for_region2 values(3,'A001',63,7);
insert into orders_items_for_region2 values(3,'A001',21,5);

insert into orders_for_region2 values(4,sysdate,null,null);
insert into orders_items_for_region2 values(4,'A001',30,13);
insert into orders_items_for_region2 values(4,'A001',35,10);
insert into orders_items_for_region2 values(4,'A001',12,5);
commit;


insert into orders_for_region3 values(1,sysdate,null,null);
insert into orders_items_for_region3 values(1,'A001',30,13);
insert into orders_items_for_region3 values(1,'A001',33,10);
insert into orders_items_for_region3 values(1,'A001',11,7);

insert into orders_for_region3 values(2,sysdate,null,null);
insert into orders_items_for_region3 values(2,'A001',30,13);
insert into orders_items_for_region3 values(2,'A001',33,10);
insert into orders_items_for_region3 values(2,'A001',11,7);

insert into orders_for_region3 values(3,sysdate,null,null);
insert into orders_items_for_region3 values(3,'A001',50,13);
insert into orders_items_for_region3 values(3,'A001',63,7);
insert into orders_items_for_region3 values(3,'A001',21,5);

insert into orders_for_region3 values(4,sysdate,null,null);
insert into orders_items_for_region3 values(4,'A001',30,13);
insert into orders_items_for_region3 values(4,'A001',35,10);
insert into orders_items_for_region3 values(4,'A001',12,5);
commit;



insert into orders_for_region4 values(1,sysdate,null,null);
insert into orders_items_for_region4 values(1,'A001',30,13);
insert into orders_items_for_region4 values(1,'A001',33,10);
insert into orders_items_for_region4 values(1,'A001',11,7);

insert into orders_for_region4 values(2,sysdate,null,null);
insert into orders_items_for_region4 values(2,'A001',30,13);
insert into orders_items_for_region4 values(2,'A001',33,10);
insert into orders_items_for_region4 values(2,'A001',11,7);

insert into orders_for_region4 values(3,sysdate,null,null);
insert into orders_items_for_region4 values(3,'A001',50,13);
insert into orders_items_for_region4 values(3,'A001',63,7);
insert into orders_items_for_region4 values(3,'A001',21,5);

insert into orders_for_region4 values(4,sysdate,null,null);
insert into orders_items_for_region4 values(4,'A001',30,13);
insert into orders_items_for_region4 values(4,'A001',35,10);
insert into orders_items_for_region4 values(4,'A001',12,5);
commit;


B 創建SP實現多個區域的銷售數據的計算。region_tab

create or replace procedure update_dyn_global(retcd out number,errmsg out varchar2) authid current_user is
? cursor csr_region is select region_name from region_tab;
begin
? for idx in csr_region loop
???? update_dyn_all_table(idx.region_name,retcd,errmsg);
???? if retcd <> 0 then
?????? exit;
???? end if;
? end loop;
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

測試:

declare
? v_sqlcode number;
? v_sqlerrm varchar2(200);
begin
? update_dyn_global(v_sqlcode,v_sqlerrm);
? dbms_output.put_line(v_sqlerrm);
end;


驗證:

select * from orders_for_region1;
select * from orders_for_region2;
select * from orders_for_region3;
select * from orders_for_region4;

在存儲過程中使用動態PLSQL調用存儲過程,封裝在SP中

create or replace procedure update_dyn_global2(retcd out number,errmsg out varchar2) authid current_user is
begin
? execute immediate 'begin update_dyn_global(:1,:2);end;' using out retcd,out errmsg;
? --動態PLSQL語句中調用存儲過程
? retcd:=0;
? errmsg:='successful!';
exception when others then
? retcd:=sqlcode;
? errmsg:=sqlerrm;
end;

練習:

將上面的三個SP封裝在一個package中,全部做成公有對象

SCOTT用戶下
?A 創建一個表emp_salary_grd : 三個列:員工號 empno 、工資等級 sal_level、年薪 sal_anl? (sal*12+comm)
?B 創建一個SP,用動態PLSQL的方式將這個表的數據裝載
?C 用動態PSLQL方式調用上面創建的SP

設計一個SP,將PLSQL用戶下所有的觸發器禁用掉,用動態SQL方式

###########################################################################################

轉載于:https://blog.51cto.com/fengsonglin/1615262

總結

以上是生活随笔為你收集整理的plsql动态的sql的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人免费无码大片a毛片抽搐色欲 | 婷婷久久综合网 | 亚洲色图第一页 | 一区二区三区久久精品 | 波多野结衣国产在线 | 亚洲熟乱 | 初尝人妻少妇中文字幕 | 亚洲干综合 | 天天鲁一鲁摸一摸爽一爽 | 毛片2 | 疯狂做爰的爽文多肉小说王爷 | 91视频麻豆| 久久99网 | 亚洲视频中文字幕在线观看 | 四虎影库永久在线 | 熟女视频一区二区三区 | 国产欧美一区二区三区国产幕精品 | 4438x全国最大成人网 | 亚洲jizzjizz日本少妇 | 韩国成人免费视频 | 欧美日韩一区二区在线观看 | 高清视频在线播放 | 欧美日韩精品一区二区三区蜜桃 | 九九热久久免费视频 | 俄罗斯色片 | x88av在线| 在线观看你懂得 | 美女脱光内衣内裤 | 国内精品卡一卡二卡三 | 五月天色网站 | 一久久| 亚洲精品h | 成人两性视频 | 超碰福利在线观看 | 色吊丝中文字幕 | av男女| 亚洲黄色在线免费观看 | 日韩成人高清在线 | 国产精品99久久久 | 日本黄色三级视频 | 五月婷婷免费视频 | 日韩视频在线播放 | 日韩欧美国产一区二区在线观看 | aaaa黄色片 | 性生活一区| av先锋资源网 | 国产精品久久久久久久久久久免费看 | 欧美日韩一区二区三区在线视频 | 国产人妖在线播放 | 国产香蕉视频在线观看 | 日韩欧美天堂 | 小草av| 91网页在线观看 | 小香蕉影院 | 中文字幕在线观看视频网站 | 日韩欧美成人一区二区 | 97在线免费 | 高潮videossex高潮 | 天堂亚洲| 国产精品精 | 午夜尤物| 国产一区二三区 | 精品蜜桃av | 正在播放亚洲 | 天堂8中文在线 | 风间由美av在线 | 亚洲啊啊啊啊啊 | 牛牛精品一区二区 | 综合网伊人 | www日韩在线 | 老熟妇一区二区三区啪啪 | 三级a毛片| 91久久人澡人人添人人爽欧美 | 96日本xxxxxⅹxxx70| 香蕉精品视频在线观看 | 国模私拍在线观看 | 欧美黄色a视频 | 久久久久久久久久久久久久久久久久久 | 欧美成人性色 | www麻豆 | 在线视频啪 | 日本va欧美va欧美va精品 | 久久精品大全 | 中文字幕在线观看的网站 | 香蕉视频官方网站 | 国产一区二区三区黄片 | 五月婷网站| 人妻一区二区在线 | 天天看夜夜爽 | 亚洲欧美综合色 | 伊人久久中文 | 亚洲成人播放 | 五月婷久久 | 人妻丰满熟妇无码区免费 | 丁香一区二区三区 | beeg日本高清xxxx18 | 欧美激情精品久久 | 国产精品久久久久久亚洲调教 | 亚洲欧美在线免费观看 |