query to get all tables in a materialized view - oracle

Good afternoon friends,
a query is there any way (select * from) to visualize which tables form a materialized view?
ex:
CREATE MATERIALIZED VIEW table_vm
REFRESH COMPLETE ON COMMIT
as
SELECT * FROM table1;
UNION ALL
SELECT * FROM table2;
I would like to output something like this:
view name | table name
table_m | Table 1
table_m | table 2
tabla_m | table 3
....
....
Thank you so much,
I would appreciate any information.

You can use the view DBA_DEPENDENCIES to view any dependencies for an object compiled into the database. Querying that view with the name of your materialized view should list all of the tables as well as any other dependencies the materialized view relies on. REFERENCED_OWNER and REFERENCED_NAME will hold the values of the tables being used by the materialized view.
SELECT *
FROM dba_dependencies
WHERE owner = 'OWNER_OF_MV' AND name = 'TABLE_MV';

One option would be
SQL> create table t1 ( c1 number, c2 varchar2(1) ) ;
Table created.
SQL> create table t2 ( c1 number , c3 varchar2(1) ) ;
Table created.
SQL> create table t3 ( c1 number , c3 varchar2(1) ) ;
Table created.
SQL> create materialized view mv1 refresh complete on demand as
2 select a.c1 , b.c3 as c2, c.c3
3 from t1 a inner join t2 b on a.c1 = b.c1
4 left join t3 c on a.c1 = c.c1 ;
Materialized view created.
SQL> select name as mv, listagg(referenced_name || ' - ' || referenced_type , '|' )
within group ( order by referenced_name ) as list_dep
from dba_dependencies where name='MV1' and name != referenced_name
group by name
MV LIST_DEP
------------------------------ --------------------------------------------------
MV1 T1 - TABLE|T2 - TABLE|T3 - TABLE

Related

In Oracle SQL Developer, I am unable to create table due to duplicate columns into same table

I am unable to create table due to duplicate columns into same table.
There is duplicate column name called load_Tstamp. How to rename the column or any other alternative?
Create table New_County_code as (
Select a.*,b.LOAD_TSTMP as Load_time
from (
Select CONCAT( b.STATE_FIPS_CODE,a.ZIP_CNTY_CDE) AS "Final_County_Code",
a.*,
b.*
from mdmstggeo.T_USPS_DETAIL_RECORD#ODSDEV a
left join (
select *
from DSSCORP.T_STATE#ds31
where STATE_FIPS_CODE is not null) b
on ST_CPTL_BLDG_ZIP_CDE = DTL_ZIP_CDE
WHERE ds_batch_gid=1661
order by STATE_FIPS_CODE
)
)
Every column name in your target table must be unique, so use column aliases wherever needed to ensure that
SQL> create table t1 as
2 select a.*, b.*
3 from scott.dept a,
4 scott.dept b;
select a.*, b.*
*
ERROR at line 2:
ORA-00957: duplicate column name
SQL>
SQL> create table t1 as
2 select a.*, b.deptno c1, b.dname c2, b.loc c3
3 from scott.dept a,
4 scott.dept b;
Table created.
SQL>
SQL> desc t1
Name Null? Type
----------------------------------------------------------------------- -------- --------------
DEPTNO NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
C1 NUMBER(2)
C2 VARCHAR2(14)
C3 VARCHAR2(13)

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.

Materialized view logs questions

I have a materialized view based on two or more other materialized views. I want to schedule fast refresh for the materialized view but the issue is that it does not have any logs, so I must create the logs first. I am new to materialized views so I am not sure how to go about creating the logs for the two underlying materialized views. Do I create a log for each underlying table that is utilized by those views?
Assuming you want everything to be fast refreshable, you need MV logs on the:
base tables
MVs underlying the "final" MV
You create MV logs on an MV in the same way as regular tables:
create table t1 (
c1 int primary key, c2 int
);
create table t2 (
c1 int, c2 int, primary key ( c1, c2 )
);
create materialized view log on t1
with rowid, primary key ( c2 )
including new values;
create materialized view log on t2
with rowid, primary key
including new values;
create materialized view mv1
refresh fast on commit as
select * from t1;
create materialized view mv2
refresh fast on commit as
select * from t2;
create materialized view log on mv1
with rowid ( c1, c2 )
including new values;
create materialized view log on mv2
with rowid ( c1, c2 )
including new values;
create materialized view mv3
refresh fast on commit as
select mv1.c1, count (*)
from mv1
join mv2
on mv1.c1 = mv2.c1
group by mv1.c1;
insert into t1 values ( 1, 1 );
insert into t1 values ( 2, 2 );
insert into t2 values ( 1, 1 );
insert into t2 values ( 1, 2 );
insert into t2 values ( 2, 2 );
commit;
select * from mv3;
C1 COUNT(*)
---------- ----------
1 2
2 1

oracle: primary key column in a materialized view

The task is to create a materialized view with the primary key on some unique column, so the materialized view could be replicated to another DB. The problem is that there are no unique columns because I had to join a very large number of tables, so I can not use the IDs from the joined tables, as they are not unique anymore in my materialized view.
First of all I have to create a view, because there are subqueries in the select:
CREATE VIEW V_CONTRACTS
AS
SELECT
ID.NEXTVAL,
C.*
FROM (SELECT <lots of columns>
FROM CONTRACT
<lots of joins>
WHERE <some filters>) C
;
But the error is thrown:
ORA-02287: sequence number not allowed here
Then I will create the materialized view as:
CREATE MATERIALIZED VIEW CONTRACTS
AS
SELECT * FROM V_CONTRACTS;
You could use the ROW_NUMBER analytic function to give you a number column.
CREATE VIEW V_TEST
AS
SELECT
ROW_NUMBER() OVER ( ORDER BY col1 , col2 ) as idx,
C.*
FROM ( SELECT 'A' as col1, 'B' as col2 FROM DUAL
UNION
SELECT 'C' as col1, 'D' as col2 FROM DUAL
UNION
SELECT 'E' as col1, 'F' as col2 FROM DUAL
) C ;
CREATE MATERIALIZED VIEW mv_test
AS
SELECT * FROM V_TEST ;
SELECT * FROM mv_test ;

How to select column value from a nested table

I created 1 object.
create type tab_billing as object(invoice_no number,
customername varchar2(100)
);
Now i created a table with the object as a column.
CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Is there anyway I can ONLY select invoice_no from the tab1.
select col2 from tab1;
Is givng me both invoice_no and customername. Substr function is not working here.
You can query the column value's object field directly, but to avoid confusing the object name resolution steps you have to supply and use a table alias:
select t1.col2.invoice_no from tab1 t1;
This is mentioned in the documentation:
To avoid inner capture and similar problems resolving references, Oracle Database requires you to use a table alias to qualify any dot-notational reference to subprograms or attributes of objects.
Qualifying the column with the the table name isn't enough; using select tab1.col2.invoice_no from tab1 gets ORA-00904. You have to use a table alias - although, slightly bizarrely, it still works if the alias is the same as the table name, so select tab1.col2.invoice_no from tab1 tab1 (i.e. aliasing tab1 as tab1, which is normally redundant) works too.
Quick demo:
create type tab_billing as object(invoice_no number,
customername varchar2(100)
);
/
Type TAB_BILLING compiled
CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Table TAB1 created.
insert into tab1 values (1, tab_billing(42, 'Test'));
1 row inserted.
select t1.col2.invoice_no from tab1 t1;
COL2.INVOICE_NO
---------------------------------------
42
You can use TREAT:
SQL> create type tab_billing as object(invoice_no number,
2 customername varchar2(100)
3 );
4 /
Type created.
SQL> CREATE TABLE tab1 (col1 number,COL2 tab_billing);
Table created.
SQL> insert into tab1 values (1, tab_billing(10, 'ten')) ;
1 row created.
SQL> select col1,
2 TREAT(col2 AS tab_billing).invoice_no as invoice_no,
3 TREAT(col2 AS tab_billing).customername as customername
4 from tab1;
COL1 INVOICE_NO CUSTOMERNAME
------ ---------- --------------------
1 10 ten

Resources