Cannot create Materialized View using PL/SQL procedure
Hello,
I have a question related to Materialized View creation.
I have a stored procedure that creates materialized view. When trying to run this procedure I get insufficient privileges error: ORA-01031.
When I run content of this procedure as anonymous PL/SQL block them materialized view is created without any complications.
Can you please advice me on that topic?
Is it even possible to create materialized view in stored procedure as I haven't found an info on it.
Thanks
Petr
Hi chudapet,
Whenever you do operation in procedure you need to have direct grants and not via a role.
Most probably the grant to create materialized view is available via a role to your user.
Assign direct grant to the user:
grant create materialized view to scott;
{code}
Similar Messages
-
HELP WITH CREATING A VIEW USING PL/SQL
Hello,
I have two tables, one is simply an audit version of the other and anytime data is updated, modified, or deleted the data is copied to the audit table (via a trigger) and the audit table records who made the changes and when.
Here is the description of one of the archive tables:
AUD_OBLIGATION_ID NOT NULL NUMBER(10)
OBLIGATION_ID NUMBER(10)
COMMUNICATION_ID NUMBER(10)
COMMUNICATION_ID_OLD NUMBER(10)
OBL_DESC VARCHAR2(4000)
OBL_DESC_OLD VARCHAR2(4000)
OBL_TYPE VARCHAR2(20)
OBL_TYPE_OLD VARCHAR2(20)
ORIGINAL_TARGET_DATE DATE
ORIGINAL_TARGET_DATE_OLD DATE
TARGET_DATE DATE
TARGET_DATE_OLD DATE
ACTUAL_DATE DATE
ACTUAL_DATE_OLD DATE
STATUS VARCHAR2(20)
STATUS_OLD VARCHAR2(20)
DOCLINK VARCHAR2(200)
DOCLINK_OLD VARCHAR2(200)
SERIAL_NUMBER NUMBER(10)
SERIAL_NUMBER_OLD NUMBER(10)
REMARKS VARCHAR2(200)
REMARKS_OLD VARCHAR2(200)
CREATED_BY VARCHAR2(10)
CREATED_BY_OLD VARCHAR2(10)
CREATION_TS DATE
CREATION_TS_OLD DATE
MODIFIED_BY VARCHAR2(10)
MODIFIED_BY_OLD VARCHAR2(10)
MODIFICATION_TS DATE
MODIFICATION_TS_OLD DATE
UPDATED_BY VARCHAR2(10)
UPDATED_TS DATE
ACTION_TYPE VARCHAR2(10)
I now need to create a view of this audit table, but do not want to list all the columns from the audit table, instead I would like it to look like this:
Modification_TS ** Action_Type ** Updated_By ** CHANGES
Where CHANGES would be a variable that stores the concatenated new & old values (if they are different).
I assume I need to create a stored procedure using PL/SQL to find these values then insert the values into a view...but all of my efforts do not seem to work.
Here is the procedure I've written:
CREATE OR REPLACE PROCEDURE proc_AUD_OBLIGATIONS AS
modData VARCHAR2(2000) :=' ';
emp VARCHAR2(200);
actType VARCHAR2(100);
actDate DATE;
obUser VARCHAR2(500);
CURSOR cur_AUD_OBLIGATION IS
SELECT o.UPDATED_TS, o.UPDATED_BY, o.OBLIGATION_ID, o.COMMUNICATION_ID,o.COMMUNICATION_ID_OLD,o.OBL_DESC,o.OBL_DESC_OLD,
o.OBL_TYPE, o.OBL_TYPE_OLD, o.ORIGINAL_TARGET_DATE,o.ORIGINAL_TARGET_DATE_OLD,o.TARGET_DATE,o.TARGET_DATE_OLD,
o.ACTUAL_DATE,o.ACTUAL_DATE_OLD,o.STATUS,o.STATUS_OLD,o.DOCLINK,o.DOCLINK_OLD,o.SERIAL_NUMBER,o.SERIAL_NUMBER_OLD,
u.FNAME || ' ' ||u.LNAME AS EMPLOYEE,o.ACTION_TYPE
FROM AUD_OBLIGATION o, TRAC_USER u, OBLIGATION_USER ou
WHERE o.OBLIGATION_ID = ou.OBLIGATION_ID
AND
ou.TRAC_USER_ID = u.TRAC_USER_ID;
i_AUD_OBLIGATION cur_AUD_OBLIGATION%rowtype;
BEGIN
for i_AUD_OBLIGATION in cur_AUD_OBLIGATION loop
actType := i_AUD_OBLIGATION.ACTION_TYPE;
actDate := i_AUD_OBLIGATION.UPDATED_TS;
emp := i_AUD_OBLIGATION.UPDATED_BY;
IF i_AUD_OBLIGATION.OBL_DESC != i_AUD_OBLIGATION.OBL_DESC_OLD
THEN modData := 'OBL. DESC. was: ' || i_AUD_OBLIGATION.OBL_DESC_OLD
|| 'It is now: ' ||i_AUD_OBLIGATION.OBL_DESC;
ELSE modData := modData;
END IF;
IF i_AUD_OBLIGATION.OBL_TYPE != i_AUD_OBLIGATION.OBL_TYPE_OLD
THEN modData := modData || 'OBL. TYPE. was: ' ||i_AUD_OBLIGATION.OBL_TYPE_OLD
|| 'It is now: ' ||i_AUD_OBLIGATION.OBL_TYPE;
ELSE modData := modData;
END IF;
IF i_AUD_OBLIGATION.ORIGINAL_TARGET_DATE != i_AUD_OBLIGATION.ORIGINAL_TARGET_DATE_OLD
THEN modData := modData || 'ORIG.TRGT DATE was: ' || i_AUD_OBLIGATION.ORIGINAL_TARGET_DATE_OLD
|| 'It is now: ' ||i_AUD_OBLIGATION.ORIGINAL_TARGET_DATE;
ELSE modData := modData;
END IF;
INSERT INTO vw_AUD_OBLIGATIONS VALUES
(actDate,actType, emp,modData);
END LOOP;
END;
Here is the view I've created, based on this procedure (it does not compile):
CREATE OR REPLACE VIEW vw_AUD_OBLIGATIONS
(Action_Date, Action_Type, Action_User, Modified_Data)
AS
SELECT actDate,actType, emp,modData
FROM proc_AUD_OBLIGATIONS
END;
Any thoughts on how to make this work - it seems like such a simple concept....
Thanks in advance
TonyYou have a couple of misconceptions here. First, you cannot SELECT from a procedure. You need to write a PROCEDURE that INSERTs these columns into a TABLE, then simply SELECT from the TABLE. There are of course many variations, but I hope you get the general idea here.
Greg -
Creating a XMLfile using pl/sql procedure.
Hi,
I have a scenario here. I have to create a XML file, in a perticular format. Since its not a well formed XML format, I am facing issues while creating the file.
The XML file format is as below.
<SECTION>10-B</SECTION>
<?xml version="1.0" encoding="UTF-8"?>
<Name>
<First>ABC</First>
<Middle>BCD</Middle>
<Lastt>ABC</Last>
<Marks>
<Subj1>89</Subj1>
<Subj2>89</Subj2>
<Subj3>89</Subj3>
</Marks>
</Name>
<?xml version="1.0" encoding="UTF-8"?>
<Name>
<First>ABC</First>
<Middle>BCD</Middle>
<Lastt>ABC</Last>
<Marks>
<Subj1>89</Subj1>
<Subj2>89</Subj2>
<Subj3>89</Subj3>
</Marks>
</Name>
<SECTIONCNT>6</SECTIONCNT>
I tried to create the file using utl functions, But it didnt work. I would like to know is there any alternative approach?
-- AnuOracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE 10.2.0.5.0 Production
TNS for Solaris: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production
I used the below query to get the XML data from relational tables.
To fetch the header :
SELECT XMLELEMENT (NAME "BATCHHEADER", batch_name) bname
FROM AP_BATCHES_ALL ab
WHERE ab.batch_id = c_batch_id AND ab.org_id = c_org_id;
For the details :
SELECT '<?xml version="1.0" encoding="UTF-8" ?>'
|| XMLELEMENT (
NAME "ABCD",
XMLELEMENT (
NAME "BankSvcRq",
XMLELEMENT (
NAME "RqUID",
'00000000-0000-0000-0000-000000'
|| TO_CHAR (SYSDATE, 'MMDDYY')),
XMLELEMENT (
NAME "XferAddRq",
XMLELEMENT (
NAME "RqUID",
'00000000-0000-0000-0000-000000'
|| TO_CHAR (SYSDATE, 'MMDDYY')),
XMLELEMENT (NAME "PmtRefId", invoice_num),
XMLELEMENT (
NAME "CustId",
XMLFOREST ('B-Bank' AS "SPName",
'B-BankID' AS "CustPermId")),
XMLELEMENT (
NAME "XferInfo",
XMLELEMENT (
NAME "DepAcctIdFrom",
XMLELEMENT (NAME "AcctId", '123456'),
XMLELEMENT (NAME "AcctType", 'DDB'),
XMLELEMENT (NAME "Name", 'Corelogic'),
XMLELEMENT (
NAME "BankInfo",
XMLFOREST ('ABC' AS "BankIdType",
'11111111' AS "BankId"))),
XMLELEMENT (
NAME "DepAcctIdTo",
XMLELEMENT (NAME "AcctId", '888888'),
XMLELEMENT (NAME "AcctType", 'DDD'),
XMLELEMENT (NAME "Name", 'Comerica Bank'),
XMLELEMENT (
NAME "BankInfo",
XMLFOREST ('ABCD' AS "BankIdType",
'11111111' AS "BankId"))),
XMLELEMENT (
NAME "RemoteCheckPayee",
(SELECT XMLELEMENT (NAME "PayeeName",
vendor_name)
FROM po_vendors po
WHERE po.vendor_id = ai.vendor_id)),
XMLELEMENT (
NAME "CurAmt",
XMLFOREST ( invoice_amount AS "Amt",
payment_currency_code AS "CurCode")),
XMLELEMENT (NAME "DueDt",
TO_CHAR (SYSDATE, 'YYYY-MM-DD')),
(SELECT XMLAGG (
XMLELEMENT (
NAME "RefInfo",
XMLFOREST (
'Originator to Beneficiary '
|| distribution_line_number AS "RefType",
ad.description AS "RefId"))
ORDER BY distribution_line_number ASC)
FROM ap_invoice_distributions_all ad
WHERE ad.invoice_id = ai.invoice_id)),
XMLELEMENT (
NAME "PrinterInfo",
XMLELEMENT (
NAME "PrinterId",
'ABCD-Printer')))))
lc_qry
FROM ap_invoices_all ai
WHERE batch_id = 1168207
AND org_id = 13
And for the trailer:
SELECT XMLELEMENT (NAME "BATCHTRAILER", COUNT (1)) cnt
FROM ap_invoices_all ai
WHERE invoice_id = NVL (c_invoice_id, invoice_id)
AND batch_id = c_batch_id
AND org_id = c_org_id
Since the details query is having avery long output, I cant print this in one shot. So I am breaking the line and writing the same in the output file.
But this results in breaking the tags/data,
Regards,
Anupama -
How to create one procedure which can drop and create materialized view
Hi,
I want to create one pl/sql procedure which can first drop materialized view CATEGORY_PK and after that create same materialized view CATEGORY_PK.
programme is as follows:
DROP MATERIALIZED VIEW CATEGORY_PK;
CREATE MATERIALIZED VIEW CATEGORY_PK REFRESH FORCE WITH PRIMARY KEY AS
SELECT cav1.ownerid AS categoryid, p.uuid AS productid ,p.domainID AS productdomainid,pav.stringvalue AS NAME
,pav2.stringvalue AS ID, pav3.stringvalue AS SHORT
FROM product p, product_av pav, catalogcategory_av cav1, catalogcategory_av cav2,product_av pav2,product_av pav3
WHERE
cav1.NAME = 'PRODUCT_BINDING_ATTRIBUTE' AND
cav2.NAME = 'PRODUCT_BINDING_VALUE' AND
cav1.ownerid = cav2.ownerid AND
p.uuid = pav.ownerid AND
p.uuid = pav2.ownerid AND
p.uuid = pav3.ownerid AND
pav.NAME = cav1.stringvalue AND
pav2.NAME = cav1.stringvalue AND
pav2.NAME = cav1.stringvalue AND
pav.stringvalue = cav2.stringvalue AND
pav2.stringvalue = cav2.stringvalue AND
pav3.stringvalue = cav2.stringvalue
UNION
SELECT catalogcategoryid AS categoryid, productid, repdomainid AS productdomainid,pav1.stringvalue AS NAME
,pav2.stringvalue AS ID, pav3.stringvalue AS SHORT
FROM productcategoryassignment ,product_av pav1,product_av pav2,product_av pav3
WHERE pav1.ownerid=productid
AND pav2.ownerid=productid
AND pav3.ownerid=productid
AND pav1.NAME='name'
AND pav2.NAME='productID'
AND pav3.NAME='shortDescription';user498566 wrote:
I want to create one pl/sql procedure which can first drop materialized view CATEGORY_PK and after that create same materialized view CATEGORY_PK.That sounds like a waste of time and resources. What do you hope to achieve by this? A refresh? If so, a simple refresh of the old materialized view will do.
If you truly want to continue this road, you'll have to use the EXECUTE IMMEDIATE command to execute DDL commands from within PL/SQL.
Regards,
Rob. -
Illegal use of LONG datatype error message when i create materialized view
Hello to all
I want create read only materialized view replication environment two of our tables have LONG datatype when i create materialized view against on them
I recieve this error message
CREATE MATERIALIZED VIEW MDB.TOAD_PLAN_TABLE TABLESPACE aramis REFRESH FORCE WITH ROWID AS SELECT * FROM MDB.TOAD_PLAN_TABLE@arahisto
Error report:
SQL Error: ORA-00997: illegal use of LONG datatype
00997. 00000 - "illegal use of LONG datatype"
Do you know any resort solution for it?
thanksYou can not use longs in materialized views over a database link, you can however take a part of a long over to a materialized view.
I have gotten this to work in the past l had to create a PL/SQL function that you can use to extract the character data from the long column and use that to
as part of the function you will need to pass in the columns of the table that will identify the unique records so you can pick out the long column
example function
-- you will need to make sure this funtion is in the remote location as you can not select longs accross a DB LINK.
CREATE OR REPLACE FUNCTION MDB.TOAD_PLAN_LONG_CONV
(pass in the primary key columns for the table)
RETURN VARCHAR2
IS
v_long VARCHAR2(32767) ;
BEGIN
BEGIN
-- need to select the long column into the PL/SQL variable
SELECT long_column
INTO v_long
FROM MDB.TOAD_PLAN_TABLE
WHERE key_columns = passed columns ;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = '-01406' THEN
NULL ;
ELSE
RAISE ;
END IF ;
END ;
RETURN SUBSTR(v_long,1,4000) ;
END ;
Then when you create the materialized view utilize that function on the long column.
create or replace materialized view MDB.TOAD_PLAN_TABLE TABLESPACE aramis REFRESH FORCE WITH ROWID
AS
SELECT column1, .... columnx,
MDB.TOAD_PLAN_LONG_CONV@arahisto (primary key column list) as long_column_name
FROM MDB.TOAD_PLAN_TABLE@arahisto ;
See if this will work for you? Keep in mind however this solution will not get the entire long column only as much as a PL/SQL variable will hold of it.
Mike -
Error while creating materialized view which using database link
Helo!
I'm getting error "ORA-00942: table or view does not exist" when I want to create materialized view.
Details:
1. On destination database I create a database link:
CREATE DATABASE LINK SDATABASE
CONNECT TO MYUSER
IDENTIFIED BY MYUSERPASS
USING 'ORCL';
=> Command "SELECT * FROM TABLE1@SDATABASE" returns data normally!
2. On source database I create MATERIALIZED VIEW LOG:
CREATE MATERIALIZED VIEW LOG
ON TABLE1
WITH PRIMARY KEY
INCLUDING NEW VALUES;
3. Now, when I want to create MATERIALIZED VIEW on destination database:
CREATE MATERIALIZED VIEW TABLE1
REFRESH FAST
START WITH SYSDATE
NEXT SYSDATE + 1/1440
WITH PRIMARY KEY
AS SELECT * FROM TABLE1@SDATABASE;
...I get error "ORA-00942: table or view does not exist"!
How is that possible if command "SELECT * FROM TABLE1@SDATABASE" returns data normally?
Thanks,
VorancAnd, I'm using Oracle 10g.
Voranc -
Error while creating Materialized View step 3 of 6 using wizard
have oracle 9i Rel 1 on Windows 2000 server. Master Site has been setup. Database links are created at Materialized view site. But while creating Materialized View Group using wizard there is following error on step 3 of 6.
Statement:----------------
/*OracleOEM*/ SELECT 1 FROM SYS.dba_constraints@masterdbname WHERE OWNER='username' and table_name='tabname' AND constraint_type='P'
Stack Trace:----------------
ORA-00942: table or view does not exist.
ORA-02063: preceding line from masterdbname.
All parameters for replication are correct.
Please help me early.
ThanksHello,
In the masterdbname, logging as sys user, you must grant select permission on sys.dba_constraints view to mvadmin_dbname user (where dbname is the replicated database name).
Regards, -
Error creating materialized view log using DBlink
Hi guys,
I have 2 databases in diferent machines . (machine A and B)
Machine A is my production database and I have a database link in machine B accessing Machine A
CREATE MATERIALIZED VIEW vm_test
BUILD IMMEDIATE
REFRESH FAST ON commit as
select * from test@A
-- no problem in this first operation the materialized view was created sucessfully
Now I need to create the LOG
SQL> CREATE MATERIALIZED VIEW LOG ON test
2 PCTFREE 5
3 TABLESPACE prodemge_2006
4 STORAGE (INITIAL 10K NEXT 10K);
CREATE MATERIALIZED VIEW LOG ON test
ERROR at line 1:
ORA-02050: transaction 5.21.8771 rolled back, some remote DBs may be in-doubt
ORA-02068: following severe error from A
ORA-03113: end-of-file on communication channel
What could be causing this error ?
Thank you,
FelipeORA-02050 transaction string rolled back, some remote DBs may be in-doubt
Cause: Network or remote failure during a two-phase commit.
Action: Notify operations; remote databases will automatically re-sync when the failure is repaired.
ORA-02068 following severe error from stringstring
Cause: A severe error (disconnect, fatal Oracle error) was received from the indicated database link. See following error text.
Action: Contact the remote system administrator.
M.S.Taj -
Create materialized view is failing when refresh fast is used
version 10.2.0.4 on solaris
This statement is working fine
CREATE MATERIALIZED VIEW MVIEW1
TABLESPACE MIS_CURD01
BUILD IMMEDIATE
as
SELECT ACTIVITY_ID "ACTIVITY_ID",
ASSOC_ID "ASSOC_ID",
PIT_ROLE_CODE "PIT_ROLE_CODE",
PIT_BANK_CODE "PIT_BANK_CODE",
PIT_COST_CENTER "PIT_COST_CENTER",
RESP_ASSOC_IND "RESP_ASSOC_IND"
FROM TABLE1@DBLINK;
The statement with fast refresh is failing with this error message
ERROR at line 18:
ORA-12018: following error encountered during code generation for
"TABLE1"
ORA-00942: table or view does not exist
Here is the statement
CREATE MATERIALIZED VIEW MVIEW1
TABLESPACE MIS_CURD01
NOCACHE
LOGGING
NOCOMPRESS
NOPARALLEL
BUILD IMMEDIATE
USING INDEX TABLESPACE MIS_CURI01
REFRESH FAST ON DEMAND
WITH PRIMARY KEY
AS
SELECT ACTIVITY_ID "ACTIVITY_ID",
ASSOC_ID "ASSOC_ID",
PIT_ROLE_CODE "PIT_ROLE_CODE",
PIT_BANK_CODE "PIT_BANK_CODE",
PIT_COST_CENTER "PIT_COST_CENTER",
RESP_ASSOC_IND "RESP_ASSOC_IND"
FROM TABLE1@DBLINK;
Any idea what's going wrong here. Thanks for your help in advance.
Edited by: user11319873 on Jun 30, 2010 4:17 PMRefresh FAST requires that
a. An MV Log (Snapshot Log) be created on the source table
b. The user doing the refresh (i.e. the account that the DBLink uses) has SELECT privilege on the MV Log.
Hemant K Chitale -
Create Materialized View based on another database table using db link?
SQL> SELECT sysdate
2 FROM dual@CBRLINK ;
SYSDATE
21-NOV-12
SQL> CREATE MATERIALIZED VIEW USERCBR.V_T24_COUNTRY1
2 REFRESH COMPLETE
3 START WITH SYSDATE NEXT SYSDATE + (5/24)
4 AS
5 SELECT sysdate
6 FROM dual@CBRLINK ;
CREATE MATERIALIZED VIEW USERCBR.V_T24_COUNTRY1
ERROR at line 1:
ORA-04052: error occurred when looking up remote object SYS.DUAL@CBRLINK
ORA-00600: internal error code, arguments: [ORA-00600: internal error code,
arguments: [qksfroFXTStatsLoc() - unknown KQFOPT type!], [0], [], [], [], [],
ORA-02063: preceding line from CBRLINKIt works for me:orcl>
orcl> CREATE MATERIALIZED VIEW scott.V_T24_COUNTRY1
2 REFRESH COMPLETE
3 START WITH SYSDATE NEXT SYSDATE + (5/24)
4 AS
5 SELECT sysdate
6 FROM dual@l1 ;
Materialized view created.
orcl> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for 32-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
orcl>so there is no problem with the code. HTH. -
Start one job after another complets using PL/SQL procedure and DBMS_JOB
All,
I am attempting to refresh a materialized view using DBMS_JOB and having a PL/SQL program loop through each materialized view name that resides in a table I created. We do the table because they have to be refreshed in a specific order and I utilize the ORDER_OF_REFRESH column to dictate which MV comes first, second, third, etc.
Now - I have this working to the extent that it kicks off 4 materialized views (currently set the procedure to only do 4 MVs for testing purposes) but I would ultimately like the procedure to create a new DBMS_JOB that calls DBMS_MVIEW.REFRESH of the next view in line ONLY after the preceeding materialized view DBMS_JOB completes.
The purpose of all of this is to do a few things. One - if I simply create a procedure with the DBMS_MVIEW.REFRESH call to each materialized view in order - that works but if one fails, the job starts over again and will up to 16 times - BIG PROBLEM. Secondly, we want the job that will call this procedure to fail if it encounters 2 failures on any one materialized view (because some MVs may be dependant upon that data and cannot use old stale data).
This may not be the "best" approach but I am trying to make the job self-sufficient in that it knows when to fail or not, and doesn't kick off the materialized views jobs all at once (remember - they need to start one after the other - in order).
As you can see near the bottom, my logic doesn't work quite right. It kicks off all four jobs at once with the date of the whatever LAST_REFRESH is in my cursor (which ultimately is from the prior day. What I would like to happen is this:
1.) 1st MV kicks off as DBMS_JOB and completes
2.) 2nd MV kicks off with a start time of 3 seconds after the completion of 1st MV (based off LAST_REFRESH) date.
3.) This conitnues until all MVs are refresh or until 2 failures are encountered, in which no more jobs are scheduled.
- Obviously I am having a little bit of trouble with #2 and #3 - any help is appreciated.
CREATE OR REPLACE PROCEDURE Next_Job_Refresh_Test2 IS
V_FAILURES NUMBER;
V_JOB_NO NUMBER;
V_START_DATE DATE := SYSDATE;
V_NEXT_DATE DATE;
V_NAME VARCHAR2(30);
V_DELIMITER VARCHAR2(1);
CURSOR MV_LIST IS SELECT DISTINCT A.ORDER_OF_REFRESH,
A.MV_OBJECT_NAME
FROM CATEBS.DISCO_MV_REFRESH_ORDER A
WHERE A.ORDER_OF_REFRESH < 5
ORDER BY A.ORDER_OF_REFRESH ASC;
CURSOR MV_ORDER IS SELECT B.ORDER_OF_REFRESH,
B.MV_OBJECT_NAME,
A.LAST_REFRESH
FROM USER_SNAPSHOTS A,
DISCO_MV_REFRESH_ORDER B
WHERE A.NAME = B.MV_OBJECT_NAME
ORDER BY B.ORDER_OF_REFRESH ASC;
BEGIN
FOR I IN MV_LIST
LOOP
IF I.ORDER_OF_REFRESH = 1
THEN V_START_DATE := SYSDATE + (30/86400); -- Start job one minute after execution time
ELSE V_START_DATE := V_NEXT_DATE;
END IF;
V_FAILURES := 0;
V_JOB_NO := 0;
V_NAME := I.MV_OBJECT_NAME;
V_DELIMITER := '''';
DBMS_JOB.SUBMIT(V_JOB_NO,'DBMS_MVIEW.REFRESH(' || V_DELIMITER || V_NAME || V_DELIMITER || ');',V_START_DATE,NULL);
SELECT JOB, FAILURES INTO V_JOB_NO, V_FAILURES
FROM USER_JOBS
WHERE WHAT LIKE '%' || V_NAME || '%'
AND SCHEMA_USER = 'CATEBS';
IF V_FAILURES = 3
THEN DBMS_JOB.BROKEN(V_JOB_NO,TRUE,NULL); EXIT;
END IF;
FOR O IN MV_ORDER
LOOP
IF I.ORDER_OF_REFRESH > 2
THEN V_NEXT_DATE:= (O.LAST_REFRESH + (3/86400)); -- Start next materialized view 3 seconds after completion of prior refresh
END IF;
END LOOP;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF MV_LIST%ISOPEN
THEN CLOSE MV_LIST;
END IF;
NULL;
END Next_Job_Refresh_Test2;
---------------------------------------------------------------------------------------------------------------------Justin,
I think I am getting closer. I have a procedure shown just below this that updates my custom table with information from USER_SNAPSHOTS to reflect the time and status of the refresh completion:
CREATE OR REPLACE PROCEDURE Upd_Disco_Mv_Refresh_Order_Tbl IS
V_STATUS VARCHAR2(7);
V_LAST_REFRESH DATE;
V_MV_NAME VARCHAR2(30);
CURSOR MV_LIST IS SELECT DISTINCT NAME, LAST_REFRESH, STATUS
FROM USER_SNAPSHOTS
WHERE OWNER = 'CATEBS';
BEGIN
FOR I IN MV_LIST
LOOP
V_STATUS := I.STATUS;
V_LAST_REFRESH := I.LAST_REFRESH;
V_MV_NAME := I.NAME;
UPDATE DISCO_MV_REFRESH_ORDER A SET A.LAST_REFRESH = V_LAST_REFRESH
WHERE A.MV_OBJECT_NAME = V_MV_NAME;
COMMIT;
UPDATE DISCO_MV_REFRESH_ORDER A SET A.REFRESH_STATUS = V_STATUS
WHERE A.MV_OBJECT_NAME = V_MV_NAME;
COMMIT;
END LOOP;
END Upd_Disco_Mv_Refresh_Order_Tbl;
Next, I have a "new" procedure that does the job creation and refresh show just below this which, when starting the loop, sets the LAST_REFRESH date in my table to NULL and the STATUS = 'INVALID'. Then if the order of refresh = 1 then it uses SYSDATE to submit the job and start right away, else if it's not the first job, it uses V_NEXT_DATE. Now, V_NEXT_DATE is equal to the LAST_REFRESH date from my table when the view has completed and the V_PREV_STATUS = 'VALID'. I think tack on 2 seconds to that to begin my next job.... See code below:
CREATE OR REPLACE PROCEDURE Disco_Mv_Refresh IS
V_FAILURES NUMBER;
V_JOB_NO NUMBER;
V_START_DATE DATE := SYSDATE;
V_NEXT_DATE DATE;
V_NAME VARCHAR2(30);
V_PREV_STATUS VARCHAR2(7);
CURSOR MV_LIST IS SELECT DISTINCT A.ORDER_OF_REFRESH,
A.MV_OBJECT_NAME,
A.LAST_REFRESH,
A.REFRESH_STATUS
FROM CATEBS.DISCO_MV_REFRESH_ORDER A
WHERE A.ORDER_OF_REFRESH <= 5
ORDER BY A.ORDER_OF_REFRESH ASC;
BEGIN
FOR I IN MV_LIST
LOOP
V_NAME := I.MV_OBJECT_NAME;
V_FAILURES := 0;
UPDATE DISCO_MV_REFRESH_ORDER SET LAST_REFRESH = NULL WHERE MV_OBJECT_NAME = V_NAME;
UPDATE DISCO_MV_REFRESH_ORDER SET REFRESH_STATUS = 'INVALID' WHERE MV_OBJECT_NAME = V_NAME;
IF I.ORDER_OF_REFRESH = 1
THEN V_START_DATE := SYSDATE;
ELSE V_START_DATE := V_NEXT_DATE;
END IF;
DBMS_JOB.SUBMIT(V_JOB_NO,'DBMS_MVIEW.REFRESH(' || '''' || V_NAME || '''' || '); BEGIN UPD_DISCO_MV_REFRESH_ORDER_TBL; END;',V_START_DATE,NULL);
SELECT A.REFRESH_STATUS, A.LAST_REFRESH INTO V_PREV_STATUS, V_NEXT_DATE
FROM DISCO_MV_REFRESH_ORDER A
WHERE (I.ORDER_OF_REFRESH - 1) = A.ORDER_OF_REFRESH;
IF I.ORDER_OF_REFRESH > 1 AND V_PREV_STATUS = 'VALID'
THEN V_NEXT_DATE := V_NEXT_DATE + (2/86400);
ELSE V_NEXT_DATE := NULL;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF MV_LIST%ISOPEN
THEN CLOSE MV_LIST;
END IF;
NULL;
END Disco_Mv_Refresh;
My problem is that it doesn't appear to be looping to the next job. It worked succesfully on the first job but not the subsequent jobs (or materialized views in this case).... Any ideas? -
Error Creating Materialized View With a Job
Oracle 9ir2
I've created a job like this in a java class:
...Java Code ...
cs = conn.prepareCall ("DECLARE v_job NUMBER; BEGIN DBMS_JOB.SUBMIT(v_job,'begin CTH_REGENERA_VM; end;', TRUNC(SYSDATE+1) + (3/24)); END;");
...Java Code ...
The Procedure called in the Job:
CREATE OR REPLACE PROCEDURE CTH_REGENERA_VM
AUTHID CURRENT_USER IS
existe NUMBER(1);
cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;
fdbk BINARY_INTEGER;
BEGIN
SELECT count(*) INTO existe FROM user_mviews WHERE mview_name = 'CTH_PRESENTA_A_VM';
IF existe > 0 THEN
DBMS_SQL.PARSE(cur, 'DROP MATERIALIZED VIEW CTH_PRESENTA_A_VM', DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE(cur);
INSERT INTO CTH_HISTORIAL VALUES('ELIMINADA VM CTH_PRESENTA_A_VM', SYSDATE);
COMMIT;
END IF;
DBMS_SQL.PARSE(cur, 'CREATE MATERIALIZED VIEW CTH_PRESENTA_A_VM
TABLESPACE DAT1_CTH
STORAGE(INITIAL 16M NEXT 8M MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)
XMLTYPE XML STORE AS CLOB ( TABLESPACE DAT1_CTH
STORAGE(INITIAL 16M NEXT 8M MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0))
AS select FICHA, XML,
extractvalue(xml, ''/FICHE/Encab_de_nombre_geogr�fico_a'') as MUNICIPIO,
extractvalue(xml, ''/FICHE/Encab_de_nombre_geogr�fico_c'') as CALIFICACION,
extractvalue(xml, ''/FICHE/Encab_de_nombre_geogr�fico_b'') as PROVINCIA,
extractvalue(xml, ''/FICHE/Encab_tem�tico_de_materia_a[1]'') as MATERIA,
extractvalue(xml, ''/FICHE/Fecha_cronol�gica_b[1]'') as FECHA,
extractvalue(xml, ''/FICHE/Datos_matem�ticos_a[1]'') as ESCALA
from cth_xmltable', DBMS_SQL.NATIVE);
INSERT INTO CTH_HISTORIAL VALUES('ASIGNO EL PARSE DE MATERIALIZED', SYSDATE);
fdbk := DBMS_SQL.EXECUTE(cur);
INSERT INTO CTH_HISTORIAL VALUES('EJECUTO EL PARSE DE MATERIALIZED', SYSDATE);
INSERT INTO CTH_HISTORIAL VALUES('CREADA VM CTH_PRESENTA_A_VM', SYSDATE);
DBMS_SQL.PARSE(cur, 'CREATE INDEX CTH_INDEX1
ON CTH_PRESENTA_A_VM(XML)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS (''storage cth section group ctxsys.auto_section_group'')', DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE(cur);
INSERT INTO CTH_HISTORIAL VALUES('CREADO INDICE ORACLE TEXT CTH_INDEX1', SYSDATE);
DBMS_SQL.PARSE(cur, 'CREATE INDEX CTH_IDX_MUNICIPIO3
ON CTH_PRESENTA_A_VM(UPPER(MUNICIPIO))
TABLESPACE IDX1_CTH
STORAGE (INITIAL 1M NEXT 512K MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)', DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE(cur);
INSERT INTO CTH_HISTORIAL VALUES('CREADO INDICE CTH_IDX_MUNICIPIO2', SYSDATE);
DBMS_SQL.PARSE(cur, 'CREATE INDEX CTH_IDX_FICHA2
ON CTH_PRESENTA_A_VM
(FICHA)
TABLESPACE IDX1_CTH
STORAGE(INITIAL 1M NEXT 512K MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)', DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE(cur);
INSERT INTO CTH_HISTORIAL VALUES('CREADO INDICE CTH_IDX_FICHA2', SYSDATE);
DBMS_SQL.CLOSE_CURSOR(cur);
COMMIT;
END;
I got always an error in the created materialized view. If I call the procedure with SQL Plus, it run ok. The user
has CTXAPP, DBA roles, so I supouse it is not a privileges problem. I also tried to create a simple materialized view or a table, and always got an error ora-12011
Thanks in advance.If I call the procedure with SQL Plus, it run ok. Are you using the same user to run it in SQL*Plus as runs it from Java.
The normal reason for procedures to fail like this is privileges. Particularly, we cannot run procedures using privileges we have been granted through roles.
The user has CTXAPP, DBA roles, so I supouse it is not a privileges problem. Try granting the system privilege CREATE MATERIALIZED VIEW to the user and see what happens.
I drop the materialized and create again, cause it's the fastest way I've found. With a DBMS_MVIEW.REFRESH is too slow.I find that surprising as drop & create has to do all the work that a refresh has to do plus some more - maybe it's something to do with XML. Did you try adding a snapshot log and going for FAST? I don't know whwther the XML procesing would render the view complex - have you explained it?
Cheers, APC -
How to CREATE MATERIALIZED VIEW LOG (MV fast refresh) with some JOINS
Hi @ all,
i'm trying to create a MATERIALIZED VIEW LOG for a fast refresh of a MATERIALIZED VIEW.
It works fine with a simple Request in the MATERIALIZED VIEW:
CREATE MATERIALIZED VIEW MV_ZOTD43_P
TABLESPACE GDII
BUILD IMMEDIATE
REFRESH FORCE AS
SELECT * FROM ZOTD43_P;
COMMIT;
CREATE MATERIALIZED VIEW LOG ON ZOTD43_P
TABLESPACE "GDII"
WITH PRIMARY KEY, ROWID, SEQUENCE INCLUDING NEW VALUES;
call DBMS_MVIEW.REFRESH('MV_ZOTD43_P', 'f');
But when I use a complex SQL-Request with some JOINS (one of the Table with spatial Data) in the MATERIALIZED VIEW, I get an error:
CREATE MATERIALIZED VIEW MV_TEST
TABLESPACE GDII
BUILD IMMEDIATE
REFRESH FORCE AS
SELECT lptd04_p.sst_nr AS sst_nr,
lptd03_p.aaaa AS aaaa,
lptd04_geom.geom as geom
FROM lptd04_p lptd04_p
JOIN lptd01_p lptd01_p ON lptd01_p.cre_nr = lptd04_p.sst_nr
JOIN lptd04_geom ON lptd04_geom.sst_nr = lptd04_p.sst_nr
JOIN lptd03_p lptd03_p ON lptd03_p.lief_nr = lptd04_p.lief_nr;
COMMIT;
CREATE MATERIALIZED VIEW LOG ON LPTD04_P
TABLESPACE "GDII"
WITH PRIMARY KEY, ROWID, SEQUENCE INCLUDING NEW VALUES;
call DBMS_MVIEW.REFRESH('MV_TEST', 'f');
Error report:
SQL Error: ORA-12004: REFRESH FAST kann für Materialized View "GDI"."MV_GDI_SST_STAMM" nicht benutzt werden
ORA-06512: in "SYS.DBMS_SNAPSHOT", Zeile 2255
ORA-06512: in "SYS.DBMS_SNAPSHOT", Zeile 2461
ORA-06512: in "SYS.DBMS_SNAPSHOT", Zeile 2430
ORA-06512: in Zeile 1
12004. 00000 - "REFRESH FAST cannot be used for materialized view \"%s\".\"%s\""
*Cause: The materialized view log does not exist or cannot be used. PCT
refresh is also not enabled on the materialized view
*Action: Use just REFRESH, which will reinstantiate the entire table.
If a materialized view log exists and the form of the materialized
view allows the use of a materialized view log or PCT refresh is
possible after a given set of changes, REFRESH FAST will
be available starting the next time the materialized view is
refreshed.
Am I doing something wrong or is it not possible CREATE MATERIALIZED VIEW LOG when the MATERIALIZED VIEW got some JOINS?
Regards,
GreqThanks for the link Alessandro ,
the error seems something to do with the Column-Type SDO_GEOMETRY, so
i create a new thread in the Spatial Discussion forum:
FAST REFRESHing of Oracle Materialized Views containing SDO_GEOMETRY column
Regards,
Greq -
Error While Creating Materialized View
Hello,
I am getting error ORA-22818: subquery expressions not allowed here while creating materialized view. I am using Oracle9i Enterprise Edition Release 9.2.0.1.0. Below pasted is my SQL Script.
Any help is highly appreciable.
Thanks
*********SQL************
select distinct(id),NAME,(select count(GRADE) from employees where
nationality like '%US%'and id=a.organization_id and grade=a.grade
group by ID,GRADE) US,(select count(GRADE) from employees where
nationality not like '%US%' and organization_id=a.organization_id and grade=a.grade
group by ORGANIZATION_ID,GRADE) NON_US,grade from employees a
where grade is not null
group by GRADE,ID,name
order by to_number(grade) descHi,
This is a documented restriction on MVs. You cannot have a scalar express (i.e a select statement) in the select list.
You can get round this by joining your select count(grade).. expression in as an inline view in your FROM clause. Or you can create a normal view without the scalar expression, create your MV as a select from this view, then re-define your view to contain the query you want.
Hope that helps,
Rod West -
ORA-25175 when trying to create materialized view, organization index SOLV
Hi,
I'm trying to create a materialized view to compensate for non-normalized table.
I have table anormal, and mv is to be on distinct agency, company in that table.
Here goes:
SQL> select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.3.0 - Productio
NLSRTL Version 10.2.0.3.0 - Production
SQL> create table anormal (company varchar2(8) not null
2 ,dept varchar2(8) not null
3 ,agency varchar2(8) not null
4 ,constraint anormal_pk primary key (company,dept));
Table created.
SQL> insert into anormal values('c1', 1, 'Ajax');
1 row created.
SQL> insert into anormal values('c1', 2, 'Ajax');
1 row created.
SQL> insert into anormal values('c1', 3, 'Acme');
1 row created.
SQL> insert into anormal values('c2', 1, 'Acme');
1 row created.
SQL> insert into anormal values('c2', 2, 'Acme');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from anormal;
COMPANY DEPT AGENCY
c1 1 Ajax
c1 2 Ajax
c1 3 Acme
c2 1 Acme
c2 2 Acme
SQL> create materialized view agency_comp_mv
2 organization index --primary key (agency, company)
3 build deferred
4 refresh on demand
5 as
6 select distinct agency, company from anormal
7 /
select distinct agency, company from anormal
ERROR at line 6:
ORA-25175: no PRIMARY KEY constraint found
SQL>The error tells me that there is no primary key, but is there any way to add such?
- or is my problem rather that I cannot use DISTINCT with organization index?
Regards
Peter
bump
Message was edited by:
Peter Gjelstrup
<SOLVED>
Message was edited by:
Peter GjelstrupThanks William,
I tried with ON PREBUILT TABLE, just to see what happens.
Building on my OP:
SQL> create table iot(agency varchar2(8) not null, company varchar2(8) not null
2 ,constraint iot_pk primary key (agency,company))
3 organization index;
Table created.
SQL> insert into iot select distinct agency, company from anormal;
4 rows created.
SQL> commit;
Commit complete.
SQL> create materialized view iot on prebuilt table
2 as
3 select distinct agency, company from anormal;
Materialized view created.
SQL> select * from iot;
AGENCY COMPANY
Acme c1
Acme c2
Ajax c1
SQL> insert into anormal values('c3', 2, 'Foo');
insert into anormal values('c3', 2, 'Foo')
1 row created
SQL> select * from anormal;
COMPANY DEPT AGENCY
c1 1 Ajax
c1 2 Ajax
c1 3 Acme
c2 1 Acme
c2 2 Acme
c3 2 Foo
6 rows selected.
SQL> select * from iot;
AGENCY COMPANY
Acme c1
Acme c2
Ajax c1
3 rows selectedNow, try to refresh and MV
SQL> alter materialized view iot refresh complete;
Materialized view altered.
SQL> select object_type, to_char(last_ddl_time, 'hh:mi:ss'), status
2 from user_objects where object_name = 'IOT';
OBJECT_TYPE DDL_TIME STATUS
TABLE 10:40:42 VALID
MATERIALIZED VIEW 10:41:13 VALID
SQL> select * from iot;
AGENCY COMPANY
Acme c1
Acme c2
Ajax c1Agency "Foo" is not in MV,
Looks like that IOT select'ed from is indeed the MV:
SQL> drop table iot;
drop table iot
ERROR at line 1:
ORA-12083: must use DROP MATERIALIZED VIEW to drop "STIK"."IOT"
SQL>So, seems that Maxim is right, it just can't be done. And it seems my options are:
Create HEAP organized MV or
Create and maintain IOT
Regards
Peter
Maybe you are looking for
-
I had upgraded to current OS X yosemite, I performed clean install and I also made a new icloud account and apple ID. the previous apple ID have few purchased paid app like- "GarageBand" now in my new apple ID I have to purchase it I was wondering if
-
I created an HTML file in Text Edit and another in Microsoft Word and saved the extensions as .htm and .html When I try to open the webpages in Safari by going to File > Open File, the HTML documents show only the source code in Safari instead of the
-
How do I get Adobe Reader XI to default to Auto Portrait/landscape when I print?
How do I get Adobe Reader XI to default to Auto Portrait/landscape when I print?
-
Re-registering quicklook associations
I've installed SafariStand and HetimaWebThumbnail.qlgenerator plugin. For a couple of weeks everything worked smoothly, my webloc files had the beautiful prewiews icons. Suddenly, it stops working and all webloc files are displayed as standard http i
-
How to change my name in icloud
Hello For Some reason my name in my iCloud account is not correct. When i sent an email with my iCloud Emailaddress my name as sender is not correct. I assume thuis changed when i had to fill in my husbands name with the creditcard info. How Can i ch