Oracle Script -Materialized View & synonym - sql

I've got a question about script in Oracle!
I have a materialized view on a prebuilt table, in my BBDD, (this MV is of the user DAT_OWN, other 2 user (APP & BO) have synonym on this MV)
I have to change the MV and add a column. I know that I need to drop this MV and create a another one, but what's append with the synonym?
I have a previous script like:
DROP SYNONYM APP.STAT_VOZ;
CREATE SYNONYM APP.STAT_VOZ FOR DAT_OWN.STAT_VOZ;
DROP SYNONYM BO.STAT_VOZ;
CREATE SYNONYM BO.STAT_VOZ FOR DAT_OWN.STAT_VOZ;
DROP MATERIALIZED VIEW DAT_OWN.STAT_VOZ;
CREATE MATERIALIZED VIEW DAT_OWN.STAT_VOZ
ON PREBUILT TABLE WITH REDUCED PRECISION
REFRESH COMPLETE
START WITH TO_DATE('21-ene-2013 19:20:00','dd-mon-yyyy hh24:mi:ss')
NEXT (trunc(SYSDATE,'HH')+19/72)
WITH PRIMARY KEY
AS
SELECT TO_CHAR (SUM (COUNT)) AS sum_count,
start_date AS date_hour,
input_type AS input_type
FROM DAT_OWN.another_table
WHERE start_date > TO_CHAR (SYSDATE - 60, 'yyyymmdd')
GROUP BY start_date
Why would somebody do a drop synonym APP and create synonym APP drop synonym BO and create synonym BO BEFORE dropping of the materialized View? In my opinion, I have to do
drop synonym1
drop synonym2
drop Mview
create Mview
create Synonym1
Create Synonym2
I'm sure that the programmer before me did a good job, but I can't understand why they did it that way! Can somebody explain me this, please?
Regards

Your original script was probably just written by an "old school" developer. Most people are accustomed to dropping objects immediately before recreating them. As you've noticed, the sequence is not important.
Most people these days use CREATE OR REPLACE syntax instead of first dropping the object. Here is a good explanation of that concept.

There is probably no need to touch either synonym in the script.
A synonym is just a pointer. There is no requirement that the object pointed to by the synonym exists at all. If you simply drop and re-create the materialized view, the synonyms will automatically point at the newly created materialized view. Of course, after the materialized view is dropped and before it is recreated, if a session tries to use the synonym to query the materialized view, that session will get an error that the object doesn't exist. But, presumably, you're waiting to drop and recreate the materialized view until no one will be using it so that generally isn't a major concern.

Related

Materializing an existing view in Postgres

I have an existing view I need materialized. Ideally, I would drop the view and create a materialized one, but dropping the view would require a cascade drop and that would create a lot more work.
Is there an expression to change the view to a materialized one?

Do Oracle synonyms need to be recreated when the object changes?

I have 2 tables:
table1 with synonyms schema: userA.table1, userB.table1
table2
I have used:
ALTER TABLE table1 RENAME TO table1_old;
ALTER TABLE table2 RENAME TO table1;
It is necessary to recreate synonyms with drop, create, replace SQL syntax or is safe to use as is synonyms and don't recreate it?
No, you don't need to recreate synonyms if the underlying object changes.
They will be temporarily marked as "invalid" until Oracle re-validates them, which will eventually be done automatically - although it's often a good idea to revalidate them manually (in order to check they are still ok).
ALTER SYNONYM usera.table1 COMPILE;
ALTER SYNONYM userb.table1 COMPILE;

update table error as data manipulation operation not legal on this view

I wrote simple update query as below
update table_name set name = 'new name
that gave to me error
SQL Error: ORA-01732: data manipulation operation not legal on this view 01732. 00000 - "data manipulation operation not legal on this view"
after that i check
select * FROM USER_OBJECTS WHERE OBJECT_NAME='table_name'
that list TABLE and MATERIALIZED VIEW same as the 'table_name'
I know materialized view is not possible to update but table should update
please let me know how can i update table using simple above update query
You cannot update the materialized view or the physical table it uses for storage. You can only update the table(s) the view is built against. Presumably you know those; if not you can get the view definition from the data dictionary, or with dbms_metadata.get_ddl.
Updating the view or it's backing table doesn't make sense anyway. Even if you were allowed to, any changes you made would be lost the next time the view is refreshed.
If you don't want the materialized view to ever be refreshed again then you could drop that with the preserve table option, which would leave behind just the physical table - and you then update that. But if you change your mind you'd have to recreate the view and specify the existing table.

how to load modified and unmodified data into materialized view in oracle

I have a table T_SG_LTA_TRANSACTION_TYPE in source database.
I want to move it into a target database.
I have created a materialized view log in source database.
CREATE MATERIALIZED VIEW LOG ON T_SG_LTA_TRANSACTION_TYPE WITH PRIMARY KEY, ROWID;
Then I created materialized view in target database with following query.
CREATE MATERIALIZED VIEW T_SG_LTA_TRANSACTION_TYPE
ON PREBUILT TABLE
REFRESH FAST ON DEMAND
FOR UPDATE
AS
SELECT TRANSACTION_ID,
TRANSACTION_DESCRIPTION,
FILE_TYPE_ID
FROM T_SG_LTA_TRANSACTION_TYPE#EBAODWH_SRC_1_GS_AIG;
But when I refresh materialized view , I am unable to load the data which is already present in T_SG_LTA_TRANSACTION_TYPE(SOURCE DB).
BEGIN
DBMS_MVIEW.refresh('T_SG_LTA_TRANSACTION_TYPE');
END;
The data which is updated in source table after creation of materialized view, is only loading to materialized view . But I want to get whole data from source table(modified and unmodified) into materialized view. And I need this unmodified data only once when mview is created. Please suggest the solution. Thanks in advance.
You seem to be using the ON PREBUILT TABLE clause incorrectly:
The ON PREBUILT TABLE clause lets you register an existing table as a preinitialized materialized view.
And
Caution:
This clause assumes that the table object reflects the materialization of a subquery. Oracle strongly recommends that you ensure that this assumption is true in order to ensure that the materialized view correctly reflects the data in its master tables.
You're essentially saying that T_SG_LTA_TRANSACTION_TYPE already exists on the target database - not the source - and contains the current state of the source table; which, since you're missing data, is not true.
When you refresh Oracle is only looking for changes since the view was created, as it's supposed to; it relies on the MV log to identify what has changed.
Drop the MV in the target database, without the preserve table clause, and then recreate it without the on prebuilt table clause.
Make sure you're dropping the right thing in the right database/schema, of course...
It isn't clear if the (empty) table already existed in your target DB before you started; or you've run this a couple of times and dropped the MV with preserve table - and either the source was empty last time, or you truncated the target table afterwards - or perhaps you tried to export/import the initial state but just got the metadata and not the data. If the table you said existed on the target DB did not, in fact, exist then Oracle would have thrown an ORA-12059 exception when you tried to create the MV. I suspect you'd created an empty table and then tried to convert it to an MV, but if you do that it won't get any data from the source DB, as you've seen.

My Oracle view uses a table that doesn't exist, but I can still query it

I have an Oracle view that uses a table that I cannot find anywhere. However, I can still query the view, which I would have thought would be impossible.
Are the view contents cached somewhere, from when the table still existed, or am I simply not looking hard enough for the table?
Just to be clear: I've looked in ALL_TABLES and ALL_OBJECTS and the table (or whatever it is) doesn't appear in either.
This is very possible.. Granting select on a view does not grant select on the underlying tables. This allows me to create a view that exposes a couple columns from a table that I don't want you to see all of. You have to have access on the table for it to show up in the ALL_TABLES view. If it really is a table, you should be able to find it in the DBA_TABLES view (assuming you have access to the DBA_TABLES view), which has everything and not just tables that your user has privileges on.
In fact, the ALL_TABLES view is a perfect example of this situtation. I bet you can't find the tables used in that view either, as you probably don't have permissions on the SYS tables that it is based on (e.g. SYS.user$, SYS.obj$, etc).
Also check to see if the "missing" table is actually a synonym:
SELECT table_owner, table_name
FROM all_synonyms
WHERE table_name = 'MISSING_TABLE';
If it is not a synonym, try looking in the all_tables dictionary view for your table:
SELECT owner, table_name
FROM all_tables
WHERE table_name = 'MISSING_TABLE';
Is it maybe a materialized view? That's a copy of the data so it would continue to exist even if a base table was dropped.
Check the schema for the table references in the view that you can't find - it's likely to be not the current schema, but the current schema has SELECT privilege (at a minimum) on the particular table.
Once you know the schema, it should help determine if the table is actually a view in the current schema. Or it could be a synonym, which exists in the current schema -- vs a public synonym is the same across all schemas, so you'd have to check the synonyms to see where it points to.
I would make sure you havent set it up by saying
Create Table "TableName"
("ColumnName" Number(10,0))....
If you then try and reference these with the following script:
Select ColumnName from TableName....
it wont work. This is because Oracle takes unquoted names like TableName and turns them into TABLENAME which doesnt exist as when you declared it with "TableName" you were in effect saying "only respond to queries with this exact capitalisation that are also in quotes"
So the following would have worked:
Select "ColumnName" from "TableName"....
But basically you should never use the case sensitive definitions because they require every query to be quoted.
Instead do
Create Table TableName
(ColumnName Number(10,0))....
and it will respond to whatever capitalisation you feel like using when querying