Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/SQL语句引发错误_Sql_Oracle_Ado.net - Fatal编程技术网

Oracle PL/SQL语句引发错误

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

我通过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][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#;