Oracle UNION无法正常工作

时间:2013-06-20 08:47:20

标签: database oracle stored-procedures

我有一个Oracle存储过程 - 从Java 1.6代码调用。有一条消息被发送到一个号码,号码可以回复。我的问题是UNION部分无法正常工作。 我想要一行返回消息并回复一行。此刻发生的是存储过程返回2行。第一行只有消息。第二行是他们的组合。我只想要第二排。

这是我的存储过程:

  create or replace
  FUNCTION "LIST_ALL_MSGS_SERVICE" (
gvi_service_code_in     in varchar2,
start_date_in           in varchar2,
end_date_in         in varchar2
)
  return types.cursorType
  is
     msg_cursor types.cursorType;
     l_msg_code message.gvi_message_code%type;
     l_start_date   date;
     l_end_date date;

  BEGIN
     IF start_date_in IS NULL THEN
        raise_application_error(-20054, 'start_date missing');
    END IF;
    IF end_date_in IS NULL THEN
        raise_application_error(-20054, 'end_date missing');
    END IF;

 /*  Set end date */

    l_end_date := to_date(end_date_in, 'yyyy-mm-dd hh24:mi:ss');

/*  Set start date  */
    l_start_date := to_date(start_date_in, 'yyyy-mm-dd hh24:mi:ss');


/*  Use cursor to select messages  */
BEGIN
   OPEN msg_cursor FOR
      SELECT
        m.message_id,
          m.gvi_message_code  sort_gvi_message_code,
              m.recipient,
              m.originator,
              m.content,
              mct.message_channel_type,
              to_char(m.message_date, 'yyyy-mm-dd hh24:mi:ss'),
              mst.description,
              null,
              null,
        m.gvi_datafeed_name
         FROM message m,
            message_channel_type mct,
              message_status_type mst,
        message_status ms
    WHERE TRIM(UPPER(m.gvi_service_code)) = gvi_service_code_in
    AND m.gvi_message_code = ms.gvi_message_code
    AND m.message_date >= l_start_date
          AND m.message_date <= l_end_date
    AND m.message_channel_type_id = mct.message_channel_type_id
          AND ms.message_status_type_id = mst.message_status_type_id
    AND ms.message_status_type_id =
    (SELECT MAX(ms2.message_status_type_id)
    FROM message_status ms2
      WHERE ms2.gvi_message_code = m.gvi_message_code)

UNION
SELECT
        m.message_id,
              m.gvi_message_code  sort_gvi_message_code,
              m.recipient,
              m.originator,
              m.content,
              mct.message_channel_type,
              to_char(m.message_date, 'yyyy-mm-dd hh24:mi:ss'),
              mst.description,
              em.gvi_external_message_code,
              em.content,
        m.gvi_datafeed_name
         FROM message m,
          external_message em,
          ext_msg_status_type emst,
              message_channel_type mct,
              message_status_type mst,
        message_status ms
    WHERE TRIM(UPPER(m.gvi_service_code)) = gvi_service_code_in
    AND m.gvi_message_code = ms.gvi_message_code
    AND m.gvi_message_code = em.gvi_message_code
    AND TRIM(UPPER(emst.ext_msg_status_type)) = 'REPLY'
    AND em.ext_msg_status_type_id = emst.ext_msg_status_type_id
    AND m.message_date >= l_start_date
          AND m.message_date <= l_end_date
    AND m.message_channel_type_id = mct.message_channel_type_id
          AND ms.message_status_type_id = mst.message_status_type_id
      AND ms.message_status_type_id =
    (SELECT MAX(ms2.message_status_type_id)
    FROM message_status ms2
      WHERE ms2.gvi_message_code = m.gvi_message_code)
  ORDER BY sort_gvi_message_code;

END;

RETURN msg_cursor;
  commit;
  END list_all_msgs_service;

1 个答案:

答案 0 :(得分:2)

联盟正在运作,如果有回复,它会在selects中找到不同的值。它只是没有做你想要的。你可以在联合的第一部分添加一个and not exists ()子句,这样如果后半部分就不会返回任何内容,但它会更容易并且重复使用外连接的次数要少得多 - 所以您只有一个select而没有union

   SELECT m.message_id,
          m.gvi_message_code  sort_gvi_message_code,
          m.recipient,
          m.originator,
          m.content,
          mct.message_channel_type,
          to_char(m.message_date, 'yyyy-mm-dd hh24:mi:ss'),
          mst.description,
          em.gvi_external_message_code,
          em.content,
          m.gvi_datafeed_name
     FROM message m
     JOIN message_status ms
       ON m.gvi_message_code = ms.gvi_message_code
     JOIN message_status_type mst
       ON ms.message_status_type_id = mst.message_status_type_id
     JOIN message_channel_type mct
       ON m.message_channel_type_id = mct.message_channel_type_id
LEFT JOIN external_message em
       ON m.gvi_message_code = em.gvi_message_code
LEFT JOIN ext_msg_status_type emst
       ON em.ext_msg_status_type_id = emst.ext_msg_status_type_id
      AND TRIM(UPPER(emst.ext_msg_status_type)) = 'REPLY'
    WHERE TRIM(UPPER(m.gvi_service_code)) = gvi_service_code_in
      AND m.message_date >= l_start_date
      AND m.message_date <= l_end_date
      AND ms.message_status_type_id =
          (SELECT MAX(ms2.message_status_type_id)
             FROM message_status ms2
            WHERE ms2.gvi_message_code = m.gvi_message_code)
 ORDER BY sort_gvi_message_code;
显然未经测试。左外连接表示如果没有回复,则em.gvi_external_message_codeem.content值将为null,这是您希望从现有联合的第一部分获得的值。我想。