使用動態sql解決在同一張表格中輸出不同字段

場景再現:

需求要求我們在table1中取到墓位定金和墓位成交額,然後再table2中取到墓位的管理費以及一些連帶費用,但是兩個表沒有唯一的關聯關係,故我們採用在求墓位定金、墓位成交額的的存儲過程中嵌入存儲函數的方式進行實現;

那麼問題來了,因爲我們要取得字段偏多,我們不可能新建十幾個存儲函數去單獨取各個字段,於是,我們就可以使用動態SQL來解決這一問題;

動態sql

oracle編譯PL/SQL程序塊分爲兩種,其一爲前期聯編(early binding),即SQL語句在編譯期間就已經確定;另一種爲後期聯編(late binding),即SQL語句只有在運行階段才能建立;靜態SQL採用的是前期聯編,動態SQL採用的是後期聯編;
2、動態SQL是一種“不確定”的SQL,這裏ORACLE提供了Execute immediate語句來執行動態SQL,語法如下:Excute immediate 動態SQL語句 using 綁定參數列表 returning into 輸出參數列表;
實例:根據特定ID可以查詢到其姓名和薪水的信息

create or replace procedure find_info(p_id number)
as v_name varchar2(10);
v_salary number;
begin
execute immediate 'select name,salary from emp where id=:1'
using p_id
return into v_name,v_salary;--這裏的動態SQL爲查詢語句
dbms_output.put_line(v_name ||'的收入爲:'||to_char(v_salary));
exception
when others then
dbms_output.put_line('找不到相應數據')end find_info;

注意:這裏的動態SQL語句使用了佔位符“:1“,其實它相當於函數的形式參數,使用”:“作爲前綴,然後使用using語句將p_id在運行時刻將:1給替換掉,這裏p_id相當於函數裏的實參。

實例二:根據大於特定的薪水的查詢相應的員工信息

create or replace procedure find_emp(p_salary number)as
r_emp emp%rowtype;
type c_type is ref cursor;--聲明遊標
c1 c_type;--定義遊標
begin
open c1 for --打開遊標
'select * from emp where salary >:1'
using p_salary;
loop --開啓循環輸出員工薪水大於入參p_salary的
fetch c1 into r_emp;
exit when c1%notfound;
dbms_output.put_line('薪水大於‘||to_char(p_salary)||’的員工爲:‘);
dbms_output.put_line('ID爲'to_char(r_emp)||' 其姓名爲:'||r_emp.name);
end loop;
close c1;
end find_emp;

注意:打開的遊標爲動態遊標,它也屬於動態SQL的範疇,其整個編譯和開發的過程與execute immediate執行的過程很類似,這裏就不在贅述了

本案例實現:
首先,我們創建個通過傳入userId和字段名動態獲取字段值的存儲函數

create or replace function GET_SUMFY(TMPNAME VARCHAR2,QSYRID VARCHAR2) return VARCHAR is
  CONVERT_AMOUNT VARCHAR2(300);
  SQLSTR  VARCHAR2(1000);
begin
  SQLSTR :='SELECT SUM('||TMPNAME||') FROM my_jf_record T WHERE T.MY_USER_ID='''||QSYRID||''' ';
  EXECUTE IMMEDIATE SQLSTR INTO CONVERT_AMOUNT;
  return CONVERT_AMOUNT;
end GET_SUMFY;

其次,我們在之前的存儲過程中直接調用該存儲函數,通過傳入參數來獲取字段值;

 					NVL(GET_SUMFY('GL_F', X.ID), 0) GL_F,
                     NVL(GET_SUMFY('KZ_F', X.ID), 0) KZ_F,
                     NVL(GET_SUMFY('TJ_F', X.ID), 0) TJ_F,
                     NVL(GET_SUMFY('CL_F', X.ID), 0) CL_F,
                     NVL(GET_SUMFY('ZAZ_F', X.ID), 0) ZAZ_F,
                     NVL(GET_SUMFY('KFZ_F', X.ID), 0) KFZ_F,
                     NVL(GET_SUMFY('ZP_F1', X.ID), 0) ZP_F1,
                     NVL(GET_SUMFY('ZP_F2', X.ID), 0) ZP_F2,
                     NVL(GET_SUMFY('ZP_F3', X.ID), 0) ZP_F3,
                     NVL(GET_SUMFY('KF_F', X.ID), 0) KF_F,
                     NVL(GET_SUMFY('QT_F', X.ID), 0) QT_F,
                     NVL(GET_SUMFY('YJ_F', X.ID), 0) YJ_F,
                     NVL(GET_SUMFY('SJ_F', X.ID), 0) SJ_F,
                     NVL(GET_SUMFY('QF_F', X.ID), 0) QF_F

大功告成!

原文連接:https://www.cnblogs.com/AaronBear/p/11049917.html

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