【问题标题】:PL/SQL retrieve multiple rows using SELECT INTO in OraclePL/SQL 在 Oracle 中使用 SELECT INTO 检索多行
【发布时间】:2017-03-18 15:19:09
【问题描述】:

我正在尝试创建一个触发器,该触发器在将新行插入到表中时触发。触发器应检查该表是否有任何行,其列中的值等于插入行中同一列的值。然后我需要更新原始表中与所选行具有相同 ID 的行。现在我需要请求检索数据(所有列),这就是我遇到麻烦的时候。

问题是我需要声明一个变量,该变量将用于存储该请求的结果。该变量应该与我从中检索数据的表具有相同的类型,但是当我这样声明它时(REC_ROAD_INT 是我的表):

DECLARE REQUEST_RESULT REC_ROAD_INT%TYPE;

我明白了

%TYPE must be applied to a variable, column, field or attribute, not to "REC_ROAD_INT"

我实际上可以检索我需要的数据,但仅在表只有 1 行满足要求的情况下。这是一个示例:

create or replace TRIGGER INSERT_ROAD_TRIGGER 
BEFORE INSERT ON REC_ROAD_INT
FOR EACH ROW
DECLARE
  ROAD_ID NUMBER;
  ROAD_NAME VARCHAR2(20);
  ROAD_START_KM NUMBER;
  ROAD_END_KM NUMBER;
BEGIN 
    SELECT ID, NAME, START_KM, END_KM INTO ROAD_ID, ROAD_NAME, ROAD_START_KM, ROAD_END_KM
    FROM REC_ROAD_INT
    WHERE (:NEW.START_KM BETWEEN START_KM AND END_KM) OR 
      (:NEW.END_KM BETWEEN START_KM AND END_KM);
    IF INSERTING 
    THEN 
      DBMS_Output.Put_Line('INSERTING');
      DBMS_Output.Put_Line('Inserting road: ' || :NEW.ID || ' ' || :New.NAME || ' ' || :New.START_KM || ' ' || :New.END_KM);
      DBMS_Output.Put_Line('Crossing road: ' || 'ID = ' || ROAD_ID || ', NAME = ' || ROAD_NAME || 
              ', START_KM = ' || ROAD_START_KM || ', END_KM = ' || ROAD_END_KM);
    END IF;
END;

如何获取所有行?谢谢。

【问题讨论】:

  • 你可以使用cursor
  • 听起来你在寻找复合触发器viralpatel.net/blogs/…
  • @Akio Hamasaki,这是个好主意,我会试试的
  • REC_ROAD_INT 上的行级触发器通常不能在不引发变异表异常的情况下查询 REC_ROAD_INT。可以使用复合触发器或一系列行级和语句级触发器(取决于 Oracle 版本)以及可能带有集合的包,但这有点复杂。这看起来应该由执行插入的过程而不是通过触发器来验证。
  • 这就是为什么你总是必须使用游标而不是 select into 语句。

标签: sql oracle plsql dml database-trigger


【解决方案1】:

如果我理解正确,您正在尝试声明一个表类型的变量。您的问题是该变量不是 %TYPE 而是 %ROWTYPE。

DECLARE
  emp_rec scott.emp%ROWTYPE;
BEGIN
 .....
END;
/

您的第二个要求非常令人困惑。删除 where 条件以获取所有行。你需要更加具体和清晰。

【讨论】:

  • 不幸的是我无法删除WHERE 条件,因为我只想要那些满足该条件的行,问题是可能有多个行
  • 那有什么问题呢?打开显式游标和循环并获得所需的一切。打开任何 Oracle 书籍或 Web 并阅读隐式和显式游标之间的区别。
  • 我有点忘了在我的问题中提及它,但我还需要更新那些满足我表中要求的行,但前提是我实际上插入了一些东西(这就是我有 @987654323 @ 在我的代码中。问题是您不能在 IF 语句中使用 SELECT 子句,所以我需要在外面执行并将结果存储在某处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多