1
votes

While this works as expected:

SQL> DROP TABLE TEST1;

Table dropped.

SQL> CREATE TABLE TEST1 (COL1 INTEGER, COL2 INTEGER);

Table created.

SQL> INSERT WHEN 1=1
  2  THEN INTO TEST1 (COL1, COL2)
  3  SELECT 1, 0 FROM DUAL;

1 row created.

SQL>

I receive a strange "ORA-00918: column ambiguously defined" error attempting this with more than two columns:

SQL> DROP TABLE TEST1;

Table dropped.

SQL> CREATE TABLE TEST1(COL1 INTEGER, COL2 INTEGER, COL3 INTEGER);

Table created.

SQL> INSERT WHEN 1=1
  2  THEN INTO TEST1 (COL1, COL2, COL3)
  3  SELECT 1, 0, 0 FROM DUAL;
THEN INTO TEST1 (COL1, COL2, COL3)
          *
ERROR at line 2:
ORA-00918: column ambiguously defined

SQL>

Why am I receiving ORA-00918 errors here? Is there a limit on how many columns I can SELECT in an INSERT WHEN ... THEN INTO ... SELECT pattern?

Note: I'm using Oracle 11.2.0.1.0, and the actual query I'm attempting to execute in production is more complex and references other tables (and using "VALUES" would not suffice). This is just the simplified case...

3

3 Answers

2
votes

Use aliases :

SQL> CREATE TABLE TEST1(COL1 INTEGER, COL2 INTEGER, COL3 INTEGER);

Table created.

SQL> INSERT WHEN 1=1
  2    THEN INTO TEST1 (COL1, COL2, COL3)
  3    SELECT 1 "1", 0 "2", 0 "3" FROM DUAL;

1 row created.

The reason you get this ambiguous column error is because when you don't provide an alias, Oracle will use a set of rules to name each column. In this case the second and third columns have the same name ("0") and thus can not be referenced unambiguously by the outer query:

SQL> SELECT 1, 0, 0 FROM DUAL;

         1          0          0
---------- ---------- ----------
         1          0          0

Oracle doesn't look at the data values when performing semantic analysis.

2
votes

I don't have oracle with me, but it appears that it's the inline query (SELECT FROM DUAL) that's the issue. I recommend aliasing all the fields in that inline query and trying again.

INSERT WHEN 1=1
THEN INTO TEST1 (COL1, COL2, COL3)
SELECT 1 AS c1, 0 AS c2, 0 AS c3 FROM DUAL;
1
votes

What happens you use use this?

INSERT WHEN 1=1
THEN INTO TEST1 (COL1, COL2, COL3)
SELECT 1 as col1, 0 as col2, 0 as col3 FROM DUAL;