How do I copy over data from one table to another which has new columns? - sql

I have Table A and Table B.
Both used to have same content but now table A has a few extra non nullable columns. I am trying to copy over data from Table B into Table A but getting an error when I try this query,
INSERT INTO TABLE_A (SELECT * FROM TABLE_B);
This throws the error, ORA-00947: not enough values
INSERT INTO TABLE_A(Col1, Col2, Col3, Col4)
VALUES ((SELECT Col1 FROM TABLE_B), (SELECT Col3 FROM TABLE_B), 'New Column', 'New Column');
This throws the error, ORA-01427: single-row subquery returns more than one row

Try this:
INSERT INTO TABLE_A (Col1, Col2, Col3, Col4)
(SELECT Col1, Col3, 'New Column', 'New Column' FROM TABLE_B);
This should return all the rows from TABLE_B with the correct number of columns.

As you mentioned in question itself table structure of A and B are different.
This is the reason why INSERT INTO SELECT.. is failing.
Below is the query for reference:
INSERT INTO TABLE_A (Col1, Col2, Col3, Col4)
(
SELECT Col1, Col3, 'DUMMY', 'DUMMY'
FROM TABLE_B
);

Related

pl/sql insert from select

I have tow tables:
table1 with 5 columns
table2 with 4 columns
I want to copy the data from table2 to table1.
In table1 I have column with default value, let's say column2 ='default'
How i do it in PL/SQL?
You can insert and enumerate the target columns. The idea is:
insert into table1(col1, col3, col4, col5)
select col1, col2, col3, col4 from table2
The "additional" column of table1 (I assumed col2) is not part of the list of columns to insert into - so Oracle will happily use the configured default value.
You can simply use the constant value for the col2 as follows:
insert into table1(col1, col2, col3, col4, col5)
select col1, 'default', col2, col3, col4 from table2;

INSERT INTO using a query, and add a default value

I want run an INSERT INTO table SELECT... FROM...
The problem is that the table that I am inserting to has 5 columns, whereas the table I am selecting from has only 4. The 5th column needs to be set do a default value that I specify. How can I accomplish this? The query would be something like this (note: this is Oracle):
INSERT INTO five_column_table
SELECT * FROM four_column_table
--and a 5th column with a default value--;
Just add the default value to your select list.
INSERT INTO five_column_table
SELECT column_a, column_b, column_c, column_d, 'Default Value'
FROM four_column_table;
Just select the default value in your SELECT list. It's always a good idea to explicitly list out columns so I do that here even though it's not strictly necessary.
INSERT INTO five_column_table( col1, col2, col3, col4, col5 )
SELECT col1, col2, col3, col4, 'Some Default'
FROM four_column_table
If you really don't want to list out the columns
INSERT INTO five_column_table
SELECT fct.*, 'Some Default'
FROM four_column_table fct
Oracle supports a keyword DEFAULT for this purpose:
insert all
into five_column_table( col1, col2, col3, col4, col5 )
VALUES( col1, col2, col3, col4, DEFAULT)
SELECT col1, col2, col3, col4
FROM four_column_table;
But in your case I had to use multi-table insert. DEFAULT keyword can be used only in values clause.

Oracle: Insert into select... in the

What is the advantage of inserting into a select of a table over simply inserting into the table?
eg
insert into
( select COL1
, COL2
from Table1
where 1=2 <= this and above is the focus of the question.
) select COL3, COL4 from Table2 ;
It seems to do the same thing as:
insert into Table1
( COL1, COL2 )
select COL3, COL4 from Table2 ;
This is the first time I've seen this; our Sr Dev says there is some advantage but he can't remember what it is.
It may make sense in a way if one was inserting a "select *..." from a table with lots of columns, and we want to be lazy, but... we're not. We're enumerating each column in the table.
Database is Oracle 11gR2, but this query was written probably in 10g or before.
we want to be lazy
No, we use insert into table(col1, col2) select col2, col2 from ... when there is a lot of records (for example 1M) and we don't want to create a the values section for each. Let's imagine how much time it takes if you write
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1);
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 2);
...
insert into table (col1, col2)
values (select col1, col2 from (select col1, col2, rownum rn from ...) where rn = 1000000);
insert select is faster way for copying data from one table(several tables) to an another table.
In a nutshell. It's a lot easier. Especially when you have a massive query that you dont wanna rebuild,or if you have a crapton of objects, or values you are inserting.
Without WITH CHECK OPTION specified, I don't know of any purpose for this syntax. If you specify WITH CHECK OPTION, you can effectively implement an ad-hoc check constraint within your insert statement.
insert into
( select COL1
, COL2
from Table1
where 1=2 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;
The above will never insert a record, because 1 will never equal 2.
The statement below will insert a record as long as COL3 is less than 100, otherwise an exception is raised.
insert into
( select COL1
, COL2
from Table1
where COL1 < 100 WITH CHECK OPTION
) select COL3, COL4 from Table2 ;

PL/SQL Inserting into a table minus another table but inserting another column at the same time

I have a small problem, say I have a table with 5 columns, I insert into that table using MINUS from another table that has 4 columns.
I am having problem inserting a (null) or ' ' value into the 5th column when I do that statement as it says:
invalid number of columns selected (table I am minusing from does not have the 5th column)
This is my code I use for the insert into statement
INSERT INTO my_table(SELECT col1, col2, col3, col4 FROM that_table
MINUS SELECT col1, col2, col3, col4 FROM my_table);
This code works, it copies whatever I need if I don't create a 5th column, is there a way to insert into my table values from the other table alongside a 5th column in my_table?
Thank you
Assuming I'm understanding your question, you want to select all records from that_table and insert those into my_table where the first 4 columns don't exist, using null as the value for the 5th column? If so, you can use not exists:
insert into my_table (col1, col2, col3, col4, col5)
select col1, col2, col3, col4, null
from that_table tt
where not exists (
select 1
from my_table mt
where tt.col1 = mt.col1 and tt.col2 = mt.col2
and tt.col3 = mt.col3 and tt.col4 = mt.col4
)
You should also be able to use Minus, just make sure you have the same number of columns and same data types:
insert into my_table (col1, col2, col3, col4, col5)
select col1, col2, col3, col4, null
from that_table
minus
select col1, col2, col3, col4, null
from my_table
If you want to insert only the selected columns, then try this:
insert into my_table (col1, col2, col3, col4, col5) select col1, col2, col3, col4, null from that_table;
You can find more information at http://www.w3schools.com/sql/sql_insert_into_select.asp

PostgreSQL: insert from another table

I'm trying to insert data to a table from another table and the tables have only one column in common. The problem is, that the TABLE1 has columns that won't accept null values so I can't leave them empty and I can't get them from the TABLE2.
I have TABLE1:
id, col_1 (not null), col_2(not null), col_3 (not null)
and TABLE2:
id, col_a, col_b, col_c
so how could I insert id from TABLE2 to TABLE1 and fill the col_1-3 with hard coded strings like "data1", "data2", "data3"?
INSERT INTO TABLE1 (id) SELECT id FROM TABLE2 WHERE col_a = "something";
will result in:
ERROR: null value in column "col_1" violates not-null constraint
You can supply literal values in the SELECT:
INSERT INTO TABLE1 (id, col_1, col_2, col_3)
SELECT id, 'data1', 'data2', 'data3'
FROM TABLE2
WHERE col_a = 'something';
A select list can contain any value expression:
But the expressions in the select list do not have to reference any columns in the table expression of the FROM clause; they can be constant arithmetic expressions, for instance.
And a string literal is certainly a value expression.
For referential integtity :
insert into main_tbl (col1, ref1, ref2, createdby)
values ('col1_val',
(select ref1 from ref1_tbl where lookup_val = 'lookup1'),
(select ref2 from ref2_tbl where lookup_val = 'lookup2'),
'init-load'
);
Very late answer, but I think my answer is more straight forward for specific use cases where users want to simply insert (copy) data from table A into table B:
INSERT INTO table_b (col1, col2, col3, col4, col5, col6)
SELECT col1, 'str_val', int_val, col4, col5, col6
FROM table_a
You could use coalesce:
insert into destination select coalesce(field1,'somedata'),... from source;