Return a single value using oracle function and stored procedure

1 function 返回值
function get_link_coalingid(p_id in varchar2 ) return varchar2  is    
     r_lid             varchar2(200);
   begin
     select t.link_coalingid into r_lid
      from dis_w_package_train_link_his t
     where t.pid =  p_id  and rownum <= 1  order by t.link_date desc ;   
      return r_lid;
    EXCEPTION 
    WHEN OTHERS THEN 
    RETURN NULL; 
    end;

2 执行动态sql
比如动态获取某个字段值
function getStanderByField(p_id in varchar2,fieldName in varchar2 ) return number is
    iv_sqlstr           VARCHAR2(200); 
    r_result number;
    begin
      iv_sqlstr := 'select '||fieldName||' from v_dis_w_package_train_type 
     where id = :1' ;
     EXECUTE IMMEDIATE iv_sqlstr INTO r_result using p_id; RETURN
     r_result; end
    ; posts/list/792.html http://blog.csdn.net/jumtre/article/details/38092067 http://blog.csdn.net/tanshi/article/details/7083922 --------- ------------------------------ 1 EXECUTE IMMEDIATE         DBMS_SQL package and EXECUTE IMMEDIATE in Oracle can be used to parse and execute dynamic SQL In comparison, EXECUTE IMMEDIATE is simpler to use for statements or PL/SQL blocks that are not created at runtime and can meet more common needs. 1.1 Syntax














           EXECUTE IMMEDIATE v_sql [BULK COLLECT INTO or INTO return value variable] [INTO input parameter 1,.., out output parameter 1,..].

Description:
      1. v_sql is varchar2 type or clob (only supported by 11g), which can be sql strings dynamically spliced ​​by DDL, DML, etc. When used in pl/sql code, if it is of varchar2 type, the length cannot be greater than 32767 (32K).

      2. When v_sql is a DML dynamic statement, it will not be submitted after execution, and it needs to be explicitly submitted using commit. If it is a DDL command, all previous changes will be committed after execution.
      3. If you need to return a value from dynamic sql, you can define a return value variable, BULK COLLECT INTO returns a multi-line value, and the variable defined at this time must be a list of array variables or a record table type; INTO returns a single row, the variable defined at this time You can make multiple pl/sql variables a list or record type.

      4. If you need to bind variables in dynamic sql, use USING. Usually, the bound variables are input parameters. In this case, the in of the variable can be omitted; if you need to bind output variables (for example, you may need to output when calling a process), then Use out before the variable to indicate it explicitly.
1.2.1 Dynamic DDL
DECLARE 
  v_sql VARCHAR2(1000); 
  v_table VARCHAR2(30) := 'test_ynamic_sql'; 
BEGIN 
  v_sql := ' create table ' || v_table || 
           ' (id varchar2(10),name varchar2(100))'; 
  EXECUTE IMMEDIATE v_sql; 
END;
1.2.2 Dynamic DML insert
1.2.2.1 Do not bind input variables
DECLARE 
  v_sql VARCHAR2(1000); 
  v_table VARCHAR2(30) := 'test_ynamic_sql'; 
BEGIN  --1
  , do not bind input variables 
  v_sql := ' insert into ' || v_table || 
           ' values ​​(''1'',''no_binding_in_variable'')'; 
  EXECUTE IMMEDIATE v_sql; 
  COMMIT; - -dml needs to show submission 
END;
1.2.2.2 Bind input variable
DECLARE 
  v_sql VARCHAR2(1000); 
  v_table VARCHAR2(30) := 'test_ynamic_sql'; 
BEGIN  --1
  , bind input variable 
  v_sql := ' insert into ' || v_table || ' values ​​(:1,:2)'; 
  EXECUTE IMMEDIATE v_sql 
    USING '2', 'binding_in_variable'; --Use using to bind input variablesEND 
;
1.2.3 Dynamic DML select
1.2.3.1 returns a single row value
DECLARE 
  v_sql VARCHAR2(1000); 
  v_table VARCHAR2(30) := 'test_ynamic_sql'; --1 
  . Use simple pl/sql variables v_id, v_name to obtain single row output 
  v_id VARCHAR2(10); 
  v_name VARCHAR2( 100); 
  --2. Use the record variable based on the test_ynamic_sql table to obtain a single-line output 
  TYPE test_ynamic_sql_record IS RECORD( 
    v_id test_ynamic_sql.ID%TYPE, 
    v_name test_ynamic_sql.NAME%TYPE); 
  test_ynamic_sql_row test_ynamic_sql_record; 
BEGIN 
  --1. Use simple pl/sql variables v_id, v_name to obtain single-line output 
  v_sql := ' select id, name from ' || v_table || ' where id=:1 '; 
  EXECUTE IMMEDIATE v_sql 
    INTO v_id, v_name 
    USING '1' ; 
  DBMS_OUTPUT.put_line('id=' || v_id || ',name=' || v_name); --2 
  . Use the record variable based on the test_ynamic_sql table to obtain a single-line output 
  EXECUTE IMMEDIATE v_sql 
    INTO test_ynamic_sql_row 
    USING '1'; 
  DBMS_OUTPUT. put_line('id=' || test_ynamic_sql_row.v_id || ',name=' || 
                       test_ynamic_sql_row.v_name); 
END;

1.2.3.2 Return multi-row value
1.2.3.2.1 Use record table to get
DECLARE 
  v_sql VARCHAR2(1000);   
  v_table VARCHAR2(30) := 'test_ynamic_sql'; 
  --1. Use the record variable based on the test_ynamic_sql table to obtain multi-line output 
  TYPE test_ynamic_sql_record IS RECORD( 
    id test_ynamic_sql.ID%TYPE, 
    NAME test_ynamic_sql.NAME%TYPE); 
  TYPE test_ynamic_sql_table_type IS TABLE OF test_ynamic_sql_record INDEX BY BINARY_INTEGER; 
  /*The following can be used Way to define record table*/ 
  --TYPE test_ynamic_sql_table_type IS TABLE OF test_ynamic_sql%ROWTYPE INDEX BY BINARY_INTEGER; 
  test_ynamic_sql_multi_row test_ynamic_sql_table_type; 
BEGIN  --1
  , use the record variable based on the test_ynamic_sql table to obtain multi-row output 
  v_sql := ' select id,name from ' | | v_table; 
  EXECUTE IMMEDIATE v_sql BULK COLLECT 
    INTO test_ynamic_sql_multi_row; 
  FOR m IN 1 .. test_ynamic_sql_multi_row.COUNT LOOP 
    DBMS_OUTPUT.put_line('id=' || test_ynamic_sql_multi_row(m) 
                         .id || ',name=' || test_ynamic_sql_multi_row(m).NAME); 
  END LOOP; 
END; 

1.2.3.2.2 Get using multiple nested tables
DECLARE 
  v_sql VARCHAR2(1000); 
  v_table VARCHAR2(30) := 'test_ynamic_sql'; --1. 
  Use to get multi-row output based on multiple nested tables 
  TYPE test_ynamic_sql_id_type IS TABLE OF test_ynamic_sql.ID%TYPE INDEX BY BINARY_INTEGER; 
  TYPE test_ynamic_sql_name_type IS TABLE OF test_ynamic_sql.NAME%TYPE INDEX BY BINARY_INTEGER; 
  test_ynamic_sql_multi_row_id test_ynamic_sql_id_type; 
  test_ynamic_sql_multi_row_name test_ynamic_sql_name_type; 
BEGIN  --1
  , use to get multi-row output based on multiple nested tables 
  v_sql := ' select id,name from ' || v_table; 
  EXECUTE IMMEDIATE v_sql BULK COLLECT 
    INTO test_ynamic_sql_multi_row_id, test_ynamic_sql_multi_row_name; 
  FOR m IN 1 .. test_ynamic_sql_multi_row_id.COUNT LOOP 
    DBMS_OUTPUT.put_line('id=' || test_ynamic_sql_multi_row_id(m) || 
                         ',name=' || test_ynamic_sql_multi_row_name(m)); 
  END LOOP; 
END; 

1.2.4        动态调用函数
1.2.4.1       使用select 获取返回值
DECLARE 
  v_sql  VARCHAR2(1000); 
  v_name VARCHAR2(100); 
BEGIN 
  --1、先创建测试函数 
  v_sql := ' CREATE OR REPLACE FUNCTION f_test_ynamic_sql(v_id VARCHAR2) RETURN VARCHAR2 IS 
             v_name VARCHAR2(100); 
               BEGIN 
               SELECT NAME INTO v_name FROM test_ynamic_sql WHERE id = v_id; 
             RETURN v_name; 
            END ; '; 
  EXECUTE IMMEDIATE v_sql; --2. 
  Use select to get the return value 
  v_sql := ' select f_test_ynamic_sql(:1) from dual '; 
  EXECUTE IMMEDIATE v_sql 
    INTO v_name 
    USING '1'; 
  DBMS_OUTPUT.put_line(' NAME = ' || v_name); 
END; 

1.2.4.2 Use begin .. end bind function output variable
DECLARE 
  v_sql VARCHAR2(1000); 
  v_name_o VARCHAR2( 100); 
BEGIN 
  --1, create a test function first 
  v_sql := ' CREATE OR REPLACE FUNCTION f_test_ynamic_sql(v_id VARCHAR2,v_name_o out varchar2) RETURN VARCHAR2 IS 
             v_name VARCHAR2(100); 
               BEGIN 
               SELECT NAME INTO v_name FROM test_ynamic_sql WHERE id = v_id; 
               v_name_o:=v_name; 
             RETURN v_name; 
            END ; '; 
  EXECUTE IMMEDIATE v_sql; --2. 
  Use the begin .. end binding function to output variables 
  v_sql := ' declare v_name varchar2(100);  
           begin v_name:=f_test_ynamic_sql(:1,:2); end;'; 
  EXECUTE IMMEDIATE v_sql 
    USING '1', OUT v_name_o; 
  DBMS_OUTPUT.put_line('name_o=' || v_name_o); --The output variable in using needs to display the descriptionEND 


1.2.5 Dynamic call procedure
DECLARE 
  v_sql VARCHAR2(1000); 
  v_name_o VARCHAR2(100); 
BEGIN  --1
  . First create test procedure 
  v_sql := ' CREATE OR REPLACE procedure p_test_ynamic_sql(v_id VARCHAR2,v_name_o out varchar2) IS 
               BEGIN 
               SELECT NAME INTO v_name_o FROM test_ynamic_sql WHERE id = v_id; 
            END ; '; 
  EXECUTE IMMEDIATE v_sql; --2. 
  Use begin .. end to bind process output variables 
  v_sql := ' begin p_test_ynamic_sql(:1,:2); end;'; 
  EXECUTE IMMEDIATE v_sql 
    USING '1', OUT v_name_o; The output variable in --using needs to be displayed 
  DBMS_OUTPUT.put_line('name_o=' || v_name_o); 
END; 




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326459757&siteId=291194637