我通过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语句中删除的语法。有没有人知道谁能正常运行?
编辑: 要清楚,我通常不会以这种方式执行此声明。但由于环境原因,这是唯一可能的方式,并没有造成任何安全风险。我知道我几乎违反了所有良好做法,但这次是必要的!
答案 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#;
希望它有所帮助...