How can I avoid errors with dbms_metadata.GET_DEPENDENT_DDL - oracle

I'm writing a custom program to dump the database metadata to files in order to manage them with version control. The default way that data pump or export works isn't ideal for a few reasons (eg. I'd like a separate directory per table).
Sql Developer provides a number of ways of creating export scripts for any object. One way is just by right-clicking the object and selecting Quick DDL. By viewing the logs it creates, one can see the actual SQL it issues to create the DDL script. I've used these scripts to write my custom program and for the most part, they've been perfect.
When I generate the DDL for a materialized view, the SQL it generates is:
SELECT DBMS_METADATA.GET_DDL('MATERIALIZED_VIEW',:name,:owner) FROM DUAL
UNION ALL
SELECT DBMS_METADATA.GET_DEPENDENT_DDL('INDEX',TABLE_NAME, TABLE_OWNER) FROM (
SELECT table_name, table_owner FROM all_indexes
WHERE table_owner = :owner AND table_name = :name
AND index_name NOT IN (
SELECT constraint_name FROM sys.all_constraints
WHERE table_name = table_name AND constraint_type = 'P'
) AND ROWNUM = 1
)
UNION ALL
SELECT dbms_metadata.GET_DEPENDENT_DDL ('COMMENT', :name,:owner ) FROM DUAL
For this script, when executed via SQL Developer Quick DDL, it generates the metadata for the materialized view properly. When I run this script in a program (or even manually with SQL Developer itself), it produces the following errors:
ORA-31608: specified object of type COMMENT not found
ORA-06512: at "SYS.DBMS_METADATA", line 5805
ORA-06512: at "SYS.DBMS_METADATA", line 8436
ORA-06512: at line 1
31608. 00000 - "specified object of type %s not found"
*Cause: The specified object was not found in the database.
*Action: Correct the object specification and try the call again.
This particular materialized view doesn't have any comments (obviously), but I would have expected this part of the clause to just return 0 rows instead of generating an error (especially since SQL Developer uses this itself seemingly without errors).
Is there a way I can avoid this error, while still including comments in the metadata if they exist?
This issue exists on both Oracle 10g & 11g databases.

I was not able to test as I don't really know how to create mview without comment... However the below should work for you. Try to query dba_mview_comments instead of dual to not execute the function when you don't have comments.
UNION ALL
SELECT dbms_metadata.get_dependent_ddl ('COMMENT', :name, :owner)
FROM dba_mview_comments mvc
WHERE mvc.mview_name = :name AND
mvc.owner = :owner AND
length(comments) > 0 AND
rownum = 1

Related

Error with a user defined report in Oracel SQL Developer - Missing IN or OUT parameter at index:: 1

I have created a user defined report within Oracle SQL Developer, with a bind variable.
The report consists of a master_report (style is table), child_report_a containing with a style of 'table' and child_report_b which is the same query, but with the style of 'script'.
I am able to select a cell/row of my master report, and child_report_a data changes accordingly (ie, it returns the cells of the same date I selected.
However, when I try to view this in child_report_b (With the 'script' style) it errors with "Missing IN or OUT parameter at index:: 1".
So the setup is:
tablea
id_pk (number)
name_pk (varchar2)
1
Jack
2
John
3
Amy
tableb
id_fk (number)
start_time(timestamp(6))
1
01-JAN-23 12.00.00.123000000
2
01-JAN-23 13.00.00.123000000
3
02-JAN-23 14.05.00.123000000
User Defined Report:
master_report (Style=Table):
SELECT * FROM tablea
child_report_a (Style=Table) & child_report_b (Style=Script):
SELECT * FROM tablea a INNER JOIN tableb b ON b.id_fk = a.id_pk WHERE trunc(start_time) = trunc(to_timestamp(:STARTTIME)
Any help is appreciated.
EDIT: Included better example of setup.
My goal is to be able to select a row from the master_report, and the child_report_b would return all results which match the date (as currently happens in child_report_a) in the script format.
Welcome to StackOverflow!
The reporting feature is one of my favorites in SQL Developer, so I will try to get you started.
We can't technically answer your question without a fair bit of guessing. We know what's happening on one side of the JOIN, you have a timestamp that you're using TRUNC on.
But we can't tell what is on the other side of the equality predicate in your JOIN.
Here's a working example, see if this helps you.
Parent Query
select trunc(systimestamp) A
from dual
Child Query
select object_name, object_type, last_ddl_time
from user_objects where :A > (trunc(systimestamp) - 30)
And the report -
To debug your report, substitute the bind :STARTTIME with a literal value that is equivalent to what your parent query would return. If that works, so should your report.
Disclaimer: I work for Oracle and am a product manager for SQL Developer.

Unable to drop existing master table in sql developer

I was using yeasterday many times Data Pump in Sql Developer Wizard to export and import data. After each export/import a new master table appeared under the "+" button in sql developer(view->dba).
I wanted to drop all this tables(about 10 tables) and I was successfull for all cases, except 2 of them. When I'm writing sql code: drop table x, it shows me error that this tables doesn't exists. It was working fine for every others tables..
When i run query select * from dba_tables where table_name='x' the table is there. I'm writing drop statement as system user.
select *
from dba_tables
where table_name in ('moj_dump_job'
, 'moj_job_data_pump');
OWNER TABLE_NAME
------------------------------ ------------------------------
SYSTEM moj_dump_job
SYSTEM moj_job_data_pump
drop table moj_dump_job;
Error starting at line : 1 in command -
drop table moj_dump_job
Error report -
ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
I tired to drop this jobs, but it doesnt't work:
select owner_name, job_name
from DBA_DATAPUMP_JOBS;
OWNER_NAME JOB_NAME
------------------------------ ------------------------------
SYSTEM moj_job_data_pump
SYSTEM moj_dump_job
BEGIN
dbms_scheduler.drop_job(job_name => 'moj_dump_job');
END;
Error starting at line : 13 in command -
BEGIN
dbms_scheduler.drop_job(job_name => 'moj_dump_job');
END;
Error report -
ORA-27475: "SYSTEM.MOJ_DUMP_JOB" must be a job
ORA-06512: at "SYS.DBMS_ISCHED", line 213
ORA-06512: at "SYS.DBMS_SCHEDULER", line 657
ORA-06512: at line 2
27475. 00000 - "unknown %s \"%s\".\"%s\""
*Cause: The specified object did not exist, privileges were not granted,
or the object was of the wrong type.
*Action: Specify an object of the correct type on which you have privileges.
Do you have any idea what can I do? Using schema name before table name doesn't help.
Best regards, Darek
Thank's for your help. It work's.
drop table "moj_dump_job"
drop table "moj_job_data_pump";
Table "moj_dump_job" dropped.
Table "moj_job_data_pump" dropped.
Now
select *
from dba_tables
where table_name in ('moj_dump_job'
, 'moj_job_data_pump');
select owner_name, job_name
from DBA_DATAPUMP_JOBS;
Both statements doesn't return any rows. That's perfect, but the 2 tables are still visible under view ->dba ->data pump -> export jobs. How to drop them from the tree?
The reason it was not working cause by default Oracle changes job name to uppercase. To avoid it need use '"my_job"'
As per Oracle doc
Follow SQL naming rules to name Scheduler objects in the
DBMS_SCHEDULER package. By default, Scheduler object names are
uppercase unless they are surrounded by double quotes. For example,
when creating a job, job_name => 'my_job' is the same as job_name =>
'My_Job' and job_name => 'MY_JOB', but different from job_name =>
'"my_job"'. These naming rules are also followed in those cases where
comma-delimited lists of Scheduler object names are used within the
DBMS_SCHEDULER package.

how to get select statement query which was used to create table in oracle

I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table

How do I get the number of rows in each table I have in my oracle database

Can someone tell me how I can get the number of rows in each table in my oracle database? I have found several queries, but none of them worked because I am using oracle 7 and sqlplus 3.2 and basically all what I found didn't work on it. I just need something that would work on sqlplus 3.2.
Required:
Table Name Rows
Table 1 0
Table 2 5
...
Is it possible to do it with something like a loop? Or what exactly should I do?
if SELECT table_name, num_rows from all_tables doesn't give you what you need.
You could use dynamic SQL and counts as Rahul selected.
Run the below to get results which dynamically build a union on all tables, then run the results as it's own query to get final results.
SELECT 'SELECT ' ||t.name || ' as tName, count(*) as Row_Cnt
FROM ' || t.name || ' UNION ALL '
FROM ALL_TABLES t
Just be sure to remove the last union statement on the last query.
Also note: if you don't have access to see the table, it will not come out in this list!
---Updated ------
So if all_tables doesn't exist none of this will work. Since I don't have a oracle 7 instance handy... could you see if SELECT * FROM dictionary returns anything that might produce a list of all the tables? If you find a view or table object use it in place of all_tables above.
I'm reading the docs for oracle 7 now but finding little easily searchable. thus a guess and check method may go faster.

oracle in the real world

I've recently started using oracle after a few years of using mysql. I was immediately struck by how verbose oracle is compared to mysql. Four-word queries (like SHOW INDEX IN < table> ) become four-line queries in oracle.
My question is: how do real oracle DBAs interact with oracle efficiently. There must be some way to alias commonly used commands (like you do in the unix shell). I find it hard to believe that they would type something like
select index_name, column_name, column_position from user_ind_columns
where table_name='MYTABLENAME' order by index_name, column_position
every time they wanted to do something as simple as list the indexes of a table. Otherwise how can they get any work done?
You can use an IDE like SQL Developer or Toad; these have a UI to browse tables, indexes and other objects without typing any commands.
Or in SQL Plus you can simply save commonly used queries as scripts in files, for example a script called show_index could contain:
select index_name, column_name, column_position from user_ind_columns
where table_name=upper('&TABLENAME.') order by index_name, column_position;
You would run this in SQL Plus like this:
SQL> #show_index
Enter value for tablename: mytable

Resources