Oracle动态SQL语句的简单执行

在使用ODP.NET进行Oracle编程时,有时候SQL语句非常复杂,需要采用动态构造查询语句的情况,有两种方法可以构造动态的SQL语句,并执行返回结果集。

1、在数据访问层构造SQL语句

例如下面的语句,将构造完整的SQL语句赋值给CommandText,再传递到数据库进行执行,返回结果集。

None.gif loadCommand.CommandType  =  CommandType.Text
   loadCommand.CommandText = "Select * From Users"

   dataAdapter .SelectCommand = loadCommand
   dataAdapter . Fill(data)

   dataAdapter .SelectCommand = loadCommand
   dataAdapter . Fill(data)

该方法需要将整个SQL的构造过程放在DataAccess层,业务逻辑发生变化,修改不方便,而且每次查询需要传递给数据库很长的查询字符串,传递参数的效率也不高。

2、在存储过程中构造动态SQL语句并执行

 以下为一个完整的事例(经过删减),其中RefCursor 为自定义游标类型

None.gif PROCEDURE  G_Search(P_YearNO       IN   NUMBER ,
None.gif                              P_ControlType 
IN   NUMBER ,
None.gif                              P_Progress    
IN   CHAR ,
None.gif                              P_DepartID    
IN   VARCHAR2 ,
None.gif                              P_ProjectName 
IN  NVARCHAR2,
None.gif                              C_Projects    OUT RefCursor) 
IS
None.gif        e_ErrInterruption EXCEPTION;
None.gif        v_ErrID       
NUMBER -- Variable to hold the errorlog id
None.gif
        v_ErrCode      NUMBER -- Variable to hold the error message code
None.gif
        v_ErrText      VARCHAR2 ( 512 );  -- Variable to hold the error message text
None.gif
        v_ErrProc      VARCHAR2 ( 50 ) : =   ' G_Search ' ;
None.gif        v_DepartID    
VARCHAR2 ( 16 );
None.gif        v_ProjectName NVARCHAR2(
128 );
None.gif        v_SQL         
VARCHAR2 ( 512 );
None.gif        v_Where       
VARCHAR2 ( 256 );
None.gif    
BEGIN
None.gif    
None.gif        v_SQL   :
=   ' SELECT PROJECTID, PARENTID, PROJECTNAME ' ;
None.gif        v_SQL   :
=  v_SQL  ||   '  FROM PROJECTS A ' ;
None.gif        v_Where :
=   '  Where ' ;
None.gif    
None.gif        
--  年度
None.gif
         IF  P_YearNO  <   9999   THEN
None.gif            v_Where :
=  v_Where  ||   '   A.YearNO =  '   ||  P_YearNO  ||   '  And ' ;
None.gif        
ELSE
None.gif            v_Where :
=  v_Where  ||   '   A.YearNO <  '   ||  P_YearNO  ||   '  And ' ;
None.gif        
END   IF ;
None.gif        
--  控制类别
None.gif
         IF  P_ControlType  =   9   THEN
None.gif            v_Where :
=  v_Where  ||   '  A.ControlType < 9 And ' ;
None.gif        
ELSE
None.gif            v_Where :
=  v_Where  ||   '  A.ControlType =  '   ||  P_ControlType  ||
None.gif                       
'  And ' ;
None.gif        
END   IF ;
None.gif        
--  进度
None.gif
         IF  P_Progress  <   ' Z '   THEN
None.gif            v_Where :
=  v_Where  ||   '  A.Progress =  '''   ||  P_Progress  ||   '''  And ' ;
None.gif        
ELSE
None.gif            v_Where :
=  v_Where  ||   '  A.Progress <  '''   ||  P_Progress  ||   '''  And ' ;
None.gif        
END   IF ;
None.gif    
None.gif        
IF  TRIM(P_DepartID)  <>   ' % '   THEN
None.gif            v_Where :
=  v_Where  ||   '  A.DepartID =  '''   ||  P_DepartID  ||   '''  And ' ;
None.gif        
ELSE
None.gif            v_Where :
=  v_Where  ||   '  A.DepartID Like  '''   ||  P_DepartID  ||
None.gif                       
'''  And ' ;
None.gif        
END   IF ;
None.gif        
-- 项目名称
None.gif
        v_ProjectName : =  NVL(P_ProjectName,
None.gif                             
' % ' );
None.gif        
IF  v_ProjectName  <>   ' % '   THEN
None.gif            v_ProjectName :
=   ' % '   ||  P_ProjectName  ||   ' % ' ;
None.gif        
END   IF ;
None.gif        v_Where :
=  v_Where  ||   '  A.ProjectName Like  '   ||   ''''   ||  v_ProjectName  ||
None.gif                   
'''  And ' ;
None.gif    None.gif      
None.gif    
None.gif        v_SQL :
=  v_SQL  ||  v_Where;
None.gif    
None.gif        
OPEN  C_PROJECTS  FOR  v_SQL;
None.gif    
None.gif        
-- COMMIT;
None.gif
    EXCEPTION
None.gif        
-- 根据需要定义错误异常
None.gif
         WHEN  OTHERS  THEN
None.gif            
-- ROLLBACK;
None.gif
             v_ErrID   : =  SQLCODE;
None.gif            v_ErrText :
=  SQLERRM;
None.gif            raise_application_error(v_ErrID,
None.gif                                    v_ErrText);
None.gif    
END  G_Search;


该方法只需要传递给存储过程一些参数,使用游标返回数据。参数传递效率较高,而且业务逻辑在存储过程中,调整比较方便。该方法关键的在下面的语句:
Open C_Projects For v_SQL;
它直接使用游标打开构造的查询字符串即可。

注意事项:

A)、构造的SQL语句最后不能带有分号;
B)、SQL语句中对于字符和字符串的条件需要用单引号包括起来
C)、最重要:动态SQL语句需要防止SQL注入攻击。我们采用最简单的办法,只允许一个关键词查询,将关键词中的所有空格去掉。对于多关键词,需要将他们用空格拆开,再构造。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值