ORA-00907 Проблема с отсутствием правой круглой скобки - выберите с порядком с помощью внутреннего запроса на вставку

Я пытаюсь вставить в таблицу, и он использует один оператор выбора для одного столбца. Ниже приведена иллюстрация моего запроса.

INSERT INTO MY_TBL (MY_COL1, MY_COL2)
VALUES (
(SELECT DATA FROM FIR_TABL WHERE ID = 1 AND ROWNUM = 1 ORDER BY CREATED_ON DESC),
1
);

Выдает ORA-00907 Missing right Parenthesis. Если я уберу из этого ORDER BY, он будет работать, как и ожидалось. Но мне нужно заказать его. Как я могу это исправить?


person Vaandu    schedule 07.02.2012    source источник
comment
Я бы поставил под сомнение вашу модель данных, если вы полагаетесь на порядок данных, вставленных в таблицу СУБД. Порядок вставки не должен иметь значения, вы выполняете упорядочение при запросе данных.   -  person Ollie    schedule 07.02.2012
comment
Как вы думаете, что ORDER BY сделает для вас в этом контексте?   -  person Don Roby    schedule 07.02.2012
comment
Я привел пример, для этого выбора может быть несколько строк. Кроме того, в MY_TBL есть много столбцов. Пожалуйста, проверьте мое обновление.   -  person Vaandu    schedule 07.02.2012
comment
@Vanathi Вы добавили rownum = 1. Это вернет только одну строку. Если вы хотите вставить несколько строк одновременно, просто удалите это условие rownnum (а также id, если оно ограничивает строки), так как insert into ... select поддерживает вставку нескольких строк.   -  person Jose Rui Santos    schedule 07.02.2012
comment
Мне нужно добавить только одну строку. Я получаю последние данные, используя порядок и вставляя их.   -  person Vaandu    schedule 07.02.2012


Ответы (3)


Оба текущих ответа игнорируют тот факт, что использование order by и rownum в одном запросе по своей сути опасно. Нет абсолютно никакой гарантии, что вы получите нужные данные. Если вам нужна первая строка из упорядоченного запроса, вы должны использовать подзапрос:

insert into my_tbl ( col1, col2 )
select data, 'more data'
  from ( select data
           from fir_tabl
          where id = 1
          order by created_on desc )
 where rownum = 1
       ;

Вы также можете использовать такую ​​функцию, как rank, чтобы упорядочить данные в нужном вам методе, хотя если у вас есть две created_on даты, которые были идентичны, вы получите 2 значения с rnk = 1.

insert into my_tbl ( col1, col2 )
select data, 'more data'
  from ( select data
              , rank() over ( order by created_on desc ) as rnk
           from fir_tabl
          where id = 1)
 where rnk = 1
       ;
person Ben    schedule 07.02.2012
comment
Кажется, это исправляет это для Oracle. Преобразуйте его, чтобы использовать дополнительный подзапрос, и сообщение об отсутствующей правой скобке (даже если скобка не отсутствует) исчезнет. Спасибо! - person rogerdpack; 07.11.2013
comment
есть ли упоминание о том, что использование order by и rownum в одном и том же запросе опасно по своей сути? - person jeromerg; 13.11.2016
comment
Я уверен, что Том Кейт что-то написал @jeromerg, но вы должны увидеть это из первых принципов. Таблица кучи хранится и, следовательно, извлекается несортированной. Предложение ORDER BY всегда выполняется последней операцией. Поэтому предикат ROWNUM будет использоваться перед упорядочением неупорядоченного множества. Сначала вам нужно заказать, и из-за порядка работы оператора SQL заказ должен происходить во внутреннем выборе (до 12c с (и только с) синтаксисом FETCH N ROWS) - person Ben; 13.11.2016

Вы не используете SELECT при использовании ключевого слова VALUES. Используйте это вместо этого:

INSERT INTO MY_TBL (MY_COL)
SELECT DATA FROM FIR_TABL WHERE ID = 1 ORDER BY CREATED_ON DESC
;

Ваш отредактированный запрос будет выглядеть так:

INSERT INTO MY_TBL (MY_COL1, MY_COL2)
SELECT DATA, 1 FROM FIR_TABL WHERE ID = 1 AND ROWNUM = 1 ORDER BY CREATED_ON DESC
;
person John Doyle    schedule 07.02.2012

Я согласен с тем, что упорядочение должно выполняться при извлечении данных, а не при их вставке.

Однако в качестве обходного пути вы можете изолировать предложение ORDER BY от INSERT, инкапсулируя весь ваш SELECT в другой SELECT.

Это позволит избежать ошибки:

INSERT INTO MY_TABLE (
SELECT * FROM (
    SELECT columns
    FROM table
    ORDER BY clause
    )
)
person Marco Predicatori    schedule 04.09.2014