ORA-00907 Missing right Parenthesis issue - select

2019-01-19 12:05发布

问题:

I am trying to do insert to a table and it uses one select statement for one column. Below is the illustration of my query.

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 
);

It throws ORA-00907 Missing right Parenthesis. If I remove ORDER BY from this, it works as expected. But I need order it. Please clarify.

Thanks in advance.

回答1:

Both the current answers ignore the fact that using order by and rownum in the same query is inherently dangerous. There is absolutely no guarantee that you will get the data you want. If you want the first row from an ordered query you must use a sub-query:

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
       ;

You can also use a function like rank to order the data in the method you want, though if you had two created_on dates that were identical you would end up with 2 values with 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
       ;


回答2:

You don't use a SELECT when using the VALUES keyword. Use this instead:

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

Your edited query would look like:

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
;


回答3:

I agree that ordering should be performed when extracting data, not when inserting it.

However, as a workaround, you could isolate the ORDER BY clause from the INSERT incapsulating your whole SELECT into another SELECT.

This will avoid the error:

INSERT INTO MY_TABLE (
SELECT * FROM (
    SELECT columns
    FROM table
    ORDER BY clause
    )
)