Oracle PL/SQL语句引发错误
我通过ADO将以下PL/SQL发送到远程oracle 11gr2服务器。 它的目的是检查用户是否存在。然后,如果它这样做了,杀死它的所有连接。最后,它删除了用户Oracle PL/SQL语句引发错误,sql,oracle,ado.net,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
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][ODBC驱动程序for Oracle][Oracle]ORA-06550:第1行,
第286列:PLS-00103:预期时遇到符号脱落
以下其中一项:
begin case declare elsif end exit for goto if loop mod
null pragma raise return select update with with with with with
您不能直接在PL/SQL中发出DDL,即DROP语句。您需要使用动态SQL运行DROP语句 实现这一点的最简单方法是使用EXECUTE IMMEDIATE语句,其方式与您在ALTER SESSION命令中使用它的方式类似:
希望它有帮助…您不能直接在PL/SQL中发出DDL,即DROP语句。您需要使用动态SQL运行DROP语句 实现这一点的最简单方法是使用EXECUTE IMMEDIATE语句,其方式与您在ALTER SESSION命令中使用它的方式类似:
希望它有帮助……我强烈建议您在存储过程中执行此操作。这将完成两件事:1您将从问题中删除jet解析器,并让Oracle在内部处理此问题。2您可以构造SP,使其仅返回1或0作为成功/失败,从而拒绝任何注入尝试。另外,请注意Ollie的建议,并使用绑定参数来进一步保护任何sql事务。@wave:另外,使用count1 over count*没有任何好处。此外,SQL解析引擎将count1更改为count*。请参阅Tom Kyte的许多文章:我强烈建议您在存储过程中执行此操作。这将完成两件事:1您将从问题中删除jet解析器,并让Oracle在内部处理此问题。2您可以构造SP,使其仅返回1或0作为成功/失败,从而拒绝任何注入尝试。另外,请注意Ollie的建议,并使用绑定参数来进一步保护任何sql事务。@wave:另外,使用count1 over count*没有任何好处。此外,SQL解析引擎将count1更改为count*。请参阅Tom Kyte在这方面的许多文章:您不能在DDL中使用绑定变量,因此不能以这种方式参数化ALTER系统或删除用户命令。您必须连接用户名。您可能希望使用DBMS_ASSERT.SCHEMA_NAME函数来验证传入的用户名是否为简单的架构名称,以防止SQL注入攻击,此外还需要记录调用并验证用户名是否合理,即您不希望有人意外删除Oracle交付的帐户。您不能这样做在DDL中使用绑定变量,即alter system和drop user。这在去掉绑定部分后就达到了目的。非常感谢。啊,是的,我在想什么。不能对DDL使用绑定变量。对不起,我发布答案时正匆匆出门。不过,答案的原则是正确的,为bind变量的“红鲱鱼”道歉。Justin是正确的,您仍然应该使用DBMS_资产包来保护您的过程不受SQL注入的影响。您不能在DDL中使用绑定变量,因此您不能以这种方式参数化ALTER SYSTEM或删除用户命令。您必须连接用户名。您可能希望使用DBMS_ASSERT.SCHEMA_NAME函数来验证传入的用户名是否为简单的架构名称,以防止SQL注入攻击,此外还需要记录调用并验证用户名是否合理,即您不希望有人意外删除Oracle交付的帐户。您不能这样做在DDL中使用绑定变量,即alter system和drop user。这在去掉绑定部分后就达到了目的。非常感谢。啊,是的,我在想什么。不能对DDL使用绑定变量。对不起,我发布答案时正匆匆出门。不过,答案的原则是正确的,为bind变量的“红鲱鱼”道歉。Justin是正确的,您仍然应该使用DBMS_资产包来保护您的过程不受SQL注入的影响。
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;
EXECUTE IMMEDIATE 'alter system kill session '':sid'','':serial'''
USING c.sid,
c.serial#;