Oracle过程中执行动态SQL或DDL语句
如果你用的是Oracle8i 及以上的版本,那简单,在过程中用 execute immediate sql_str 就行, sql_str 是一个拼凑的 SQL 语句,但这个动态语句中带参数,或 Select 的结果要 into 到变量中时就要稍加留心一下了。
而在 8i 以前的版本(谁还用这么古老的玩艺,总有些不得已的地方,老系统考虑升级成本遗留下来的,应用软件所伴随着的等),都没法用 execute immediate,就得使用 DBMS_SQL 包来实现了
何谓动态 SQL 和 DDL 语句呢?通常在过程中要操作的表名、字段名都必须是明确的,否则编译过程时就要报错,但如果这两者也用变量名来表示就是动态的。
DDL 就是数据库对象定义的操作,如 CREATE TABLE/VIEW/INDEX/SYN/CLUSTER……,及这些对象的删除、修改操作等等。
比如在Oracle中有执行下面过程块的意图时,就要使用到 execute immediate 或是DBMS_SQL 包了。
当然下面的语句块是通不过的。
declare
col_name varchar2(30) := 'name'; --假定表user存在name字段
col_val varchar2(30);
begin
select col_name into col_val --按照惯常思维,可能就会这么写
from user where age between 18 and 25; --编译时会提示列名不存在的
drop table t2; --不能直接执行 DDL 语句,后面查询 t2 编译器就无能为力了
end;
现在我们提出对上面问题的解,针对第一个 Select 语句来说明,并假设查询中还带有参数。
块中的 DDL 也是类似的解法。
例子因力图涵盖更多内容,所以稍显复杂,如果不需要 into (如 update/delete 语句),或者不带参数,会简单多了,应不难简化。
有两种处理方法,以 8i 为分水岭。
1. Oracle 8i 及以上版本的过程中处理动态 SQL 语句的办法
declare
v_col_name varchar2(30) := 'name'; --字段名 name 用变量来表示
v_user_name varchar2(30); --用户名称
v_user_age integer; --用户年龄
v_sql_str varchar2(500); --动态 SQL 语句
begin
v_sql_str := 'select '||v_col_name||',age from users --字段名后面不能紧随 into 到变量了
where age between :start_age and :end_age and rownum=1'; --两个命名参数
--用 execute immediate 动态执行 SQL 语句
--注意其后的 into 字段值到变量的写法,还有 using 来代入参数
execute immediate v_sql_str into v_user_name,v_user_age using 18,25;
dbms_output.put_line('第一个符合条件的用户:'||v_user_name||',年龄:'||v_user_age);
end;
除此之外,在 Oracle 8i 及以上版本中,还能用 DBMS_UTILITY.EXEC_DDL_STATEMENT (ddl_sql_str)执行 DDL 语句。
2. Oracle 8i 以下版本相应解决之道,用 DBMS_SQL 包,如 Oracle 8.0.5 中
如果也用 execute immediate 的话编译过程时就会报如下错误:
Error: PLS-00103:出现符号"IMMEDIATE"在需要下列之一时:
:=.(@%;
符号":=在"IMMEDIATE"继续之前已插入。
Line: 3
declare
v_col_name varchar2(30) := 'name'; --字段名 name 用变量来表示
v_user_name varchar2(30); --用户名称
v_user_age integer; --用户年龄
v_sql_str varchar2(500); --动态 SQL 语句
v_cursorid integer; --游标 ID
v_dummy integer; --定义一个哑元变量
begin
v_sql_str := 'select '||v_col_name||',age from users --字段名后面不能紧随 into 到变量了
where age between :start_age and :end_age'; --两个命名参数
v_cursorid := dbms_sql.open_cursor; -- 为处理打开光标
dbms_sql.parse(v_cursorid,v_sql_str,dbms_sql.NATIVE); -- 分析SQL字符串
dbms_sql.bind_variable(v_cursorid,'start_age',8); --绑定变量 8 到 start_age
dbms_sql.bind_variable(v_cursorid,'end_age',25); --绑定变量 25 到 end_age
--定义输出的列,1为第1列,v_col_name任意,30是宽度,对于是VARCHAR2,CHAR类型要指定列宽
dbms_sql.define_column(v_cursorid,1,v_col_name,30);
dbms_sql.define_column(v_cursorid,2,v_user_age); --定义第2列,数字类型,无须指定列宽
--也可用 execute_and_fetch 执行后立即 fetch 第一行,其后还能 fetch_rows获取其余记录 v_dummy := dbms_sql.execute(v_cursorid); --执行语句,
while(dbms_sql.fetch_rows(v_cursorid)>0) --有记录时,fetch_rows 总是返回 1,否则为0 loop
dbms_sql.column_value(v_cursorid,1,v_user_name); --获取第一列的输出值
dbms_sql.column_value(v_cursorid,2,v_user_age); --获取第一列的输出值
dbms_output.put_line('符合条件的用户:'||v_user_name||',年龄:'||v_user_age);
end loop;
dbms_sql.close_cursor(v_cursorid); --关闭光标
end;
真的是很复杂啊,有条件还是赶紧升级你的数据库吧,越高越好。
当然,如果你只是用来执行一个简单的语句,没有参数,不在乎返回值的话,那也不是很费事。
需注意一个问题,在执行 dbms_sql.define_column()定义列时,如果指定了列宽,就会认为是字符串类型,并且编译时也要求字符串类型必须指定宽度。
在用
dbms_sql.column_value()接收输出值时必须符合前面的定义。
比如在定义第 2 列 age 时也加了列宽参数,如
dbms_sql.define_column(v_cursorid,2,v_user_age,10);——对于非字符串类型加了列宽参数也能编译通过,只是被误认为字符串
那在上面代码中接收这个字段值 dbms_sql.column_value(v_cursorid,2,v_user_age)时就会报类型不匹配的错误(ORA-06562:输出自变量的类型必须与列或赋值变量的类型匹配),因为前面定义该列时,加了列宽就被认为是字符串类型,不能用数字型的 v_user_age 接收该字段值。
oracle中executeimmediate的使用
oracle中executeimmediate的使用EXECUTE IMMEDIATE 是 Oracle 数据库的一个动态 SQL 语句执行命令。
它允许在运行时动态地构建和执行 SQL 语句的字符串,而不需要预编译。
EXECUTEIMMEDIATE执行的SQL语句可以是任何有效的SQL语句,包括SELECT、INSERT、UPDATE、DELETE等语句。
它可以使用变量和参数进行动态的值替换。
使用EXECUTEIMMEDIATE可以在运行时根据不同的条件和需求构建不同的SQL语句,从而实现更大的灵活性和可重用性。
以下是EXECUTEIMMEDIATE的一些常见用法:1.动态执行SELECT语句可以使用EXECUTEIMMEDIATE动态执行SELECT语句,并将结果存储在变量中。
例如:DECLAREl_emp_id NUMBER := 100;l_emp_name VARCHAR2(100);BEGINEXECUTE IMMEDIATE 'SELECT emp_name INTO :1 FROM employees WHERE emp_id = :2' INTO l_emp_name USING OUT l_emp_name,l_emp_id;DBMS_OUTPUT.PUT_LINE('Employee Name: ' , l_emp_name);END;在上面的示例中,通过使用 USING OUT 子句将变量 l_emp_name 传递给 EXECUTE IMMEDIATE,并在动态 SQL 语句中使用该变量。
使用 INTO 子句将结果存储在 l_emp_name 变量中。
2.动态执行DDL语句EXECUTEIMMEDIATE还可以用于动态执行DDL(数据定义语言)语句,例如创建表、修改表结构等。
例如:DECLAREl_table_name VARCHAR2(100);BEGINl_table_name := 'employees';EXECUTE IMMEDIATE 'DROP TABLE ' , l_table_name;DBMS_OUTPUT.PUT_LINE('Table ' , l_table_name , ' dropped successfully.');END;上面的示例使用 EXECUTE IMMEDIATE 删除名为 employees 的表。
oracle存储过程动态sql语句
oracle存储过程动态sql语句⼀、在oracle项⽬开发中越到问题:在利⽤ODP向oracle中插⼊数据时,如果这样写:insert into clobTable (id, story) values(1,'....'); 其中story为clob类型如果story的长度⼤于2000字节,直接插⼊将出现 ORA-01704:⽂字字符串过长的错误。
解决⽅案:⽅案⼀、利⽤参数insert into clobTable (id, story) values(1,:story);OracleParameter param = new OracleParameter("story", OracleDbType.Clob);param.Direction = ParameterDirection.Input;param.Value = str;cmd.Parameters.Add(param);⽅案⼆、利⽤存储过程这个就不⽤说了,写个存储过程,把参数传⼊即可。
⼆、解决⽅法oracle 中,如下操作:insert into table values(a,3,'⼀个长⽂章');ORA-01704: ⽂字字符串过长!虽然在表中已经是clob字段,⾜够存储4G的内容,但是如果存的是特别长的字符串,超过4000就会报错。
解决⽅法:⽅法⼀:就写个存储过程,然后⽤参数传过去就没问题了。
declarev_clob clob :='⼀个长⽂章';begininsert into table values(a,3,:clob);end;这样就可以插进去了,所以我觉得应该是隐式转换,oracle默认把字符串转换成 varchar2 类型,⽽这个字符串的长度,⼜⽐4000⼤所以会报ora-01704错误.真实环境⽤的存储过程:CREATE OR REPLACE PROCEDURE "BAI"."LOGMNRTXT" (tab1 in varchar2,scns in number,timestamps in varchar2,seg_owner in varchar2,table_name in varchar2,session_info in varchar2,sql_redo in clob,ssession in varchar2,serial in varchar2,operation in varchar2) isstr varchar(1000);--注意tab1必须要更改,发现原来的logmnr_contents20140524中的sql_redo为varchar,需要改成clobbeginstr:= 'insert into '||tab1||' values(:1,:2,:3,:4,:5,:6,:7,:8,:9)';execute immediate str using scns,to_date(timestamps,'yyyy-MM-ddhh24:mi:ss'),seg_owner,table_name,session_info,sql_redo,ssession,serial,operation;end logmnrtxt;/⽅法⼆:很复杂,其实没必要这么⽤,主要是为了学习⾼级的存储过程写法创建存储过程:CREATE OR REPLACE PROCEDURE p_In_Clob(pId IN NUMBER,outVar IN VARCHAR2)IStext_Var CLOB;amount_Var NUMBER;offset_Var NUMBER;BEGININSERT INTO test VALUES(pId,empty_clob());SELECT text INTO text_var FROM testWHERE id=pId;amount_var:=LENGTH(outVar);offset_var:=1;DBMS_LOB.WRITE(text_Var,amount_Var,offset_Var,outVar);COMMIT;END p_In_Clob;调⽤存储过程:beginp_In_Clob(1,'...');end;三、oracle 存储过程使⽤动态sqlOracle存储过程使⽤动态SQL 有两种写法:⽤ DBMS_SQL 或 execute immediate,建议使⽤后者。
oracle中execute_immediate的使用
oracle中execute_immediate的使用在Oracle数据库中,EXECUTE_IMMEDIATE是一条SQL语句,用于在执行过程中动态执行SQL语句。
EXECUTE_IMMEDIATE允许在一个PL/SQL块中动态执行任何有效的SQL或PL/SQL语句。
它允许通过字符串形式指定SQL语句,从而实现动态生成和执行SQL语句的目的。
EXECUTE_IMMEDIATE语句的基本语法如下:EXECUTE_IMMEDIATE (sql_statement [INTO { define_variable[, define_variable]..., record_variable}] [USING [in , out , in out] bind_argument[, [in , out , in out] bind_argument]...]);其中,sql_statement是要执行的SQL语句的字符串形式。
可以使用任何合法的SQL语句,如SELECT,INSERT,UPDATE,DELETE或PL/SQL块。
如果想要从查询中检索数据,则可以使用INTO子句将结果存储在变量中。
除了SQL语句本身之外,还可以使用USING子句传递绑定参数。
绑定参数可以在运行时动态地传递给SQL语句,从而增加灵活性和安全性。
绑定参数可以使用IN,OUT和INOUT模式指定,以指示参数是输入、输出还是输入输出参数。
以下是EXECUTE_IMMEDIATE语句的一些常见用法:1.动态创建表格:DECLAREv_table_name VARCHAR2(30) := 'my_table';BEGINEXECUTE IMMEDIATE 'CREATE TABLE ',v_table_name,' (id NUMBER, name VARCHAR2(30))';END;在上述示例中,通过传递v_table_name变量的值,可以动态创建一个表格。
ORACLE动态执行SQL语句
3. 返回结果集
str_column:='sal';--查询的列 str_Total:=0;--总和
str_sql:=' select '|| 'str_column' ||' from emp ' ; execute immediate str_sql into str_Total;
2. 返回单条结果
declare str varchar2(500); c_1 varchar2(10); r_1 test%rowtype; begin c_1:='测试人员'; str:='select * from test where name=:c WHERE ROWNUM=1'; execute immediate str into r_1 using c_1; DBMS_OUTPUT.PUT_LINE(R_||R_1.ADDRESS); end ;
网络错误503请刷新页面重试持续报错请尝试更换浏览器或网络环境
ORACLE动态执行 SQL语句
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。试验步骤如下:
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用egin EXECUTE IMMEDIATE 'drop table temp_1'; EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))'; end;
/*** DML ***/ declare v_1 varchar2(8); v_2 varchar2(10); str varchar2(50); begin v_1:='测试人员'; v_2:='北京'; str := 'INSERT INTO test (name ,address) VALUES (:1, :2)'; EXECUTE IMMEDIATE str USING v_1, v_2; commit; end;
在Oracle中执行动态SQL的几种方法
在Oracle中执⾏动态SQL的⼏种⽅法转载:以下为内容留存:在中执⾏动态SQL的⼏种⽅法在⼀般的sql操作中,sql语句基本上都是固定的,如:SELECT t.empno,t.ename FROM scott.emp t WHERE t.deptno = 20;但有的时候,从应⽤的需要或程序的编写出发,都可能需要⽤到动态SQl,如:当 from 后的表不确定时,或者where 后的条件不确定时,都需要⽤到动态SQL。
⼀、使⽤动态游标实现1、声明动态游标TYPE i_cursor_type IS REF CURSOR;2、声明游标变量my_cursor i_cursor_type;3、使⽤游标n_deptno:=20;dyn_select := 'select empno,ename from emp where deptno='||n_deptno;OPEN my_cursor FOR dyn_select;LOOPFETCH my_cursor INTO n_empno,v_ename;EXIT WHEN my_cursor%NOTFOUND;--⽤n_empno,v_ename做其它处理--....END LOOP;CLOSE dl_cursor;4、⼩结:动态游标可以胜任⼤多数动态SQL的需求了,使⽤简洁⽅便居家旅⾏之必备杀⼈放⽕之法宝。
⼆、使⽤ EXECUTE IMMEDIATE最早⼤家都使⽤DBMS_SQL包,但是太太⿇烦了,最终都放弃了。
但是⾃从有了EXECUTE IMMEDIATE之后,但要注意以下⼏点:EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执⾏动态的SQL语句或⾮运⾏时创建的PL/SQL块.动态创建和执⾏SQL语句性能超前,EXECUTE IMMEDIATE的⽬标在于减⼩企业费⽤并获得较⾼的性能,较之以前它相当容易编码.尽管DBMS_SQL仍然可⽤,但是推荐使⽤EXECUTE IMMEDIATE,因为它获的收益在包之上。
oracle execute immediate用法
oracle execute immediate用法在Oracle数据库中,EXECUTE IMMEDIATE语句用于动态执行SQL 或PL/SQL代码。
以下是EXECUTE IMMEDIATE的一些常见用法:执行动态SQL查询:
sql复制代码
EXECUTE IMMEDIATE 'SELECT column1, column2 FROM table WHERE condition';
执行动态INSERT操作:
sql
EXECUTE IMMEDIATE 'INSERT INTO table (column1, column2) VALUES (:value1, :value2)';
执行动态UPDATE操作:
sql
EXECUTE IMMEDIATE 'UPDATE table SET column1 = :value WHERE condition';
执行动态DELETE操作:
sql
EXECUTE IMMEDIATE 'DELETE FROM table WHERE condition';
在上述示例中,你可以使用绑定变量(例如::value1、:value2等)来绑定实际的参数值,这样可以避免SQL注入攻击,并提高代码的可读性和可维护性。
除了基本的EXECUTE IMMEDIATE语句外,你还可以使用其他功能和选项来扩展其功能,例如使用绑定变量、错误处理、动态创建表等。
你可以查阅Oracle文档以获取更多关于EXECUTE IMMEDIATE的详细信息和示例。
oracle数据库ddl语句
oracle数据库ddl语句Oracle数据库DDL语句是用于定义、修改和删除数据库对象的语句。
DDL 是数据定义语言(Data Definition Language)的缩写,它包括了一系列的命令,如CREATE、ALTER和DROP等,用于管理数据库的结构和元数据。
在本文中,我们将逐步回答关于Oracle数据库DDL语句的一系列问题。
什么是Oracle数据库DDL语句?Oracle数据库DDL语句指的是用于管理数据库结构和元数据的命令。
这些命令允许我们创建、修改和删除数据库对象,如表、视图、索引、序列和约束等。
DDL语句允许数据库管理员对数据库进行结构上的修改,以适应业务需求的变化。
有哪些常用的Oracle数据库DDL语句?Oracle数据库提供了一套完整的DDL语句,以下是一些常用的DDL语句:1. CREATE TABLE语句:用于创建一个新的数据库表。
可以定义表的列以及各个列的数据类型和约束。
2. ALTER TABLE语句:用于修改已存在的数据库表的结构。
可以添加或删除列,修改列的数据类型,以及添加或删除约束等。
3. DROP TABLE语句:用于删除一个数据库表及其数据。
这将会删除表的结构以及与该表关联的索引、触发器等。
4. CREATE INDEX语句:用于创建一个新的索引。
索引可以加速对数据库表的查询操作。
5. ALTER INDEX语句:用于修改已存在的索引的结构。
可以修改索引的名称、添加或删除索引的列等。
6. DROP INDEX语句:用于删除一个索引。
7. CREATE VIEW语句:用于创建一个新的视图。
视图是一个虚拟表,它包含基础表中的数据,但不实际存储数据。
8. ALTER VIEW语句:用于修改已存在的视图的结构。
9. DROP VIEW语句:用于删除一个视图。
10. CREATE SEQUENCE语句:用于创建一个新的序列。
序列是一种自动递增的数字。
11. ALTER SEQUENCE语句:用于修改已存在的序列的属性。
动态SQL的使用方法
动态SQL的使⽤⽅法⼀般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使⽤SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使⽤,要想实现在PL/SQL中使⽤DDL语句及系统控制语句,可以通过使⽤动态SQL来实现。
⾸先我们应该了解什么是动态SQL,在Oracle数据库开发PL/SQL块中我们使⽤的SQL分为:静态SQL语句和动态SQL语句。
所谓静态SQL指在PL/SQL块中使⽤的SQL语句在编译时是明确的,执⾏的是确定对象。
⽽动态SQL是指在PL Oracle中动态SQL可以通过本地动态SQL来执⾏,也可以通过DBMS_SQL包来执⾏。
下⾯就这两种情况分别进⾏说明: ⼀、本地动态SQL 本地动态SQL是使⽤EXECUTE IMMEDIATE语句来实现的。
1、本地动态SQL执⾏DDL语句: 需求:根据⽤户输⼊的表名及字段名等参数动态建表。
create or replace procedure proc_test(table_name in varchar2, --表名field1 in varchar2, --字段名datatype1 in varchar2, --字段类型field2 in varchar2, --字段名datatype2 in varchar2--字段类型) asstr_sql varchar2(500);beginstr_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;execute immediate str_sql; --动态执⾏DDL语句exceptionwhen others thennull;end ; 以上是编译通过的存储过程代码。
下⾯执⾏存储过程动态建表。
SQL>execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);PL/SQL procedure successfully completedSQL>desc dinya_test;Name Type Nullable Default Comments---- ------------- -------- ------- --------ID NUMBER(8)NAME VARCHAR2(100) YSQL> 到这⾥,就实现了我们的需求,使⽤本地动态SQL根据⽤户输⼊的表名及字段名、字段类型等参数来实现动态执⾏DDL语句。
oracle存储过程executeimmediate用法
oracle存储过程executeimmediate用法Oracle数据库中的EXECUTE IMMEDIATE语句用于在存储过程或匿名块中执行动态SQL语句。
它允许在运行时构建和执行SQL语句,而不是在编译时确定。
EXECUTEIMMEDIATE语句的基本语法如下:EXECUTE IMMEDIATE <sql_statement>;其中,<sql_statement>是要执行的动态SQL语句。
可以是一个字符串常量,也可以是一个字符串变量。
使用EXECUTEIMMEDIATE的主要优点是它提供了更大的灵活性和动态性。
它可以用于执行任意的SQL语句,包括SELECT、INSERT、UPDATE和DELETE语句,以及DDL语句如CREATETABLE、ALTERTABLE和DROPTABLE 等。
这使得存储过程和匿名块能够根据不同的条件和参数执行不同的SQL 语句。
以下是一些EXECUTEIMMEDIATE语句的示例用法:1.执行SELECT语句并将结果存储在游标中:DECLAREmy_cursor SYS_REFCURSOR;BEGINEXECUTE IMMEDIATE 'SELECT * FROM my_table' INTO my_cursor;--处理游标中的结果END;2.执行INSERT语句插入数据:DECLAREv_value NUMBER := 100;BEGINEXECUTE IMMEDIATE 'INSERT INTO my_table (column1) VALUES (:value)' USING v_value;--插入数据END;3.执行UPDATE语句更新数据:DECLAREv_id NUMBER := 1;v_value NUMBER := 100;BEGINEXECUTE IMMEDIATE 'UPDATE my_table SET column1 = :value WHERE id = :id' USING v_value, v_id;--更新数据END;4.执行DELETE语句删除数据:DECLAREv_id NUMBER := 1;BEGINEXECUTE IMMEDIATE 'DELETE FROM my_table WHERE id = :id' USING v_id;--删除数据END;5.执行DDL语句创建表:DECLAREv_table_name VARCHAR2(100) := 'my_table';BEGINEXECUTE IMMEDIATE 'CREATE TABLE ' , v_table_name , ' (id NUMBER, name VARCHAR2(100))';--创建表END;需要注意的是,EXECUTEIMMEDIATE语句在执行动态SQL语句时,需要对输入的参数进行绑定。
Oracle动态SQL语句的简单执行
Oracle动态SQL语句的简单执⾏在使⽤进⾏Oracle编程时,有时候SQL语句⾮常复杂,需要采⽤动态构造查询语句的情况,有两种⽅法可以构造动态的SQL语句,并执⾏返回结果集。
1、在数据访问层构造SQL语句例如下⾯的语句,将构造完整的SQL语句赋值给CommandText,再传递到数据库进⾏执⾏,返回结果集。
mandType = CommandType.TextmandText = "Select * From Users"dataAdapter .SelectCommand = loadCommanddataAdapter . Fill(data)dataAdapter .SelectCommand = loadCommanddataAdapter . Fill(data)该⽅法需要将整个SQL的构造过程放在DataAccess层,业务逻辑发⽣变化,修改不⽅便,⽽且每次查询需要传递给数据库很长的查询字符串,传递参数的效率也不⾼。
2、在存储过程中构造动态SQL语句并执⾏以下为⼀个完整的事例(经过删减),其中RefCursor 为⾃定义游标类型PROCEDURE G_Search(P_YearNO IN NUMBER,P_ControlType IN NUMBER,P_Progress IN CHAR,P_DepartID IN VARCHAR2,P_ProjectName IN NVARCHAR2,C_Projects OUT RefCursor) ISe_ErrInterruption EXCEPTION;v_ErrID NUMBER; --Variable to hold the errorlog idv_ErrCode NUMBER; --Variable to hold the error message codev_ErrText VARCHAR2(512); --Variable to hold the error message textv_ErrProc VARCHAR2(50) :='G_Search';v_DepartID VARCHAR2(16);v_ProjectName NVARCHAR2(128);v_SQL VARCHAR2(512);v_Where VARCHAR2(256);BEGINv_SQL :='SELECT PROJECTID, PARENTID, PROJECTNAME ';v_SQL := v_SQL ||' FROM PROJECTS A';v_Where :=' Where';-- 年度IF P_YearNO <9999THENv_Where := v_Where ||' A.YearNO = '|| P_YearNO ||' And';ELSEv_Where := v_Where ||' A.YearNO < '|| P_YearNO ||' And';END IF;-- 控制类别IF P_ControlType =9THENv_Where := v_Where ||' A.ControlType < 9 And';ELSEv_Where := v_Where ||' A.ControlType = '|| P_ControlType ||' And';END IF;-- 进度IF P_Progress <'Z'THENv_Where := v_Where ||' A.Progress = '''|| P_Progress ||''' And';ELSEv_Where := v_Where ||' A.Progress < '''|| P_Progress ||''' And';END IF;IF TRIM(P_DepartID) <>'%'THENv_Where := v_Where ||' A.DepartID = '''|| P_DepartID ||''' And';ELSEv_Where := v_Where ||' A.DepartID Like '''|| P_DepartID ||''' And';END IF;--项⽬名称v_ProjectName := NVL(P_ProjectName,'%');IF v_ProjectName <>'%'THENv_ProjectName :='%'|| P_ProjectName ||'%';END IF;v_Where := v_Where ||' A.ProjectName Like '||''''|| v_ProjectName ||''' And';v_SQL := v_SQL || v_Where;OPEN C_PROJECTS FOR v_SQL;--COMMIT;EXCEPTION--根据需要定义错误异常WHEN OTHERS THEN--ROLLBACK;v_ErrID := SQLCODE;v_ErrText := SQLERRM;raise_application_error(v_ErrID,v_ErrText);END G_Search;该⽅法只需要传递给存储过程⼀些参数,使⽤游标返回数据。
