oracle--08 stored procedure 2



In fact, the recordset is returned using REF CURSOR --procedure:
----------------------Declare a Package------------ --
CREATE OR REPLACE PACKAGE pkg_test
AS
TYPEmyrctypeIS REF CURSOR;

PROCEDURE get_r(p_id NUMBER,p_rc OUT myrctype); --Procedure named get declared in the Package (only the interface has no content)
END pkg_test;

-------- ---------Declare Package Body, which is the content in the above Package, including Procedure get---------------------
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE get_r(p_id NUMBER,p_rc OUT myrctype)
IS
sqlstr VARCHAR2 (500);
BEGIN
IF p_id = 0 THEN
OPEN p_rc FOR
SELECT ID, NAME, sex, address, postcode, birthday
FROM student;
ELSE
sqlstr :=
'select id,name,sex,address,postcode,birthday
from student where id=:w_id'; --w_id is a parameter,
--the following p_rc is a REF CURSOR cursor type, and is an OUT parameter, you can return a recordset . USING p_id is to replace the above SQL: w_id value pull:) OPEN
p_rc FOR sqlstr USING p_id; 
END IF;
END get;
END pkg_test;

to return the recordset.

The function returns a record set:
create a package with ref cursor definition, package body and function:

CREATE OR REPLACE
package pkg_test as

type myrctype is ref cursor;
function get_r(intID number) return myrctype;
end pkg_test;
/
CREATE OR REPLACE
package body pkg_test as --function
body
function get_r(intID number) return myrctype is
rc myrctype; --define ref cursor variable
sqlstr varchar2(500);
begin
if intID=0 then --static

test, directly return the result with select statement
open rc for select id,name,sex,address,postcode,birthday from student ;
else
-- dynamic sql assignment, use :w_id to declare that the variable is obtained from outside
sqlstr := 'select id,name,sex,address,postcode,birthday from student where id=:w_id'; --dynamic
test, use sqlstr String return result, use the keyword to pass parameters
open rc for sqlstr using intid;
end if;
return rc;
end get;
end pkg_test

; Points:
a) SQL usage specifications:
i. Try to avoid large transaction operations and use the holdlock clause with caution to improve system concurrency.
ii. Try to avoid repeatedly accessing the same table or tables, especially tables with a large amount of data, you can consider extracting data into temporary tables based on conditions, and then making connections.
iii. Try to avoid using the cursor, because the efficiency of the cursor is poor, if the data operated by the cursor exceeds 10,000 rows, it should be rewritten; if the cursor is used, it is necessary to avoid the operation of table join in the cursor loop.
iv. Pay attention to the writing of the where clause. The order of the statement must be considered. The order of the conditional clauses should be determined according to the index order and range size, and the field order should be consistent with the index order as much as possible. The range is from large to small.
v. Do not perform functions, arithmetic operations or other expression operations on the left side of the "=" in the where clause, otherwise the system may not be able to use the index correctly.
vi. Try to use exists instead of select count(1) to determine whether there is a record. The count function is only used to count all the rows in the table, and count(1) is more efficient than count(*).
vii. Try to use ">=" instead of ">". viii. Pay attention to some substitutions between or clauses and union clauses
ix. Pay attention to the data types of joins between tables and avoid joins between different types of data.
x. Note the relationship between parameters and data types in stored procedures.
xi. Pay attention to the data volume of insert and update operations to prevent conflicts with other applications. If the amount of data exceeds 200 data pages (400k), the system will perform lock escalation, and page-level locks will be upgraded to table-level locks.
b) Specifications for the use of indexes:
i. The creation of indexes should be considered in conjunction with the application. It is recommended that large OLTP tables should not have more than 6 indexes.
ii. Use index fields as query conditions as much as possible, especially clustered indexes. If necessary, index index_name can be used to force
the specified index. iii. Avoid table scan when querying large tables, and consider creating new indexes if necessary.
iv. When using an index field as a condition, if the index is a joint index, the first field in the index must be used as a condition to ensure that the system can use the index, otherwise the index will not be used.
v. Pay attention to the maintenance of indexes, rebuild indexes periodically, and recompile stored procedures.
c) Specifications for the use of tempdb:
i. Try to avoid using distinct, order by, group by, having, join, and ***pute, because these statements will increase the burden of tempdb.
ii. Avoid frequent creation and deletion of temporary tables to reduce the consumption of system table resources.
iii. When creating a new temporary table, if a large amount of data is inserted at one time, you can use select into instead of create table to avoid logging and improve the speed; if the amount of data is not large, in order to ease the resources of the system table, it is recommended to create table first, Then insert.
iv. If the data volume of the temporary table is large and an index needs to be established, then the process of creating the temporary table and building the index should be placed in a separate sub-stored procedure, so as to ensure that the system can use the index of the temporary table well .
v. If temporary tables are used, all temporary tables must be explicitly deleted at the end of the stored procedure, first truncate table, and then drop table, which can avoid long-term locking of system tables.
vi. Use caution to query and modify the connection between large temporary tables and other large tables to reduce the burden of system tables, because this operation will use the system tables of tempdb multiple times in one statement.
d) Reasonable algorithm use:
According to the SQL optimization technology mentioned above and the SQL optimization content in the ASE Tuning manual, combined with the actual application, a variety of algorithms are used to compare to obtain the method that consumes the least resources and has the highest efficiency. Specific ASE tuning commands can be used: set statistics io on, set statistics time on , set showplan on, etc.


Execute DDL syntax in Oracle stored procedure

--C1: Delete all data in the target table

EXECUTE IMMEDIATE 'TRUNCATE TABLE LDCODE';

--C2: Create index

EXECUTE IMMEDIATE 'CREATE INDEX I_JHLCPOL_CONTNO ON JH_LCPOL(CONTNO)';

--C3: Delete index

EXECUTE IMMEDIATE 'DROP INDEX I_JHLCPOL_CONTNO';

    By default, Oracle uses owner permissions for stored procedures, that is, if user B uses stored procedures under user A, the object permissions and system permissions of user A are used. If user A does not have permission, user B will report an error.
  So the first way is to grant the user permission to execute DDL in the stored procedure.
  Another way is to convert the stored procedure to caller authority by using authid Current_user in the stored procedure. In this way, each time the stored procedure is called, it is determined whether there is permission dynamically according to the composition of the caller's permission.
eg:
create or replace procedure P_TEST
Authid Current_User
is
begin
execute immediate 'create table t (id number)';
end P_TEST;
/

create or replace procedure pr_zhaozhenlong_strsql
/*
Name: Execute dynamic sql functions in stored procedures
: dynamically create and delete tables;
      dynamically modify table structure;
      dynamically modify table primary keys ;
      Determine whether a table or a column exists
Call :
      begin
        -- Call the procedure
        pr_zhaozhenlong_strsql;
      end;
Creator: Zhao Zhenlong
Creation time: 2007-01-03
*/
is
     v_rows integer;
     v_sqlstr varchar2(1000);
     v_tablename varchar2(50) ;
     v_pkname varchar2(50);
begin --1
     , determine whether a table exists, delete and create a table
     --select * from tabs where table_name = 'TB_ZHAOZHENLONG'
     select count(1) into v_rows from tabs where table_name = 'TB_ZHAOZHENLONG';
     if v_rows >0 then
        execute immediate 'drop table tb_zhaozhenlong';
     end if;
     v_sqlstr := 'create table tb_zhaozhenlong("id" integer,rpt_date date,dept_id varchar2
(20),item varchar2(20), qty float)';
     execute immediate(v_sqlstr);
     select count(1) into v_rows from tabs where table_name = 'TB_TEMP_ZHAOZHENLONG';
     if v_rows >0 then
        execute immediate 'drop table tb_temp_zhaozhenlong';
     end if;
     
     --创建,基于会话的临时表
     v_sqlstr := 'create global temporary table tb_temp_zhaozhenlong(rpt_date date,dept_id 
varchar2(20),item varchar2(20), qty float, memo varchar(200))'
                 ||' on commit preserve rows';
     execute immediate(v_sqlstr);

     --2、判断是否存在某表,删除、创建表
     --select * from cols where table_name  = 'TB_ZHAOZHENLONG' and column_name = 'MEMO';
     select count(1) into v_rows from cols where table_name = 'TB_ZHAOZHENLONG' and 
column_name = 'MEMO';
     if v_rows <=0 then
        v_tablename :='tb_zhaozhenlong';
        v_sqlstr    := 'alter table ' ||v_tablename ||' add "demo" varchar2(100)';
        execute immediate(v_sqlstr);
     else
        execute immediate 'alter table tb_zhaozhenlong modify demo varchar2(200)';
     end if; --3
     . Modify primary key
     v_tablename :='TB_ZHAOZHENLONG'; --First
     step: add column key_no
     v_sqlstr :='alter table '||v_tablename| |' add key_no int';
     execute immediate(v_sqlstr); --Part       
     II: update the value of
     key_no v_sqlstr :='update '||v_tablename||' set key_no =rownum';
     execute immediate(v_sqlstr); 
     commit;       
     - - Step 3: Set key_no to non-null
     v_sqlstr :='alter table '||v_tablename||' modify key_no int not null';
     execute immediate(v_sqlstr);           
     - Step 4: Find the primary key
     v_sqlstr :=' select   count(1)'
                ||' from   user_constraints'   
                ||' where constraint_type=''P'' and  owner=user   and   
table_name='''||v_tablename ||'''' ;
     execute immediate(v_sqlstr) into v_rows;
     if v_rows >=1  then 
           v_sqlstr :='select   constraint_name'
                      ||' from   user_constraints'   
                      ||' where constraint_type=''P'' and  owner=user   and   
table_name='''||v_tablename ||'''' ;
           execute immediate(v_sqlstr) into v_pkname;
     end if;--Step          v_sqlstr := 'ALTER TABLE ' ||v_tablename ||' DROP CONSTRAINT '|| v_pkname ||'       if v_pkname is not null then 
     5: Delete the primary key


CASCADE';
         execute immediate(v_sqlstr);
     else
         v_pkname := 'pk_' ||v_tablename;
     end if; --The
     sixth step: increase the primary key
     v_sqlstr := 'ALTER TABLE ' ||v_tablename ||' ADD (CONSTRAINT '|| v_pkname ||' PRIMARY 
KEY(rpt_date,dept_id,item,key_no))';
     execute immediate(v_sqlstr);
end pr_zhaozhenlong_strsql;
/

dbms_metadata.get_ddl() is used to obtain the DDL of the object, and its specific usage is as follows.
Note: In sqlplus, in order to better display DDL, you need to set the following parameters:

set line 200
set pagesize 0
set long 99999
set feedback off
set echo off

1) Get DDL of tables, indexes, views, stored procedures, and functions

select dbms_metadata .get_ddl('TABLE','TABLE_NAME','
select dbms_metadata.get_ddl('INDEX','INDEX_NAME','INDEX_OWNER') from dual;
select dbms_metadata.get_ddl('VIEW','VIEW_NAME','VIEW_OWNER') from dual;
select dbms_metadata.get_ddl('PROCEDURE',' PROCEDURE_NAME','PROCEDURE_OWNER') from dual;
select dbms_metadata.get_ddl('FUNCTION','FUNCTION_NAME','FUNCTION_OWNER') from dual;

the following script is used to get all tables, indexes, views, stored procedures under a schema , function DDL

set pagesize 0
set long 90000
set feedback off
set echo off
spool schema_ddl.sql
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name,u.owner) FROM DBA_TABLES u;
SELECT DBMS_METADATA.GET_DDL('VIEW', u.view_name,u.owner) FROM DBA_VIEWS u;
SELECT DBMS_METADATA.GET_DDL('INDEX',u.index_name,u.owner) FROM DBA_INDEXES u;
select dbms_metadata.get_ddl('PROCEDURE',u.object_name, u.owner,) from dba_objects u where u.object_type = 'PROCEDURE';
select dbms_metadata.get_ddl('FUNCTION',u.object_name, u.owner,) from dba_objects u where u.object_type = 'FUNCTION';
spool off;

2) Get the DDL of the tablespace Get the DDL
of a single tablespace:

select dbms_metadata.get_ddl('TABLESPACE','TBS_NAME') from dual;

Get the DDL of all tablespaces:

SELECT DBMS_METADATA.GET_DDL('TABLESPACE', TS.tablespace_name)
FROM DBA_TABLESPACES TS;

3) Get the DDL of a user to get the DDL
of a single user:

select dbms_metadata.get_ddl('USER','EPAY_USER') from dual;

get the DDL of all users :

SELECT DBMS_METADATA.GET_DDL('USER',U.username)
FROM DBA_USERS U;

code
create or replace procedure spCreateTestTable
is
    v_CreateString varchar2(1000);
begin
    declare
        v_count number;
    begin
        v_count := 0;
        
        select count(*)
        into v_count
        from tab
        where tname='TEST_TABLE';
        
        if v_count=1 then
            dbms_output.put_line('test table already exists');
            v_CreateString := 'drop table test_table';
            execute immediate v_CreateString;
            commit;
        else
            dbms_output.put_line('test table created');
        end if;
        
        v_CreateString := 'create table test_table(' ||
                                                'aa varchar2(5), ' ||
                                                'bb varchar2(5))'; execute
        immediate v_CreateString;
        commit;
    exception
   when others
   then
        rollback;
   end;
end;


Program blocks in the data dictionary, which can be shared among different users and applications, and enable program optimization and reuse.
 
First, the creation and execution of stored procedures
1. Use SQL commands to create stored procedures The
syntax format is as follows:
 
Sql code  
create [or replace] procedure [schema.]procedureName[(param1 mode1 dataType1,...n)]  
    is | as  
      var1 type1 ;  
      var2 type2;  
      ...  
    begin  
        statements; /*procedure body, the operation to be performed*/  
    end;  
 
among them, mode1 indicates the type of the parameter, like the method parameter, there are three types of in, out and in out; dataType1 indicates the data type of the parameter.
Sample code:
 
Sql code  
create or replace procedure getModuleName(mid in number,mname out varchar)  
  as  
  begin  
    select name into mname from t_module where id=mid;  
  end;  
 
 
2. Call stored procedure The
syntax format is as follows:
 
Sql code  
exec[ute] procedureName [(param1,...n)] /*This can be executed like this in the command window*/  
 
Note:
You can also execute a defined stored procedure by directly entering the name of a stored procedure.
Sample code:
 
Sql code  
declare  
  mid number := 15;  
  mname varchar(20);  
begin  
  GETMODULENAME(mid,mname);  
  dbms_output.put_line(mname || ' ********ModuleName');  
end;  
 
 
 
2. Editing and modifying stored procedures
Modifying same as modifying views. Although there is also an alter procedure statement, it is used to recompile stored procedure. If you want to modify an already defined stored procedure, still use the create or replace procedure statement.
For example, modify the above getmodulename stored procedure as follows:
 
Sql code  
create or replace procedure getModuleName(mid in number,mname out varchar)  
  as  
  begin  
    if mid > 0 then  
        select name into mname from t_module where id=mid;  
    else  
        mname := null;  
    end if;  
  end;  
 
 
 
Third, delete the stored procedure
When a stored procedure is no longer needed, it can be deleted to release the memory resources occupied by it.
The syntax format is as follows:
 
Sql code  
drop procedure [schema.]procedureName;  
 
For example, delete the stored procedure of getmodulename as follows:
 
Sql code  
drop procedure getmodulename;  

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326845581&siteId=291194637