【问题标题】:Oracle execute immediateOracle 立即执行
【发布时间】:2018-01-30 09:31:32
【问题描述】:

有一些我无法弄清楚问题出在哪里的预言机,如果你能在这里帮助我

ORA-00911: invalid character
ORA-06512: at line 20

第 20 行是EXECUTE IMMEDIATE SQL_STMT INTO P_COUNT USING L_RB_OD, L_RB_DO;

我有 10-15 个表,每个表都有相似的名称和列 TableName_ID,其中包含序列,所以我做了一个程序,从表 (@) 中选择一定数量的数据 (P_Bucket) 987654325@)。 它还将选择选择到P_COUNT 中的总行数并返回P_DATA sys_refcursor。程序编译成功但不会执行。

DECLARE
    P_PAR_01 VARCHAR2(5) := '2';
    P_BUCKET NUMBER := 200;
    P_TABLE VARCHAR2(15) := 'KB_FL_1';
    P_COUNT NUMBER;
    P_DATA SYS_REFCURSOR;
    L_RB_OD NUMBER;
    L_RB_DO NUMBER;
    L_RB NUMBER;
    SQL_STMT VARCHAR2(1000);
BEGIN
    L_RB := CAST(P_PAR_01 AS NUMBER);
    L_RB_DO := L_RB * P_BUCKET;
    L_RB_OD := L_RB_DO - (P_BUCKET - 1);

    SQL_STMT := 'SELECT COUNT(*)
                   FROM ' || P_TABLE || ' 
                   WHERE 1 = 1
                         AND ' || P_TABLE || '_ID BETWEEN :1 AND :2'; -- was :2;';

    EXECUTE IMMEDIATE SQL_STMT INTO P_COUNT USING L_RB_OD, L_RB_DO;

    OPEN P_DATA FOR 
    'SELECT * FROM ' || P_TABLE || '  
     WHERE 1 = 1
           AND ' || P_TABLE || ' _ID BETWEEN :1 AND :2
     ORDER BY ID_LICA' USING L_RB_OD, L_RB_DO;  -- was ORDER BY ID_LICA;'    
END;

编辑:正如 cmets 所说,动态 SQL 不使用分号,但即使在删除分号后,我也会在 OPEN P_DATA FOR 处收到错误 invalid character

【问题讨论】:

  • 报告的无效字符是';'。动态 SQL 字符串不需要它。
  • @MaheswaranRavisankar 我删除了分号,你是对的......这是个问题:) 必须是这样的......但现在我在OPEN P_DATA FOR 得到Invalid character,之后我删除了两个分号
  • 那个“分号”:2;,在 ':2' 之后。分号用于 PL/SQL,不要在 SQL 语句中使用。那也是ID_LICA;。此外,您在“_ID BETWEEN ...”中有一个空格
  • 动态光标也一样。也是前导空格'_ID BETWEEN :1 AND :2'
  • 编写动态 SQL 很困难,因为它将编译错误转化为运行时错误。您应该养成在变量中构建动态语句的习惯。然后您可以在执行字符串之前输出变量。这将使您非常容易发现您制作的灯笼裤。

标签: oracle dynamic select-into


【解决方案1】:

您必须从动态 SQL 中删除分号;此外,您必须在第二个动态查询中删除一个空格:' _ID' 应该是 '_ID'。 这应该有效:

DECLARE
    P_PAR_01 VARCHAR2(5) := '2';
    P_BUCKET NUMBER := 200;
    P_TABLE VARCHAR2(15) := 'KB_FL_1';
    P_COUNT NUMBER;
    P_DATA SYS_REFCURSOR;
    L_RB_OD NUMBER;
    L_RB_DO NUMBER;
    L_RB NUMBER;
    SQL_STMT VARCHAR2(1000);
BEGIN
    L_RB := CAST(P_PAR_01 AS NUMBER);
    L_RB_DO := L_RB * P_BUCKET;
    L_RB_OD := L_RB_DO - (P_BUCKET - 1);

    SQL_STMT := 'SELECT COUNT(*)
                   FROM ' || P_TABLE || ' 
                   WHERE 1 = 1
                         AND ' || P_TABLE || '_ID BETWEEN :1 AND :2';
    EXECUTE IMMEDIATE SQL_STMT INTO P_COUNT USING L_RB_OD, L_RB_DO;

    OPEN P_DATA FOR 
    'SELECT * FROM ' || P_TABLE || '  
     WHERE 1 = 1
           AND ' || P_TABLE || '_ID BETWEEN :1 AND :2
     ORDER BY ID_LICA' USING L_RB_OD, L_RB_DO;  


END;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2020-03-19
    相关资源
    最近更新 更多