【问题标题】:ORA-00933: SQL command not properly ended when using execute immediateORA-00933: 使用立即执行时 SQL 命令未正确结束
【发布时间】:2019-02-12 20:48:58
【问题描述】:

当我跑步时

SELECT COUNT(*) 
  INTO l_entry_found 
  FROM hera.hera_user@iam 
 WHERE username = docm.eb_key;

不立即执行它就可以工作。

execute immediate'
      SELECT COUNT(*) INTO l_entry_found FROM hera.hera_user@iam WHERE 
      username = docm.eb_key;';

但是会抛出ora-00933。

可能是什么问题,我该如何解决?提前致谢!

【问题讨论】:

  • 你不能在动态sql中使用select into
  • 您还需要删除 SQL 字符串中的 ;。

标签: plsql ora-00933


【解决方案1】:

您不能在动态 SQL 中使用 select into 而且你也不需要分号

declare
  l_entry number(10);
begin

  execute immediate'
        SELECT COUNT(*) FROM hera.hera_user@iam WHERE 
        username = '''||docm.eb_key||'''' INTO l_entry;
end;

【讨论】:

  • execute immediate 中的每个变量是否也需要在那里定义?因为我现在在docm.eb_key上得到一个无效的标识符
  • 如果您选择的结果超过一列,那么您需要为每一列设置一个变量
【解决方案2】:

你有一些问题;说你有一张像

这样的桌子
create table someTable(userName varchar2(100))

还有类似的代码:

declare
    someVariable    varchar2(100);
    l_entry_found   number;
begin
    someVariable := 'someName';
    --
    SELECT COUNT(*)
    INTO l_entry_found
    FROM someTable
    WHERE username = someVariable;
end;

如果你想切换到动态 SQL,你需要

  • 去掉分号
  • 使用绑定变量传递参数
  • 将INTO移到动态部分之外

您的代码可能是:

declare
    someVariable    varchar2(100);
    l_entry_found   number;
begin
    someVariable := 'someName';
    --
    execute immediate 
    'SELECT COUNT(*)
    FROM someTable
    WHERE username = :bindVar'
    into l_entry_found
    using someVariable;
end;

这里我假设您有充分的理由切换到动态 SQL,例如,您的表名可能会根据某些参数而改变;如果没有,简单的 SQL 就足以完成您的任务。

【讨论】:

  • 该代码将安装在我们的生产环境中,但只会在测试服务器上使用。数据库链接 .@iam 在生产环境中不存在,因此在没有动态 SQL 的情况下使用它会给我们带来有效的无效。但是,此时我的主要问题是,我需要在动态 SQL 内部有一个循环变量,我不能在那里使用它。整个事情只是一个小的睡眠程序,除非等待一些数据到达 .@iam DB,否则它什么都不做。如果我的问题没有解决方法,也许只能用硬连线等待 10 分钟替换它。
  • 程序检查#hera is l_cnt number := 0;程序 check#docm 是 l_entry_found 编号; l_eb_key varchar2(10);在 (SELECT eb_key from tst_migr$eb_docm) 循环 l_eb_key := docm.eb_key;立即执行'SELECT COUNT(*) FROM hera.hera_user@iam WHERE username = l_eb_key' INTO l_entry_found;如果 l_entry_found = 0 并且 l_cnt
【解决方案3】:

EXECUTE IMMEDIATE 语句执行动态 SQL 语句或匿名 PL/SQL 块。你可以用它来发出不能在PL/SQL中直接表示的SQL语句,或者构建你事先不知道所有表名、WHERE子句等的语句

继续你的问题

-- Case using 1 output column 'COUNT(*)', 1 filter variable 'eb_key'
DECLARE
  --
  eb_key VARCHAR2(100) := 'something';
  l_entry_found number;
  --
BEGIN 
  execute immediate 'SELECT COUNT(*) FROM hera.hera_user@iam WHERE username = :eb_key;' USING eb_key INTO l_entry_found;
END;

-- Case using 2 output column 'COUNT(*)', 3 filter variable 'eb_key'
DECLARE
  --
  eb_column1 VARCHAR2(100) := 'something';
  eb_column2 VARCHAR2(100) := 'something';
  l_entry_found1 number;
  l_entry_found2 number;
  --
BEGIN 
  execute immediate 'SELECT column1, column2 FROM hera.hera_user@iam WHERE username = :eb_1 AND lastname = :eb_2;' USING eb_column1, eb_column2 INTO l_entry_found1,l_entry_found2;
END;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-09
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多