Reputation: 817
Given the following create table SQL (which works fine):
CREATE TABLE blah (CAT, BUSINESS_NR, TIME_A, VERSION, SOME_CODE) AS
SELECT 'ABC', 123, TIMESTAMP '2009-02-19 00:00:00 UTC', 1, 'OPP' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-08-16 00:00:00 UTC', 4, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-10-16 00:00:00 UTC', 5, 'ZZZ' FROM DUAL;
I have to switch now to an insert stmt, because table blah is created already.
My approach:
INSERT INTO blah (CAT, BUSINESS_NR, TIME_A, VERSION, SOME_CODE)
select
(
SELECT 'ABC', 123, TIMESTAMP '2009-02-19 00:00:00 UTC', 1, 'OPP' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-08-16 00:00:00 UTC', 4, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-10-16 00:00:00 UTC', 5, 'ZZZ' FROM DUAL
) from dual;
failed with error:
ORA-00913
What could I try?
Upvotes: 0
Views: 4489
Reputation: 21115
You are using a subquery as a selected column, which is allowed, but the subquery must return only one row and one column.
So this is a valid syntax
select
( SELECT 'ABC' FROM DUAL )
from dual
But your subquery returns three rows and five column, which is not acceptable and leads to ORA-00913: too many values
What you may do is to use the subquery in the FROM
clause. This is valid syntax:
INSERT INTO blah (CAT, BUSINESS_NR, TIME_A, VERSION, SOME_CODE)
select *
FROM
(
SELECT 'ABC', 123, TIMESTAMP '2009-02-19 00:00:00 UTC', 1, 'OPP' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-08-16 00:00:00 UTC', 4, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-10-16 00:00:00 UTC', 5, 'ZZZ' FROM DUAL
);
In this simple case (as pointed out by others) you may get rid of the main query at all.
Upvotes: 1
Reputation: 1271151
You don't need the extra SELECT
:
INSERT INTO blah (CAT, BUSINESS_NR, TIME_A, VERSION, SOME_CODE)
SELECT 'ABC', 123, TIMESTAMP '2009-02-19 00:00:00 UTC', 1, 'OPP' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-08-16 00:00:00 UTC', 4, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-10-16 00:00:00 UTC', 5, 'ZZZ' FROM DUAL;
The problem with your query is that you have subqueries that return more than one column. That is not generally allowed in SQL.
Upvotes: 0