Inserting selected data from table in one schema into another table in a different schema - oracle

I have a table A in Schema1 and table B in Schema2.
The tables have different columns.
Table A:
ID1 Name Code
-------------------------------
1 Skyler A0
2 Amanda A1
3 Rachel B0
4 Harvey C0
5 Louis B1
Table B:
ID Names Enterprise Modified_Date
------------------------------------------------------
1 Amanda 1 2018.08.10
2 Skyler 1 2018.08.11
As depicted, Schema1.A.Name = Schema2.B.Names
I want to insert the values "Rachel,Harvey and Louis" from A.Name into B.Names.
For b.ID, i have a sequence in place. Enterprise column is always 1 and modified date can e sysdate.
How can i achieve this in PL/SQL?

use insert Statement with select statement
insert into tabB (names,Enterprise,Modified_Date )
select Name,1,sysdate from tabA where Name in ('Rachel','Harvey','Louis');

You can do this by using below query.
insert into tableB (names,Enterprise,Modified_Date )
select Name,1,sysdate from tableA where Name not in (select distinct(Name) from tableB);

Related

Referencing results of one query in another in Apache Nifi

We are trying to migrate data from Oracle to Elasticsearch using Apache Nifi.
We are trying to establish a one to many relationships(represented as multiple tables in Oracle) in a single elastic index.
What we are trying to achieve can be summarized as below.
select * from table1. (The primary key of table1 is key1)
For each fetched record, We want to extract data from another table using the key from table 1. Something like
select * from table2 where foreign_key = key1.
We checked the ExecuteSQLRecord processor which has select query and post query but are unable to figure out how to reference key from table1 in the query to table2
Please let us know if there are any other processors specifically designed for this use case.
There are several ways to achieve this
Creating Views in Oracle
You can create views in Oracle to build the queries that make the relationship primarykey-foreingkey. Thereby you can select directly from the view instead.
A small example
SQL> create table testpk ( c1 number , c2 number );
Table created.
SQL> alter table testpk add primary key ( c1 ) ;
Table altered.
SQL> create table testfk ( c3 number , c4 number );
Table created.
SQL> alter table testfk add constraint fk_to_testpk FOREIGN KEY (c3) references testpk(c1) ;
Table altered.
SQL> insert into testpk values ( 1 , 1);
1 row created.
SQL> insert into testfk values ( 1 , 2 );
1 row created.
SQL> insert into testpk values ( 2 , 2 );
1 row created.
SQL> insert into testfk values ( 2 , 2 );
1 row created.
SQL> commit;
Commit complete.
SQL> create or replace force view my_test_view as select a.c1 , a.c2 , b.c3 , b.c4
2 from testpk a join testfk b on ( a.c1 = b.c3 ) ;
View created.
SQL> select * from my_test_view ;
C1 C2 C3 C4
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 2
SQL>
Use queries directly
In your case, you need to run the query to make the relationship against the parent table, therefore you need a join:
select * from table2 inner join table1 where table2_foreingkey = table1_primarykey.
You want all records from table2 where the relationship parent key table 1 - child key table 2 matches, something you can do it with a normal inner join
If you ask me, I would create views to make the process more transparent in elastic search.

I want to join two table with query builder in laravel

I have Two table T1 and T2.
T2 is Making From T1.
T1 table:
ID Country Name
1 Bangaldesh
2 India
3 USA
4 UK
T2 table making from T1 ID
ID From T1 table C1 From T1 table C2
1 1(Bangladesh) 2(India)
2 2(India) 3(USA)
3 2(India) 1(Bangladesh)
4 2(India) 1(Bangladesh)
How can i Joining now Two Table for laravel query builder?
I need to show country name by ID
Thanks for Advance.
Check the documentation on joins.
DB::table('T2')->join('T1', 'T1.id', '=', 'T2.id_column')->get();
Assuming that the column in T2 that has the T1 id is called id_column.

PL/SQL: nested table with id's and create view

i've created tables, linked through the nested table inside one of them:
CREATE TABLE A (
NAME VARCHAR(150) ,
ID INTEGER PRIMARY KEY
) ;
CREATE TYPE A_LIST IS TABLE OF integer;
CREATE TABLE B (
NAME VARCHAR(150),
ID INTEGER PRIMARY KEY,
LIST A_LIST
) NESTED TABLE LIST STORE AS LIST_TABLE;
now I need to CREATE VIEW to show data from table B with nested data from A. Its something like
CREATE OR REPLACE VIEW ff OF B, A AS
SELECT N.name, N.LIST
CAST( MULTISET (
....
)AS TYPE_FILM_LIST)
FROM B N;
but i'm stuck in that dots(
If you want to join the tables B and A based on nested ID's - here an example.
Some test data
insert into b
values ('x',1, A_LIST(1,2,3));
insert into a values ('A1',1);
insert into a values ('A2',2);
insert into a values ('A3',3);
The main step is the join of the table B with the nested table from b, table(b.list) The nested ID is returned as COLUMN_VALUE ; rest is simple join
select b.id, b.name, a.name a_name, a.id a_id from b, table(b.list) ba, a
where ba.column_value = a.id;
result
ID SUBSTR(B.NAME,1,5) A_NAME A_ID
---------- ------------------ ------ ----------
1 x A1 1
1 x A2 2
1 x A3 3
create type record_for_a is object( a varchar2(150), id number);
create type l_record_for_a is table of record_for_a;
select table_b.name, table_b.id,
cast( multiset (select record_for_a(aa.name,aa.id) from a aa, table(table_b.list) bb where aa.id = bb.column_value) as l_record_for_a)
neste_col_a
from
b table_b;

Delete with Left Join in Oracle 10g

I have the following code that works fine in MS SQL Server:
delete grp
from grp
left join my_data
on grp.id1 = my_data.id1
and grp.id2 = my_data.id2
and grp.id3 = my_data.id3
and grp.id4 = my_data.id4
where my_data.id1 is NULL
Basically, I want to delete all occurrence that can be found in grp and don't have any equivalence in my_data. Sadly, it doesn't work in Oracle 10g. I tried using the old syntax for left join (+) but it doesn't work either. Like this:
delete grp
from grp,
my_data
where grp.id1 = my_data.id1 (+)
and grp.id2 = my_data.id2 (+)
and grp.id3 = my_data.id3 (+)
and grp.id4 = my_data.id4 (+)
and my_data.id1 is NULL
A IN clause would works if I didn't have multiple keys but I don't see how I could use it with my data. So, what is the alternative?
Shannon's solution is the way to go: use the operator NOT IN (or NOT EXISTS).
You can however delete or update a join in Oracle, but the synthax is not the same as MS SQL Server:
SQL> DELETE FROM (SELECT grp.*
2 FROM grp
3 LEFT JOIN my_data ON grp.id1 = my_data.id1
4 AND grp.id2 = my_data.id2
5 AND grp.id3 = my_data.id3
6 AND grp.id4 = my_data.id4
7 WHERE my_data.id1 IS NULL);
2 rows deleted
Additionally, Oracle will only let you update a join if there is no ambiguity as to which base row will be accessed by the statement. In particular, Oracle won't risk an update or a delete (the statement will fail) if there is a possibility that a row may appear twice in the join. In this case, the delete will only work if there is a UNIQUE constraint on my_data(id1, id2, id3, id4).
Tables and data:
SQL> create table grp (id1 number null, id2 number null, id3 number null, id4 number null);
Table created.
SQL> create table my_data (id1 number null, id2 number null, id3 number null, id4 number null);
Table created.
SQL> insert into grp values (1, 2, 3, 4);
1 row created.
SQL> insert into grp values (10, 20, 30, 40);
1 row created.
SQL> insert into grp values (1, 2, 30, 40);
1 row created.
SQL> insert into my_data values (1, 2, 3, 4);
1 row created.
SQL> commit;
Commit complete.
Using in. Note Do not use if the IDs in the subquery can be null. Not in of null never returns true.
SQL> delete grp where (id1, id2, id3, id4) not in (select id1, id2, id3, id4 from my_data);
2 rows deleted.
SQL> select * from grp;
ID1 ID2 ID3 ID4
---------- ---------- ---------- ----------
1 2 3 4
Using exists
SQL> rollback;
Rollback complete.
SQL> delete grp where not exists (select * from my_data where grp.id1 = my_data.id1 and grp.id2 = my_data.id2 and grp.id3 = my_data.id3 and grp.id4 = my_data.id4);
2 rows deleted.
SQL> select * from grp;
ID1 ID2 ID3 ID4
---------- ---------- ---------- ----------
1 2 3 4
SQL>
If you want to ensure there is no ambiguity in what's being deleted, you could change Vincent's solution to:
delete from grp where rowid in
(
select
grp.rowid
from
grp left outer join my_data on
grp.id1 = my_data.id1
and grp.id2 = my_data.id2
and grp.id3 = my_data.id3
and grp.id4 = my_data.id4
where
my_data.id1 is NULL
)
Either Vincent's answer https://stackoverflow.com/a/3675205 does not work at all, or it does not work in Oracle 12c. That answer should be improved by specifying the lowest or highest version of Oracle where this works. The proof:
SELECT * FROM v$version where banner like 'Oracle%';
/*
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
*/
create table a (id int);
create table b (id int);
insert into a select 1 from dual union select 2 from dual;
insert into b select 1 from dual union select 2 from dual union select 3 from dual;
select * from a right join b on b.id = a.id;
/*
1 1
2 2
null 3
*/
delete from (
select b.*
from b
inner join a on a.id = b.id
)
/*
Error at Command Line : 7 Column : 13
Error report -
SQL Error: ORA-01752: cannot delete from view without exactly one key-preserved table
01752. 00000 - "cannot delete from view without exactly one key-preserved table"
*Cause: The deleted table had
- no key-preserved tables,
- more than one key-preserved table, or
- the key-preserved table was an unmerged view.
*Action: Redefine the view or delete it from the underlying base tables.
*/
delete from b
where rowid in (
select b.rowid
from b
inner join a on a.id = b.id
)
/*
2 rows deleted.
*/
select * from a right join b on b.id = a.id
/*
null 3
*/
drop table a;
drop table b;
Bottom line is, use WHERE ROWID IN () at least in 12c.
I can't add a comment because it need 50 reps,so I add a answer here.
I tested Vincent's delete from query, that syntax can't let you delete what you want,at least it's not a common use for all the delete join cases.
At first I create a table using oracle default user scott:
create table emp1 as select * from emp where sal<2000;
I want to delete the records from emp where empno in emp1(just a simple test),so I used this delete from query:
delete from (select a.* from emp a join emp1 b on a.empno=b.empno);
No matter what the table or join order is,left join or inner join,no matter what where clause I use,the sql will delete the corresponding records in emp1.
So I think this delete from query can not let you delete from a specified table.
Loop a cursor will be a better way for these cases.

How to update a table with null values with data from other table at one time?

I have 2 tables - A and B . Table A has two columns, pkey (primary key) and col1. Table B also has two columns, pr_key (primary key but not a foreign key) and column1. Both tables have 4 rows. Table B has no values in column1, while table A has column1 values for all 4 rows. So my data looks like this
Table A
pkey col1
A 10
B 20
C 30
D 40
Table B
pr_key column1
A null
B null
C null
D null
I want to update table B to set the column1 value of each row equal to the column1 value of the equivalent row from table A in a single DML statement.
Should be something like that (depends on SQL implementation you use, but in general, the following is rather standard. In particular should work in MS-SQL and in MySQL.
INSERT INTO tblB (pr_key, column1)
SELECT pkey, col1
FROM tblA
-- WHERE some condition (if you don't want 100% of A to be copied)
The question is a bit unclear as to the nature of tblB's pr_key, if for some reason this was a default/auto-incremented key for that table, it could just then be omitted from both the column list (in parenthesis) and in the SELECT that follows. In this fashion upon insertion of each new row, a new value would be generated.
Edit: It appears the OP actually wants to update table B with values from A.
The syntax for this should then be something like
UPDATE tblB
SET Column1 = A.Col1
FROM tblA AS A
JOIN tblB AS B ON B.pr_key = A.pkey
This may perform better:
MERGE INTO tableB
USING (select pkey, col1 from tableA) a
ON (tableB.pr_key = a.pkey)
WHEN MATCHED THEN UPDATE
SET tableB.column1 = a.col1;
It sounds like you want to do a correlated update. The syntax for that in Oracle is
UPDATE tableB b
SET column1 = (SELECT a.column1
FROM tableA a
WHERE a.pkey = b.pr_key)
WHERE EXISTS( SELECT 1
FROM tableA a
WHERE a.pkey = b.pr_key )
The WHERE EXISTS clause isn't necessary if tableA and tableB each have 4 rows and have the same set of keys in each. It is much safer to include that option, though, to avoid updating column1 values of tableB to NULL if there is no matching row in tableA.

Resources