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=326845535&siteId=291194637
Ranking