13技术太卷我学APEX-Oracle动态SQL

0.场景

一句话就是执行字符串拼接起来的SQL。

1.创建3个过程

创建执行insert ,update ,delete 语句的过程;创建执行select的过程;创建一个过程把以上两个整合在一起,这样增删改查就齐活了。

1.1 创建执行DML的过程

这个比较简单,直接上plsql代码。

create or replace procedure p_exe_dml(sql_dml in varchar2) is
result varchar2(52);
rows number(17);
ls_sql6 varchar2(17);

begin
    --sql语句过滤,只执行select,update,delete,insert 开头的sql
    ls_sql6 := substr(lower(trim(sql_dml)),1,6);
  
    if ls_sql6 not in ('insert','update','delete') then 
        htp.p( '支持的DML SQL(INSERT UPDATE DELETE);不支持:' || sql_dml);
        return;
    end if;
  
    --执行sql 
    execute immediate sql_dml;
    rows := sql%rowcount;  
    commit;
    --影响的行数
    
    result := '影响行数:' || to_char(rows);
    htp.p(result); 
end;

简单测试一下:

begin 
  p_exe_dml('insert into atop(p_id) values (-5217)');
  p_exe_dml('update atop set f_dm = ''5217'' where p_id = -5217' );
end;

begin 
  p_exe_dml('delete atop where p_id=-5217');
end 

13技术太卷我学APEX-Oracle动态SQL_第1张图片
输出结果在这里:
13技术太卷我学APEX-Oracle动态SQL_第2张图片
一切OK。

1.2 执行select的过程

这个稍微复杂一些,用到DBMS_SQL包。

create or replace procedure p_exe_select(select_str in varchar2) is

SYS_RC SYS_REFCURSOR;
ls_sql6 varchar2(17);
    
L_COLS NUMBER; 
L_DESC DBMS_SQL.DESC_TAB; 
L_CURS INTEGER; 
L_VARCHAR VARCHAR2(521); 

BEGIN
    --sql语句过滤,只执行select 开头的sql
    ls_sql6 := substr(lower(trim(select_str)),1,6);
  
    if not(ls_sql6 = 'select') then 
        return;
    end if;
    
    OPEN SYS_RC FOR select_str;
    
    --CAPITALEXTRACT(SYS_RC => SYS_RC); 
    L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(SYS_RC); 
    DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS,DESC_T => L_DESC); 

    FOR i IN 1..L_COLS LOOP 
        DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000); 
    END LOOP; 
    
    WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP 
        --DBMS_OUTPUT.PUT('Row ' || DBMS_SQL.LAST_ROW_COUNT || ': ');
        htp.p('Row ' || DBMS_SQL.LAST_ROW_COUNT || ': ');
        FOR i IN 1..L_COLS LOOP 
            DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR); 
            --DBMS_OUTPUT.put( l_desc(i).col_name  || ' = ' || L_VARCHAR || ';'); 
            htp.p(l_desc(i).col_name  || ' = ' || L_VARCHAR || ';');
        END LOOP; 
        --dbms_output.put_line('');
        htp.p(chr(13));
    END LOOP; 

    DBMS_SQL.CLOSE_CURSOR(L_CURS); 
END;

简单测试一下:
13技术太卷我学APEX-Oracle动态SQL_第3张图片
输出结果:
13技术太卷我学APEX-Oracle动态SQL_第4张图片

1.3 整合在一起

以上两个过程整合在一起。

create or replace procedure P_EXE_SQL(SQL_STR VARCHAR2) is
ls_sql6 varchar2(17); 
begin
  --sql语言过滤,只执行select,update,delete,insert 开头的sql
    ls_sql6 := substr(lower(trim(SQL_STR)),1,6);
  
    if ls_sql6 in ('insert','update','delete') then 
        p_exe_dml(SQL_STR);
    elsif ls_sql6 = 'select' then
        p_exe_select(SQL_STR);
    end if;
end;

自己测试吧。

你可能感兴趣的:(sql,oracle,数据库)