ORACLE存儲過程瞭解一下

在實際項目中存儲過程暫時用的還不是很多,先標記幾個不錯的小案例:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章