Checking if oracle table exists and creating it afterwards - ORA-06550 - database

I'm trying to check if table exists and if not, then I want to create it. But I'm still getting this error:
Error report -
ORA-06550: řádka 30, sloupec 28:
PL/SQL: ORA-00942: tabulka nebo pohled neexistuje
ORA-06550: řádka 30, sloupec 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
My code is:
SELECT COUNT(*) into cnt FROM dba_tables WHERE owner = 'CENTRUMADMIN' and table_name = 'AUD$_BACKUP';
DBMS_OUTPUT.PUT_LINE(cnt);
IF (cnt <= 0) THEN
EXECUTE IMMEDIATE 'CREATE TABLE CENTRUMADMIN.AUD$_BACKUP AS select * from SYS.AUD$ where 1=2';
DBMS_OUTPUT.PUT_LINE('Vytvorena tabulka AUD$_BACKUP ve shematu CENTRUMADMIN:');
END IF;
This code is inside my procedure for cleaning audit trail.
Can anyone pls help? Thanks in advance!

As I read in your comments you said you get the error only when the table AUD$_BACKUP does not exist.
which means you get you error here:
EXECUTE IMMEDIATE 'CREATE TABLE CENTRUMADMIN.AUD$_BACKUP AS select * from SYS.AUD$ where 1=2';
I guess you just dont have permissions for sys.AUD$ in you schema.
please notice that PL/SQL code can use role privileges. which means, even if you have "dba" role on your schema, it wont work. so you should run the following grant command:
Alter user myuser select on sys.AUD$
good luck.

Related

Getting error while using sp_helptext on view

I am trying to read the code of a 'view' previously created by someone else ,
when i execute this line of code
EXEC sp_helptext [view name]
i get the following error
Msg 15197, Level 16, State 1, Procedure sp_helptext, Line 110
There is no text for object '_RGEN_ITEMVENEX'.
any idea of how to solve this error ?
you should try to grant VIEW DEFINITION to the desired schema's contained in the database to this role.
Refer to this : https://learn.microsoft.com/fr-fr/sql/t-sql/statements/grant-database-permissions-transact-sql?view=sql-server-2017

Why do I get "Synonym 'syn.Syn_AAA' refers to an invalid object" Error?

When I execute a stroed procedure it works. But specifically when I run the select statement I get the following error
Synonym 'syn.Syn_NEO_DB_tGradeAliases' refers to an invalid object.
SELECT
aa.CompanyId [LegCompanyId],
aa.ProductId AS [LegGradeId],
aa.GradeAliasId [LegGradeAliasId],
aa.ProductName AS [LobGradeText],
aa.[Alias] [GradeAlias],
aa.PhraseKey [PhraseKey],
GETUTCDATE() AS 'TimeStamp'
FROM syn.Syn_AAA aa
I haven't done any database change/permission change.
How can I overcome this?
I ran following query and it shows the base_object_name correctly linked to my table.
SELECT * FROM sys.synonyms WHERE name = 'Syn_AAA'
I overcame by replacing synonym with [LINKED_SERVER].[DB_NAME].[SCHEMA_NAME].[OBJECT_NAME].

issue with DBMS_ADVISOR package

I am trying to use the oracle SQL access advisor utility.
For recommendation on performance tuning and partitioning of tables.
But when i try to use it gives me no results and says there are no result for the task.
I am trying below code to generate the recommendation this is an example from SCOTT schema which also giving me same error
declare
v_sql varchar2(2000) := 'select * from emp where empno in (7369,7499)';
v_tuning_task varchar2(200) := 'tune_task_advisor_view7';
v_tune_result clob;
begin
dbms_advisor.quick_tune ( dbms_advisor.sqlaccess_advisor , v_tuning_task, v_sql );
DBMS_ADVISOR.reset_task(v_tuning_task);
dbms_advisor.set_task_parameter(v_tuning_task, 'ANALYSIS_SCOPE', 'ALL');
dbms_advisor.set_task_parameter(v_tuning_task, 'STORAGE_CHANGE', '10000000');
dbms_advisor.set_task_parameter ( v_tuning_task, 'MODE', 'COMPREHENSIVE');
dbms_output.put_line ('Quick Tune Completed');
end;
SELECT DBMS_ADVISOR.get_task_script ('tune_task_advisor_view7') AS script FROM dual;
The Error --
SELECT DBMS_ADVISOR.get_task_script ('tune_task_advisor_view7') AS script FROM dual
Error report -
SQL Error: ORA-13631: The most recent execution of task tune_task_advisor_view7 contains no results.
ORA-06512: at "SYS.PRVT_ADVISOR", line 3350
ORA-06512: at "SYS.DBMS_ADVISOR", line 641
ORA-06512: at line 1
13631. 00000 - "The most recent execution of task %s contains no results."
*Cause: The user attempted to create a report or script from a task that
has not successfully completed an execution.
*Action: Execute the task and then retry the operation
There is one more that when i comment all the SET_TASK_PARAMETER procedure then it run but does not provide any recommendations the output is like --
SCRIPT
--------------------------------------------------------------------------------
Rem SQL Access Advisor: Version 11.2.0.3.0 - Production
Rem
Rem Username:
Is there any parameter which i missed to define here.
For RESET_TASK if i do not rest_task then it gives me error for it also so i have used it here.
Thanks in advance
When I get this error, this typically means that the DBMS_ADVISOR does not have any advise for the profile based on its diagnostic so it doesn't return a report. I typically don't try to produce a ADDM advisor report, but rather look for all the HASH plans I can find for the query, run an explain plan on those hash values, and then profile the one with the best plan.
I forgot to execute the task !
exec dbms_advisor.execute_task('tune_task_advisor_view7');
and then
SELECT DBMS_ADVISOR.get_task_script ('tune_task_advisor_view7') AS script FROM
dual;
OUTPUT will be
SCRIPT
--------------------------------------------------------------------------------
Rem SQL Access Advisor: Version 12.1.0.2.0 - Production
Rem
Rem Username: CHRIS
Rem Task: tune_task_advisor_view7
Rem Execution date:
Rem
/* RETAIN INDEX "SCOTT"."PK_EMP" */
Find address and hash for the query SQL_ID
select address, hash_value, plan_hash_value from v$sqlarea where sql_id = '3mx8whn1c5jbb';
Purge the plan out of the cursor cache (only if it’s determined that it’s the wrong plan). Statistics should be up to date prior to purging out the plan.
exec sys.dbms_shared_pool.purge(',','C');
exec sys.dbms_shared_pool.purge('00000005DF37F740,46318955','C');
Create the tuning plan if one does not exist.
variable stmt_task VARCHAR2(64);
SET SERVEROUTPUT ON LINESIZE 200 PAGESIZE 20000 LONG 9999
EXEC :stmt_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id => '3mx8whn1c5jbb',task_name => '3mx8whn1c5jbb_AWR_tuning_task');
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('3mx8whn1c5jbb_AWR_tuning_task', 'TEXT', 'TYPICAL', 'FINDINGS') FROM DUAL;
If the tuning plan is reported. Accept the new plan.
DECLARE
sqlprofile_name VARCHAR2(30);
BEGIN
sqlprofile_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE (
task_name => '3mx8whn1c5jbb_AWR_tuning_task'
, name => 'sql_profile_1'
, force_match => true
);
END;
/
If creating a profile doesn’t work or if the plan does not exist in the cursor cache, check the AWR repository to see if a better plan exists.
If you have an AWR repository with the correct plan, you can rerun the queries above and just use the option to get the hash and sql_id from the AWR repository.
If that doesn't work. THEN I used ADDM (As you did above).

Oracle if-else query to check table exist otherwise show a message?

When i am running below query first time its working but after again i am going to run this query i am getting exception
Select count(*) into rec from all_tables where table_name='DefaultTable';
if(rec=1) then
CREATE TABLE DefaultTable(
Code INT NOT NULL,
Code1 INT NOT NULL,
ResultCode INT NOT NULL,
CONSTRAINT DefaultTable_PK PRIMARY KEY(Code,Code1)
);
else
PRMOPT DefaultTable Already Exist //To print in Console
end if;
Can anyone tell what i am doing wrong? and what all i am doing wrong to write the above query ?
Error starting at line 2 in command:
if(rec=1) then
Error report:
Unknown Command
Error starting at line 3 in command:
CREATE TABLE DefaultTable(
Code INT NOT NULL,
Code1 INT NOT NULL,
ResultCode INT NOT NULL,
CONSTRAINT DefaultTable_PK PRIMARY KEY(Code,Code1)
Error at Command Line:3 Column:14
Error report:
SQL Error: ORA-00955: name is already used by an existing object
00955. 00000 - "name is already used by an existing object"
*Cause:
*Action:
Error starting at line 16 in command:
else
Error report:
Unknown Command
Error starting at line 17 in command:
PRMOPT Table Already Exist
Error report:
Unknown Command
Error starting at line 18 in command:
end if
Error report:
Unknown Command
Well, as I understand the author is trying to do it in one sql query. But in Oracle you can not use IF statement in simple sql. Moreover, even if you use PL/SQL the DDL statements are not allowed to be directly invoked from PL/SQL code, so you should use dynamic SQL. I think, the following script will do what you want:
DECLARE
rec NUMBER;
BEGIN
SELECT COUNT(*) INTO rec FROM all_tables WHERE table_name='DEFAULTTABLE';
IF (rec=0) THEN
EXECUTE IMMEDIATE 'CREATE TABLE DefaultTable(
Code INT NOT NULL,
Code1 INT NOT NULL,
ResultCode INT NOT NULL,
CONSTRAINT DefaultTable_PK
PRIMARY KEY(Code,Code1,ResultCode)
)';
ELSE
dbms_output.put_line('DefaultTable Already Exist');
END IF;
END;
Please, note that in order to see the messages printed via dbms_output, you should execute:
SET SERVEROUTPUT ON;
If you read the error message you will notice it says:
ORA-00955: name is already used by an existing object
This means you are trying to create a table that already exists. That explains why it runs the first time and not any more after that.
Check the entries in all_tables and you will find that Oracle creates tablenames in uppercase. So check for 'DEFAULTTABLE'.

How to install PL/CTL language into PostgreSQL database 8.1.22

Hi I am using postgresql 8.1.22, I am trying to setup postgresql auditing using the following function.
CREATE OR REPLACE FUNCTION audit.if_modified_func() RETURNS TRIGGER AS $body$
DECLARE
v_old_data TEXT;
v_new_data TEXT;
BEGIN
/* If this actually for real auditing (where you need to log EVERY action),
then you would need to use something like dblink or plperl that could log outside the transaction,
regardless of whether the transaction committed or rolled back.
*/
/* This dance with casting the NEW and OLD values to a ROW is not necessary in pg 9.0+ */
IF (TG_OP = 'UPDATE') THEN
v_old_data := ROW(OLD.*);
v_new_data := ROW(NEW.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,original_data,new_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_old_data,v_new_data, current_query());
RETURN NEW;
ELSIF (TG_OP = 'DELETE') THEN
v_old_data := ROW(OLD.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,original_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_old_data, current_query());
RETURN OLD;
ELSIF (TG_OP = 'INSERT') THEN
v_new_data := ROW(NEW.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,new_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_new_data, current_query());
RETURN NEW;
ELSE
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - Other action occurred: %, at %',TG_OP,now();
RETURN NULL;
END IF;
EXCEPTION
WHEN data_exception THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [DATA EXCEPTION] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
WHEN unique_violation THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [UNIQUE] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
WHEN OTHERS THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [OTHER] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
END;
$body$
LANGUAGE plpgsql
SECURITY DEFINER
But if you observe in the above function current_query() is not coming with the mentioned language plpgsql. It throws some error. When I googled I found that in order to use current_query() function PL/CTL language must be installed. I tried to install as mentioned below. It throws an error. So kindly help me how to install PL/CTL language into my database so that current_query() function should work
-bash-3.2$ createlang -d dbname pltcl
createlang: language installation failed: ERROR: could not access file "$libdir/pltcl": No such file or directory
Okay as you suggested I created that current_query() function,but this time I got some thing like this , What i did is ,
CREATE TABLE phonebook(phone VARCHAR(32), firstname VARCHAR(32), lastname VARCHAR(32), address VARCHAR(64));
CREATE TRIGGER phonebook_auditt AFTER INSERT OR UPDATE OR DELETE ON phonebook
FOR EACH ROW EXECUTE PROCEDURE audit.if_modified_func();
INSERT INTO phonebook(phone, firstname, lastname, address) VALUES('9966888200', 'John', 'Doe', 'North America');
for testing the function i created a table named phonebook and created a trigger so that the function mentioned above audit.if_modified_func() will be executed after any insert or update or delete.the row is getting inserted but I am getting a error reg the audit.if_modified_func() function .the error is as follows
WARNING: [AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [OTHER] - SQLSTATE: 42703, SQLERRM: column "*" not found in data type phonebook
Query returned successfully: 1 rows affected, 10 ms execution time.
Kindly tell me what can i do to get rid of the above error.
Not sure where you found the information about current_query and pltcl. These are unrelated. The reason why you can't find pltcl is simply because you're using too old PostgreSQL. current_query() has been added to Pg in version 8.4.
Is there any particular reason why you're using such old version? It is no longer supported, and it lacks almost 8 years of added features!
If you have to use 8.1, you might want to define:
create function current_query() returns text as '
select current_query from pg_stat_activity where procpid = pg_backend_pid();
' language sql;
But it is much better idea just to upgrade.
As for edited and added second question - it's very likely that Pg 8.1 cannot use "row.*" construct. Find who wrote the original code with the "dance comments", and ask about it. Perhaps it was meant to work in newer Pgs.

Resources