在實際項目中存儲過程暫時用的還不是很多,先標記幾個不錯的小案例:
1.查所有字段
DECLARE
CURSOR cur_query IS
SELECT table_name, column_name, data_type FROM user_tab_columns;
a NUMBER;
sql_hard VARCHAR2(2000);
vv NUMBER;
BEGIN
FOR rec1 IN cur_query LOOP
a := 0;
IF rec1.data_type = 'NVARCHAR' THEN
a := 1;
END IF;
IF rec1.data_type = 'VARCHAR2' THEN
a := 1;
END IF;
IF rec1.data_type = 'VARCHAR' THEN
a := 1;
END IF;
IF a > 0 THEN
sql_hard := '';
sql_hard := 'SELECT COUNT(*) FROM ' || rec1.table_name || ' WHERE ' ||
rec1.column_name || '=''4bd4c8d4-e4cf-4272-8472-92ef81e44616'''; --字段值
EXECUTE IMMEDIATE sql_hard
INTO vv;
IF vv > 0 THEN
dbms_output.put_line('[字段值所在的表.字段]:[' || rec1.table_name || '].[' ||
rec1.column_name || ']');
END IF;
END IF;
END LOOP;
END;
2.一個基礎的小DEMO
create or replace procedure P_EstimateEngineerType(--概算按項目歸類分析項目數量及投資情況(以第一次申報投資計算)
OUT_TABLE OUT types.ref_cursor
)AUTHID CURRENT_USER
is
e_flag number;
e_create_sql varchar2(2000);
e_flagsql varchar2(200);
totalNum number;
investNum number;
tempTotalNum number;
tempInvestNum number;
totalNumRatio varchar2(50);
investNumRatio varchar2(50);
total_sql varchar2(2000);
result_sql varchar2(2000);
zh_query_sql varchar2(2000);
fj_query_sql varchar2(2000);
lh_query_sql varchar2(2000);
sl_query_sql varchar2(2000);
dx_query_sql varchar2(2000);
qt_query_sql varchar2(2000);
begin
--創建臨時表
e_create_sql='create global temporary table estimateEngineer_temp(engineerType varchar(50)
,proNum varchar(50),proNumRatio varchar(50),
investCost varchar(50), investCostRatio varchar(50))';
--判斷臨時表是否存在
e_flagsql='select COUNT() from User_Tables where table_name=''ESTIMATEENGINEER_TEMP''';
execute immediate e_flagsql into e_flag;
if e_flag 0 then
begin
execute immediate 'drop table estimateEngineer_temp';
end;
end if;
--執行創建臨時表
execute immediate e_create_sql;
--所有項目項目數量及投資情況語句
total_sql='select count(a.id),sum(a.totalinvest) from PS_TASK_REG a where a.auditinfo=''第一次申報'' and a.busiType= ''3''';
execute immediate total_sql into totalNum,investNum;
--市政項目項目數量及投資情況語句
zh_query_sql=total_sql ' and (a.engineertype like ''%市政%'' or a.engineertype = ''1'' )';
execute immediate zh_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2);
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入市政項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''市政'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--房建項目項目數量及投資情況語句
fj_query_sql=total_sql ' and (a.engineertype=''2'' or a.engineertype like ''%房建%'')';
execute immediate fj_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2) ;
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入房建項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''房建'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--綠化項目項目數量及投資情況語句
lh_query_sql=total_sql ' and (a.engineertype=''3'' or a.engineertype like ''%綠化%'')';
execute immediate lh_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2) ;
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入綠化項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''綠化'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--水利項目項目數量及投資情況語句
sl_query_sql=total_sql ' and (a.engineertype=''4'' or a.engineertype like ''%水利%'')';
execute immediate sl_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2) ;
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入水利項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''水利'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--信息化項目項目數量及投資情況語句
dx_query_sql=total_sql ' and (a.engineertype=''5'' or a.engineertype like ''%信息化%'')';
execute immediate dx_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2) ;
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入信息化項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''信息化'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--公路項目項目數量及投資情況語句
qt_query_sql=total_sql ' and (a.engineertype=''6'' or a.engineertype like ''%公路%'')';
execute immediate qt_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2);
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入公路項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''公路'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--管線遷改項目項目數量及投資情況語句
qt_query_sql=total_sql ' and (a.engineertype=''7'' or a.engineertype = ''通信''
or a.engineertype = ''電力'' or a.engineertype = ''給排水'')';
execute immediate qt_query_sql into tempTotalNum,tempInvestNum;
totalNumRatio= round(tempTotalNum100totalNum,2);
investNumRatio=round(tempInvestNum100investNum,2);
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
if (investNumRatio is null) then
investNumRatio='0';
end if;
if (totalNumRatio is null) then
totalNumRatio=0;
end if;
--臨時表中插入管線遷改項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,proNumRatio,investCost,investCostRatio)
values (''管線遷改'''','tempTotalNum','totalNumRatio','
tempInvestNum','investNumRatio')';
--所有項目項目數量及投資情況語句
execute immediate total_sql into tempTotalNum,tempInvestNum;
if (tempTotalNum is null) then
tempTotalNum='0';
end if;
if (tempInvestNum is null) then
tempInvestNum=0;
end if;
--臨時表中插入所有項目類型
execute immediate'insert into estimateEngineer_temp(engineerType,proNum,investCost)
values (''合計'''','tempTotalNum','tempInvestNum')';
--查詢結果SQL
result_sql= 'select from estimateEngineer_temp';
OPEN OUT_TABLE FOR result_sql;
end P_EstimateEngineerType;
******************************************************************************************************************************
create or replace procedure P_BUDGETREVIEWDETAIL(
in_id in varchar2,--輸入項目的id
out_table out types.ref_cursor
) AUTHID CURRENT_USER
is
create_temptab varchar(2000);
insert_commsql varchar(2000);
insert_sql varchar(2000);
query_sql varchar(200);
sqlflag varchar(200);
result_sql varchar(200);
flagnum varchar(20);
ordernum varchar(10);
detailname varchar(100);
dcinvest number;
dcjafeerate number;
dcjtfeerate number;
auinvest number;
aujafeerate number;
aujtfeerate number;
checkinvest number;
checkrate number;
remark varchar(2000);
flag_num varchar(20);
applybudget number;
confirmmoney number;
applybudget_1 number;
confirmmoney_1 number;
conditionexe exception;
item ps_item_record%rowtype;
--創建遊標,可以傳遞參數
Cursor cursor is select itemtext,itemname,applybudget,confirmmoney,confirmbalance,remark from ps_item_record where itemtype='PS_ZTZGS' and taskid=''||in_id||'';
begin
--拼接創建臨時表的sql
create_temptab:='create global temporary table budgetreviewdetail_temp(
ordernum varchar2(10),
detailname varchar2(100),
dcinvest varchar2(50),
dcjafeerate varchar2(50),
dcjtfeerate varchar2(50),
auinvest varchar2(50),
aujafeerate varchar2(50),
aujtfeerate varchar2(50),
checkinvest varchar2(50),
checkrate varchar2(50),
remark varchar2(2000)
) on commit preserve rows';
--判斷表是否存在,存在則刪除表格
sqlflag:='select count(*) from User_Tables where table_name=''BUDGETREVIEWDETAIL_TEMP''';
execute immediate sqlflag into flagnum;
if flagnum>0 then
begin
execute immediate 'drop table budgetreviewdetail_temp';
end;
end if;
--重新創建臨時表
execute immediate create_temptab;
--可拼接的sql子串
insert_commsql:='insert into budgetreviewdetail_temp (ordernum,detailname,dcinvest,dcjafeerate,dcjtfeerate,auinvest,aujafeerate,aujtfeerate,checkinvest,checkrate,remark) values';
if in_id is not null then
--判斷靜態總投資數據是否存在
query_sql:='select count(id) from ps_item_record where itemtype=''PS_ZTZGS'' and itemtext=''靜態總投資'' and taskid='''||in_id||'''';
execute immediate query_sql into flag_num;
--獲取靜態總投資的數據
if flag_num>0 then
query_sql:='select applybudget,confirmmoney from ps_item_record where itemtype=''PS_ZTZGS'' and itemtext=''靜態總投資'' and taskid='''||in_id||'''';
execute immediate query_sql into applybudget,confirmmoney;
if applybudget is null then
applybudget:=0;
end if;
if confirmmoney is null then
confirmmoney:=0;
end if;
else
applybudget:=0;
confirmmoney:=0;
end if;
--判斷建安工程費數據是否存在
query_sql:='select count(id) from ps_item_record where itemtype=''PS_ZTZGS'' and itemtext=''建安工程費'' and taskid='''||in_id||'''';
execute immediate query_sql into flag_num;
--獲取建安工程費
if flag_num>0 then
query_sql:='select applybudget,confirmmoney from ps_item_record where itemtype=''PS_ZTZGS'' and itemtext=''建安工程費'' and taskid='''||in_id||'''';
execute immediate query_sql into applybudget_1,confirmmoney_1;
if applybudget_1 is null then
applybudget_1:=0;
end if;
if confirmmoney_1 is null then
confirmmoney_1:=0;
end if;
else
applybudget_1:=0;
confirmmoney_1:=0;
end if;
for item in cursor loop
ordernum:=item.itemname;
detailname:=item.itemtext;
dcinvest:=item.applybudget;
auinvest:=item.confirmmoney;
checkinvest:=item.confirmbalance;
remark:=item.remark;
if applybudget = 0 then
dcjtfeerate:=0;
else
dcjtfeerate:=dcinvest/applybudget;
end if;
if confirmmoney = 0 then
aujtfeerate:=0;
else
aujtfeerate:=auinvest/confirmmoney;
end if;
if applybudget_1 = 0 then
dcjafeerate:=0;
else
dcjafeerate:=dcinvest/applybudget_1;
end if;
if confirmmoney_1 = 0 then
aujafeerate:=0;
else
aujafeerate:=auinvest/confirmmoney_1;
end if;
if checkinvest is null then
checkinvest:=0;
end if;
if dcinvest is null or dcinvest = 0 then
checkrate:=0;
else
checkrate:=checkinvest/dcinvest;
end if;
insert_sql:=insert_commsql||' ('''||ordernum||''','''||detailname||''','''||dcinvest||''','''||dcjafeerate||''','''||dcjtfeerate||''','''||auinvest||''',
'''||aujafeerate||''','''||aujtfeerate||''','''||checkinvest||''','''||checkrate||''','''||remark||''')';
execute immediate insert_sql;
end loop;
else
raise conditionexe;
end if;
result_sql:='select * from budgetreviewdetail_temp';
open out_table for result_sql;
exception
when conditionexe then
dbms_output.put_line('查詢條件不能爲空');
end P_BUDGETREVIEWDETAIL;
Mysql存儲過程小案例:
CREATE PROCEDURE proc_sys_employ_statistics (
IN start_date datetime,
IN end_date datetime,
IN project_level_id VARCHAR(36),
IN project_depth INT
)
BEGIN
/* 定義開始結束開關 */
DECLARE done INT DEFAULT FALSE;
DECLARE P_PROJECT_ID VARCHAR(36);
DECLARE P_PARENT_ID VARCHAR(36);
DECLARE P_PROJECT_NAME VARCHAR(256);
DECLARE P_PROJECT_SNAP_NUM INT DEFAULT 0;
/* 找到要查詢的項目-遊標 */
DECLARE CUR_PROJECT CURSOR FOR SELECT p.id,p.parent_id,p.`name` FROM project p WHERE p.is_delete = '0'
and p.project_level in (2,3) and
p.id in(select t1.id from project t1 where t1.parent_id in (select t.id from project t where t.parent_id= project_level_id ) )
ORDER BY p.order_num ASC,p.`name` ASC;
/* 找到要查詢的項目-遊標 */
DECLARE CUR_PROJECT_2 CURSOR FOR SELECT p.id,p.parent_id,p.`name` FROM project p WHERE p.is_delete = '0'
and p.project_level in (2,3) and p.id in(select t1.id from project t1 where t1.parent_id = project_level_id) ORDER BY p.order_num ASC,p.`name` ASC;
/*如果找不到了,就設置done爲true,停止循環*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 創建臨時輸出表
DROP TABLE
IF EXISTS tmp_output_table;
CREATE TEMPORARY TABLE tmp_output_table (
projectId VARCHAR (36),
parentId VARCHAR (36),
projectName VARCHAR (256),
projectSnap INT DEFAULT 0,
);
IF project_depth=2 THEN
OPEN CUR_PROJECT_2;
ELSE
OPEN CUR_PROJECT;
END IF;
-- OPEN CUR_PROJECT;
OUT_LOOP: LOOP
/* 循環需要修改的根目錄遊標 */
IF project_depth=2 THEN
FETCH NEXT FROM CUR_PROJECT_2 INTO P_PROJECT_ID,P_PARENT_ID,P_PROJECT_NAME;
ELSE
FETCH NEXT FROM CUR_PROJECT INTO P_PROJECT_ID,P_PARENT_ID,P_PROJECT_NAME;
END IF;
-- FETCH NEXT FROM CUR_PROJECT INTO P_PROJECT_ID,P_PARENT_ID,P_PROJECT_NAME;
IF done THEN
LEAVE OUT_LOOP;
END IF;
SELECT
COUNT(t.id) INTO P_PROJECT_SNAP_NUM
FROM
`project_snap_file` t
WHERE
t.is_delete = '0'
AND t.creation_time BETWEEN start_date
AND end_date AND t.project_id=P_PROJECT_ID;
/* 創建一條tmp_output_table數據CUR_PROJECT */
INSERT INTO tmp_output_table (projectId,parentId,projectName,projectSnap)
VALUES
(P_PROJECT_ID,P_PARENT_ID,P_PROJECT_NAME,P_PROJECT_SNAP_NUM);
END LOOP OUT_LOOP;-- 關閉數據
IF project_depth=2 THEN
CLOSE CUR_PROJECT_2;
ELSE
CLOSE CUR_PROJECT;
END IF;
-- 查詢數據
SELECT * from tmp_output_table;
END