Oracle PL / SQL语句抛出错误

时间:2011-11-09 16:59:00

标签: sql oracle ado.net

我通过ADO将以下PL / SQL发送到远程oracle 11gr2服务器。 它的目的是检查用户是否存在。然后如果确实如此,就杀死它的所有连接。最后它会让用户失望。

DECLARE   
   i INTEGER;  
BEGIN  
   select count(1) into i from dba_users where username='<schema>';
   if i=0 THEN 
     FOR c IN (SELECT s.sid,s.serial# FROM v$session s WHERE s.username = '<schema>') LOOP    
       EXECUTE IMMEDIATE 'alter system kill session ''' ||c.sid || ',' || c.serial# || '''';  
     END LOOP;   
     drop user <schema> Cascade;   
   END IF;  
END;

经过多次调整后我收到的错误信息仍然是:

  

错误:[Microsoft] [Oracle的ODBC驱动程序] [Oracle] ORA-06550:第1行,   第286行:PLS-00103:在期待时遇到符号“DROP”   以下之一:

     

(如果循环mod为,则开始案例声明其他elsif结束退出goto   null pragma raise返回选择更新时使用        &LT;&LT;   继续关闭当前删除获取锁定插入打开回滚   savepoint set sql execute commit forall merge pipe purge

它不喜欢在IF语句中删除的语法。有没有人知道谁能正常运行?

编辑: 要清楚,我通常不会以这种方式执行此声明。但由于环境原因,这是唯一可能的方式,并没有造成任何安全风险。我知道我几乎违反了所有良好做法,但这次是必要的!

1 个答案:

答案 0 :(得分:4)

您无法直接在PL / SQL中发出DDL(即DROP)语句,您需要使用动态SQL运行DROP语句。

实现此目的的最简单方法是使用EXECUTE IMMEDIATE语句(与您已经将其用于ALTER SESSION命令的方式类似): http://download.oracle.com/docs/cd/B12037_01/appdev.101/b10807/13_elems017.htm

DECLARE
   i INTEGER;
BEGIN
   SELECT COUNT( 1 )
     INTO i
     FROM dba_users
    WHERE username = '<schema>';

   IF i = 0
   THEN
      FOR c IN ( SELECT s.sid,
                        s.serial#
                   FROM v$session s
                  WHERE s.username = '<schema>' )
      LOOP
         EXECUTE IMMEDIATE 'alter system kill session ''' || 
                           c.sid || ',' || c.serial# || '''';
      END LOOP;

      EXECUTE IMMEDIATE 'DROP USER :username CASCADE'
      USING '<schema>';   
   END IF;
END;

顺便提一下,您可能希望使用绑定变量而不是连接动态SQL中的值,因为它可以提高性能,尤其是在循环中。

e.g。

EXECUTE IMMEDIATE 'alter system kill session '':sid'','':serial'''
USING c.sid,
      c.serial#;

希望它有所帮助...