Oracle子查询:此SELECT语句中应包含INTO子句

nvbavucw  于 2023-04-05  发布在  Oracle
关注(0)|答案(2)|浏览(198)

下面是我的函数在一个包中的简化版本

function log_booking_mapping(
         pi_booking_id    in         VARCHAR2
        ,pi_event_id      in         VARCHAR2
        ...
        ,po_return        out        my_return_typ
    )
    return integer as
        ...
        v_event_id varchar2(200) := null;
    begin

        IF pi_event_id IS NULL OR TRIM(BOTH FROM pi_event_id) = '' THEN
            begin
                select EVENT_ID into v_event_id 
                    from (
                        select EVENT_ID, row_number() over (order by UPDATE_DATE desc) as seqnum
                            from BOOKING_MAPPING_LOG
                            WHERE BOOKING_ID = pi_booking_id
                    )
                    WHERE seqnum  = 1;
                IF v_event_id IS NULL THEN
                    return c_failure;
                END IF;
            exception
                when NO_DATA_FOUND then
                    return c_failure;
            end;
        ELSE
            v_event_id := pi_event_id;
        END IF;
        insert into BOOKING_MAPPING_LOG (
            ...
        ) values (
            ...
        );

        po_return := ...;
        return c_success;

    exception
        WHEN DUP_VAL_ON_INDEX THEN
            UPDATE BOOKING_MAPPING_LOG ...
                WHERE BOOKING_ID = pi_booking_id AND EVENT_ID = v_event_id;
        when OTHERS then
            ...
        return c_failure;
    end log_booking_mapping;

我在 * 子查询SELECT* 中收到关于seqnum的警告:

INTO clause is expected in this SELECT statement

作为一个回顾,这里是我得到警告的查询(及其子查询):

select EVENT_ID into v_event_id 
from (
    select EVENT_ID, row_number() over (order by UPDATE_DATE desc) as seqnum
    from BOOKING_MAPPING_LOG
    WHERE BOOKING_ID = pi_booking_id
)
WHERE seqnum  = 1;

我不知道这是为什么,因为我试图在子查询中创建两列,并将它们传递给外部查询以进一步选择变量。我不想将子查询的结果放在外部查询的变量中,那么为什么在这种情况下要使用INTO作为子查询呢?

lpwwtiir

lpwwtiir1#

这是一段你可以责怪的代码:

SQL> declare
  2    v_event_id varchar2(10);
  3  begin
  4    select 'x' into v_event_id
  5    from (select 'x' event_id,
  6                 row_number() over (order by null) seqnum
  7          from dual
  8         )
  9    where seqnum = 1;
 10  end;
 11  /

PL/SQL procedure successfully completed.

SQL>

对我来说,它工作正常,没有错误。
但你说你是
在子查询SELECT中得到一个关于seqnum的警告
此SELECT语句中需要INTO子句
是什么引起了这个警告?是Oracle本身(所以你得到了ORA-xxxxx error),还是它是一个(GUI?)工具(如果是,是哪一个)?
另外,这是否意味着您可以成功地运行代码,或者“警告”是否阻止您这样做?

f8rj6qna

f8rj6qna2#

从您给出的代码来看,它不会引发有关INTO clause is expected in this SELECT statement的错误。
你的代码有问题:

  • 您在给我们看的代码中没有定义C_SuCCESSC_FAILURE变量。
  • TRIM(BOTH FROM pi_event_id) = ''永远不会为真,因为在Oracle中,''NULL相同,您需要使用TRIM(BOTH FROM pi_event_id) IS NULL
  • 如果引发DUP_VAL_ON_INDEX,则不存在RETURN语句,并且将引发运行时异常。

此代码成功编译:

CREATE OR REPLACE function log_booking_mapping(
   pi_booking_id    in         VARCHAR2
  ,pi_event_id      in         VARCHAR2
  -- ...
  ,po_return        out        my_return_typ
)
return integer
as
  -- ...
  v_event_id varchar2(200) := null;
  c_failure  CONSTANT INTEGER := 0;
  c_success  CONSTANT INTEGER := 1;
begin
  IF TRIM(BOTH FROM pi_event_id) IS NULL THEN
    begin
      select EVENT_ID
      into   v_event_id 
      from (
        select EVENT_ID, row_number() over (order by UPDATE_DATE desc) as seqnum
        from BOOKING_MAPPING_LOG
        WHERE BOOKING_ID = pi_booking_id
      )
      WHERE seqnum  = 1;
      
      IF v_event_id IS NULL THEN
        return c_failure;
      END IF;
    exception
      when NO_DATA_FOUND then
        return c_failure;
    end;
  ELSE
    v_event_id := pi_event_id;
  END IF;

  insert into BOOKING_MAPPING_LOG (
    event_id,
    update_date,
    booking_id
  ) values (
    pi_event_id,
    SYSDATE,
    pi_booking_id
  );

  po_return := MY_RETURN_TYP('x', 'y');
  return c_success;
exception
  WHEN DUP_VAL_ON_INDEX THEN
    UPDATE BOOKING_MAPPING_LOG
    SET update_date = SYSDATE
    WHERE BOOKING_ID = pi_booking_id AND EVENT_ID = v_event_id;

    RETURN c_success;
  when OTHERS then
    -- ...
    return c_failure;
end log_booking_mapping;
/

fiddle

相关问题