带有索引变量 oracle 的 TOP

Posted

技术标签:

【中文标题】带有索引变量 oracle 的 TOP【英文标题】:TOP with index variable oracle 【发布时间】:2020-08-05 14:37:07 【问题描述】:

我试图使用变量“ind”在我的选择中获取 ROWNUM,但每次我尝试使用该变量时都会收到如下错误:

ORA-01008:并非所有变量都绑定

或者这两个:

ORA-01403:未找到数据

ORA-06512:在第 10 行

    DECLARE 
texto VARCHAR2(255);
ind NUMBER := 0;
BEGIN
   LOOP
     ind := ind + 1;
     IF ind > 3 THEN
      EXIT;
     END IF;
     SELECT TEXTO_LOG 
     INTO texto
      from table WHERE REGEXP_LIKE(TEXTO_LOG, 'Alteração') AND ROWNUM >= :ind AND ROWNUM <= :ind ;
      dbms_output.put_line(substr(trim(texto), 1, instr(texto, ' ')));
      dbms_output.put_line(substr(texto, 0, 100));
     
    END LOOP;
END;
/

我搜索并发现有人说并非所有绑定的变量都是错误,我不确定是否是。 我用不同的运算符尝试了 ROWNUM。有什么建议吗?

【问题讨论】:

ind:ind 是两个不同的东西。 【参考方案1】:

使用rownum 是这里的问题,除了已经回答的其他问题。像 rownum>=2 和 rownum

但是作为解决方法,将 rownum 放在 from 子句中并将其限制在外部应该可以工作,

DECLARE
   texto VARCHAR2(255);
   ind   NUMBER := 0;
BEGIN
   LOOP
      ind := ind + 1;
      IF ind > 3
      THEN
         EXIT;
      END IF;
      SELECT texto_log 
      INTO texto
      FROM   (SELECT texto_log
                    ,rownum myrownum
              FROM   TABLE
              WHERE  regexp_like(texto_log
                                ,'Alteração'))
      WHERE  myrownum >= ind
      AND    myrownum <= ind;
      dbms_output.put_line(substr(TRIM(texto)
                                 ,1
                                 ,instr(texto
                                       ,' ')));
      dbms_output.put_line(substr(texto
                                 ,0
                                 ,100));
   
   END LOOP;
END;
/

【讨论】:

我找到了 AskTom 的一个很好的解释,asktom.oracle.com/pls/asktom/…。 您在cluase中漏掉了列名【参考方案2】:

错误是你引用:ind 好像它是一个绑定变量,但它不是。它实际上是在 DECLARE 部分中声明的变量。

你可以试试这个

** 更新**

由于您的查询看起来失败,原因可能在于查询本身。运行这个并获取输出并单独运行

set serveroutput on size unlimited 
DECLARE 
texto VARCHAR2(255);
ind    NUMBER := 0;
BEGIN
  for r in 1..4 
   LOOP
     ind := r + 1;
   dbms_output.put_line ( q'[SELECT TEXTO_LOG 
         INTO texto
          from table WHERE REGEXP_LIKE(TEXTO_LOG, 'Alteração') AND ROWNUM <= ind ;
          dbms_output.put_line(substr(trim(texto), 1, instr(texto, ' ')));
          dbms_output.put_line(substr(texto, 0, 100));]');
   exit when ind > 3;
   END LOOP;
END;
/

虽然你可以像这样更容易构建它

DECLARE 
texto VARCHAR2(255);
ind    NUMBER := 0;
BEGIN
  for r in 1..4 
   LOOP
     ind := r + 1;
     dbms_output.put_line(ind);
     SELECT TEXTO_LOG 
     INTO texto
      from table WHERE REGEXP_LIKE(TEXTO_LOG, 'Alteração') AND ROWNUM >= ind AND ROWNUM <= ind ;
      dbms_output.put_line(substr(trim(texto), 1, instr(texto, ' ')));
      dbms_output.put_line(substr(texto, 0, 100));
     exit when ind > 3;
   END LOOP;
END;
/

示例

SQL> DECLARE
texto VARCHAR2(255);
ind    NUMBER := 0;
BEGIN
  for r in 1..4
   LOOP
     ind := r + 1;
     dbms_output.put_line(ind);
         exit when ind > 3;
   END LOOP;
END;
/  2    3    4    5    6    7    8    9   10   11   12
2
3
4

PL/SQL procedure successfully completed.

SQL>

【讨论】:

我之前试过不带 : ,把 : 尝试不同的东西,它给了我 ORA-01403: no data found ORA-06512: at line 10 I'm using OCI 12.1 PL/SQL 然后制作查询本身的 dbms_output,因为我的示例中的其他所有内容都可以正常工作 您试图只获得一行。如果失败,只打印查询以查看它是否有效 @Danielr,我更新了答案。尝试打印查询以查看输出,因此您可以运行该部分以查看发生了什么,因为我的示例中的程序的其余部分可以正常工作【参考方案3】:

带隐式光标

DECLARE 
-- texto VARCHAR2(255);
ind NUMBER := 0;
BEGIN
   
    FOR i IN (SELECT TEXTO_LOG FROM table WHERE REGEXP_LIKE(TEXTO_LOG, 'Alteração'))
     LOOP  
         ind:=ind+1;
         EXIT WHEN ind >3;
         DBMS_OUTPUT.PUT_LINE(SUBSTR(TRIM(i.TEXTO_LOG), 1, INSTR(i.TEXTO_LOG, ' ')));
         DBMS_OUTPUT.PUT_LINE(SUBSTR(i.TEXTO_LOG, 0, 100));
     END LOOP;
END;

【讨论】:

只有一件事就是将退出条件放在增量旁边以匹配与问题相同的输出。 @Sujitmohanty30 谢谢没有注意到剪切和粘贴

以上是关于带有索引变量 oracle 的 TOP的主要内容,如果未能解决你的问题,请参考以下文章

Oracle --- 表索引替代变量数据库事务

错误:在 Oracle 上创建索引时缺少右括号

如何将带有索引列表的dict映射到新变量

python使用np.argsort对一维numpy概率值数据排序获取倒序索引获取的top索引(例如top2top5top10)索引二维numpy数组中对应的原始数据:原始数据概率最大的头部数据

python使用np.argsort对一维numpy概率值数据排序获取升序索引获取的top索引(例如top2top5top10)索引二维numpy数组中对应的原始数据:原始数据概率最小的头部数据

Azure SQL、聚集列存储索引、“TOP”性能