Oracle 12c - 插入到 Select 查询中的列不明确,ORA-00918
Oracle 12c - Ambiguous column in Insert Into Select Query, ORA-00918
我正在尝试使用单个语句执行多个插入以实现此目的我正在使用 Insert into select 语句。但是当两列在插入中具有相同的值时,我面临着。我收到的错误消息是 ORA-00918: column ambiguously defined
.
查询
INSERT INTO sample (
HOST,
TOTAL_PING,
TOTAL_UNAVAILABLE_PING
)
SELECT * FROM (
SELECT 'FR3158-73-1',
82,
82
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
)
第一个 select 语句中存在问题,其中两个值是 82 和 82,如果我将一个值更改为有效的值。即使列值相同,我也不知道如何进行这项工作。
---更新---
Table定义
CREATE TABLE sample
(
ID NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1) PRIMARY KEY,
HOST VARCHAR2(15 BYTE),
TOTAL_PING INTEGER,
TOTAL_UNAVAILABLE_PING INTEGER,
ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
);
删除 select * from
((和尾随 )
)。
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
SELECT 'FR3158-73-1', 82, 82 FROM DUAL
UNION ALL
SELECT 'FR3158-76-2', 80, 10 FROM DUAL
[编辑,评论说它仍然不起作用]
好吧,它 有效 ,至少在我的 11gXE 中是这样:
SQL> select * From v$version where rownum = 1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> CREATE TABLE sample
2 (
3 ID NUMBER,
4 HOST VARCHAR2(15 BYTE),
5 TOTAL_PING INTEGER,
6 TOTAL_UNAVAILABLE_PING INTEGER,
7 ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
8 );
Table created.
SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
2 SELECT 'FR3158-73-1', 82, 82 FROM DUAL
3 UNION ALL
4 SELECT 'FR3158-76-2', 80, 10 FROM DUAL;
2 rows created.
12c 也没有错误:
SQL> select * from v$version where rownum = 1;
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
SQL> CREATE TABLE sample
2 (
3 ID NUMBER,
4 HOST VARCHAR2(15 BYTE),
5 TOTAL_PING INTEGER,
6 TOTAL_UNAVAILABLE_PING INTEGER,
7 ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
8 );
Table created.
SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
2 SELECT 'FR3158-73-1', 82, 82 FROM DUAL
3 UNION ALL
4 SELECT 'FR3158-76-2', 80, 10 FROM DUAL;
2 rows created.
SQL>
现在,请证明它不适用于您的数据库。
在这种情况下,您不需要子查询 - 正如@Littlefoot 所示。但是如果你这样做了,在更复杂的情况下,你可以通过在子查询中为列表达式设置别名来避免错误:
INSERT INTO sample (
HOST,
TOTAL_PING,
TOTAL_UNAVAILABLE_PING
)
SELECT * FROM (
SELECT 'FR3158-73-1' as host,
82 as total_ping,
82 as total_unavailable_ping
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
)
/
2 rows inserted.
问题是子查询本身得到隐含的列别名,从查询的第一个分支中的值派生:
SELECT 'FR3158-73-1',
82,
82
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
'FR3158-73- 82 82
----------- ---------- ----------
FR3158-73-1 82 82
FR3158-76-2 80 10
第二列和第三列都被称为"82"
,这是ORA-00918抱怨的歧义,从外部select
。如果您添加消失的别名:
SELECT 'FR3158-73-1' as host,
82 as total_ping,
82 as total_unavailable_ping
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
HOST TOTAL_PING TOTAL_UNAVAILABLE_PING
----------- ---------- ----------------------
FR3158-73-1 82 82
FR3158-76-2 80 10
这样外层查询就不再迷茫了。请注意,您只需要联合的第一个分支中的别名 (usually, anyway) - 在所有分支中使用别名并没有什么坏处,它们只会被忽略,但如果您'手动创建这个。在这种情况下,实际的别名也无关紧要,它们必须是唯一的;具体来说,它们不必与您要插入的列相匹配 - 但如果它们匹配,则更容易理解。
如果按照@Littlefoot 显示的方式进行操作,则您没有中间结果集 select
,因此不需要评估派生名称(如果可以说它们存在的话) , 所以看不到歧义 - 这纯粹是位置问题。
尝试命名列:
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
SELECT 'FR3158-73-1' as host, 82 as total_ping, 82 as total_UNAVAILABLE_PING FROM DUAL
UNION ALL
SELECT 'FR3158-76-2' as host, 80 as total_ping, 10 as total_UNAVAILABLE_PING FROM DUAL
;
但更好的方法是:
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-73-1',82,82);
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-76-2',80,10);
你避免了子查询。
如果您有大量数据要插入数据库,请考虑 SQL*Loader 并从文本文件加载。
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-sql-loader-concepts.html#GUID-DD843EE2-1FAB-4E72-A115-21D97A501ECC
我正在尝试使用单个语句执行多个插入以实现此目的我正在使用 Insert into select 语句。但是当两列在插入中具有相同的值时,我面临着。我收到的错误消息是 ORA-00918: column ambiguously defined
.
查询
INSERT INTO sample (
HOST,
TOTAL_PING,
TOTAL_UNAVAILABLE_PING
)
SELECT * FROM (
SELECT 'FR3158-73-1',
82,
82
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
)
第一个 select 语句中存在问题,其中两个值是 82 和 82,如果我将一个值更改为有效的值。即使列值相同,我也不知道如何进行这项工作。
---更新---
Table定义
CREATE TABLE sample
(
ID NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1) PRIMARY KEY,
HOST VARCHAR2(15 BYTE),
TOTAL_PING INTEGER,
TOTAL_UNAVAILABLE_PING INTEGER,
ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
);
删除 select * from
((和尾随 )
)。
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
SELECT 'FR3158-73-1', 82, 82 FROM DUAL
UNION ALL
SELECT 'FR3158-76-2', 80, 10 FROM DUAL
[编辑,评论说它仍然不起作用]
好吧,它 有效 ,至少在我的 11gXE 中是这样:
SQL> select * From v$version where rownum = 1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> CREATE TABLE sample
2 (
3 ID NUMBER,
4 HOST VARCHAR2(15 BYTE),
5 TOTAL_PING INTEGER,
6 TOTAL_UNAVAILABLE_PING INTEGER,
7 ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
8 );
Table created.
SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
2 SELECT 'FR3158-73-1', 82, 82 FROM DUAL
3 UNION ALL
4 SELECT 'FR3158-76-2', 80, 10 FROM DUAL;
2 rows created.
12c 也没有错误:
SQL> select * from v$version where rownum = 1;
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
SQL> CREATE TABLE sample
2 (
3 ID NUMBER,
4 HOST VARCHAR2(15 BYTE),
5 TOTAL_PING INTEGER,
6 TOTAL_UNAVAILABLE_PING INTEGER,
7 ADDED_ON TIMESTAMP(6) DEFAULT systimestamp
8 );
Table created.
SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
2 SELECT 'FR3158-73-1', 82, 82 FROM DUAL
3 UNION ALL
4 SELECT 'FR3158-76-2', 80, 10 FROM DUAL;
2 rows created.
SQL>
现在,请证明它不适用于您的数据库。
在这种情况下,您不需要子查询 - 正如@Littlefoot 所示。但是如果你这样做了,在更复杂的情况下,你可以通过在子查询中为列表达式设置别名来避免错误:
INSERT INTO sample (
HOST,
TOTAL_PING,
TOTAL_UNAVAILABLE_PING
)
SELECT * FROM (
SELECT 'FR3158-73-1' as host,
82 as total_ping,
82 as total_unavailable_ping
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
)
/
2 rows inserted.
问题是子查询本身得到隐含的列别名,从查询的第一个分支中的值派生:
SELECT 'FR3158-73-1',
82,
82
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
'FR3158-73- 82 82
----------- ---------- ----------
FR3158-73-1 82 82
FR3158-76-2 80 10
第二列和第三列都被称为"82"
,这是ORA-00918抱怨的歧义,从外部select
。如果您添加消失的别名:
SELECT 'FR3158-73-1' as host,
82 as total_ping,
82 as total_unavailable_ping
FROM DUAL
UNION ALL
SELECT 'FR3158-76-2',
80,
10
FROM DUAL
HOST TOTAL_PING TOTAL_UNAVAILABLE_PING
----------- ---------- ----------------------
FR3158-73-1 82 82
FR3158-76-2 80 10
这样外层查询就不再迷茫了。请注意,您只需要联合的第一个分支中的别名 (usually, anyway) - 在所有分支中使用别名并没有什么坏处,它们只会被忽略,但如果您'手动创建这个。在这种情况下,实际的别名也无关紧要,它们必须是唯一的;具体来说,它们不必与您要插入的列相匹配 - 但如果它们匹配,则更容易理解。
如果按照@Littlefoot 显示的方式进行操作,则您没有中间结果集 select
,因此不需要评估派生名称(如果可以说它们存在的话) , 所以看不到歧义 - 这纯粹是位置问题。
尝试命名列:
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
SELECT 'FR3158-73-1' as host, 82 as total_ping, 82 as total_UNAVAILABLE_PING FROM DUAL
UNION ALL
SELECT 'FR3158-76-2' as host, 80 as total_ping, 10 as total_UNAVAILABLE_PING FROM DUAL
;
但更好的方法是:
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-73-1',82,82);
INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-76-2',80,10);
你避免了子查询。 如果您有大量数据要插入数据库,请考虑 SQL*Loader 并从文本文件加载。 https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-sql-loader-concepts.html#GUID-DD843EE2-1FAB-4E72-A115-21D97A501ECC