Is it possible to use PRAGMA AUTONOMOUS_TRANSACTION in Pro*C? - oracle-pro-c

I've tried to use PRAGMA AUTONOMOUS_TRANSACTION in Pro*C but I get the following error at compile time:
PRAGMA AUTONOMOUS_TRANSACTION;
...........1
PCC-S-02201, Encountered the symbol "AUTONOMOUS_TRANSACTION" when expecting one
of the following:
; into, using,
The relevant section code is:
EXEC SQL EXECUTE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO TABLE_TEST
( FIELD1, FIELD2, FIELD3 )
VALUES
(:sOraFIELD1, :sOraFIELD2, :sOraFIELD3);
COMMIT;
END;
END-EXEC;
What am I doing wrong here? Is it that Pro*C doesn't allow this?
Version: Pro*C/C++: Release 11.2.0.1.0
Do I have an alternative to obtain a similar result? I can't simply do EXEC SQL COMMIT; because then I would get the Oracle error 2089: COMMIT is not allowed in a subordinate session

I never tried this in Pro*c , however please evaluate the concept of alternate connection .
You can insert and commit using an alternate connection.
EXEC SQL AT "DB name" "your statement or in this case" Insert ;
EXEC SQL AT "DB name" "your statement or in this case" Commit;

Related

PLS-00103: Encountered the symbol "CREATE" when expecting one of the

I am trying to create a stored procedure in oracle 12c database and I am getting error when I am running code to store the procedure.
PLS-00103: Encountered the symbol "CREATE" when expecting one of the
There are multiple stack overflow question already asked on this topic. but they suggest some different syntax. which is deviation from actual oracle documentation. and even those didn't worked for me
I checked for documentation on multiple website including oracle documentation. oracle documetation suggest syntax as following
Oracle STORED PROCEDURE DOCUMENTATION
so I as per the syntax I wrote the following procedure.
CREATE PROCEDURE PDD_PROC_BASE
AS
--DROP TABLE BASE;
CREATE TABLE BASE as
SELECT idno
,DATE
,diff
,SUBSTR(idNO,7,2) AS PRD
,COMPLETED
,CATG
,OP_Number
FROM table1
WHERE = date >= '30-JUN-2018'
AND STATUS = 'G'
END;
and I got the following error.
Procedure PDD_PROC_BASE compiled
Errors: check compiler log
Errors for PROCEDURE AN_5043152.PDD_PROC_BASE:
LINE/COL ERROR
-------- ------------------------------------------------------------------------------
7/5 PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
json_exists json_value json_query json_object json_array
I checked other resources as well but still didn't understood what went wrong.
I even tried code example from Oracle documentation and got similar error.
I am using SQLdeveloper tool as client
You cant use directly sql ddl statements in plsql block, you can do the same thing using dynamic sql with the "EXECUTE IMMEDIATE" statement like this:
begin
execute immediate 'create table test_table1 (test_column1 varchar2(40))';--your create table statement here
end;
In Oracle in stored procedures you can use DDL statements only as dynamic SQL, that means as EXECUTE IMMEDIATE 'CREATE TABLE ' ...
Check here, for example: http://www.dba-oracle.com/t_using_ddl_create_index_table_plsql.htm

Oracle: Setting Session Parameters in Packages and Procedures

I'm a SQL Server DBA currently getting up to speed on Oracle. I'm trying to create something very similar to sp_WhoIsActive for SQL Server but for Oracle without reinventing the wheel. Essentially all I'm doing is selecting some values from v$session and inserting them into a table (poor man's ASH/AWR).
It would seem that in Oracle 12.1, there's a bug when querying dictionary views where it can take forever due to bad parsing logic (Bug 22225899 : SLOW PARSE FOR COMPLEX QUERY). The work-around is to set a session parameter:
alter session set "_optimizer_squ_bottomup"=false;
In T-SQL, I could very easily execute a stored procedure in-session and set this variable at runtime. However in Oracle, it wouldn't seem thats the case.
Sample Code:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(
v_temp NUMBER :=1
) IS
BEGIN
alter session set "_optimizer_squ_bottomup"=false;
INSERT INTO SY_DB_ACTIVITY
SELECT
<fields>
FROM
v$session;
commit;
When I run this, I get the error:
"PLS-00103: Encountered symbol 'ALTER' when expecting one of the following..."
Right now, the only way I know how to do this is via a utility like SQL Plus that initiates an interactive user session. Can anyone give me some direction as to how Oracle handles this situation? I'd like to bundle this up into a SP or a Package and then call it from Oracle Scheduler.
Hre is a simple example how to execute alter session inside of the procedure:
CREATE PROCEDURE SP_DB_ACTIVITY IS
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
END;
/
Here is the way you can combine that with your select and insert statement:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
SELECT 1
INTO v_Id
FROM dual;
INSERT INTO SY_DB_ACTIVITY (id) VALUES(v_Id);
END SP_DB_ACTIVITY;
/
Here is a small DEMO where you can see what will procedure do when you call it and how you can call it. Also, in this example you are calling procedure with and IN parameter. So you can use that parameter for something and in the example above is the procedure without any parameters...
You can also, of course, insert into table directly:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
INSERT INTO SY_DB_ACTIVITY(id)
select 1
from dual;
END SP_DB_ACTIVITY;
/

Procedure fails to create executing from Urban Code Deploy

I've run into problems with following script which I'm trying to execute. In SQLDeveloper or other tools like DataGrip, everything works fine, so in my understanding, this is UCD issue.
...more inserts
insert into M_MIGRATION_CONTROL values ('PRODUCTREL', 'M_' || 'PRODUCTREL');
CREATE OR REPLACE PROCEDURE MIGRATE_DATA_BEFORE_DEPLOY IS
TABLE_NAME VARCHAR2(128);
MIGRATION_TABLE_NAME VARCHAR2(128);
CURSOR MIGRATION_CURSOR IS SELECT * FROM M_MIGRATION_CONTROL;
BEGIN
OPEN MIGRATION_CURSOR;
LOOP
FETCH MIGRATION_CURSOR INTO TABLE_NAME, MIGRATION_TABLE_NAME;
EXIT WHEN MIGRATION_CURSOR%NOTFOUND;
EXECUTE IMMEDIATE 'CREATE TABLE '||MIGRATION_TABLE_NAME||' AS SELECT * FROM '||TABLE_NAME||'';
END LOOP;
CLOSE MIGRATION_CURSOR;
END MIGRATE_DATA_BEFORE_DEPLOY;
/
insert into A_ACCEPTEDINCOMETYPEOPTION select * from M_A_ACCEPTEDINCOMETYPEOPTION;
insert into A_INSTALMENT select * from M_A_INSTALMENT;
...more inserts
with errors:
[sql] Failed to execute: MIGRATION_TABLE_NAME VARCHAR2(128)
[sql] java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
[sql] Failed to execute: CURSOR MIGRATION_CURSOR IS SELECT * FROM M_MIGRATION_CONTROL
When I print procedure body from Oracle i get:
PROCEDURE MIGRATE_DATA_BEFORE_DEPLOY IS TABLE_NAME VARCHAR2(128)
So I think that client ends create procedure after first ;
Can you help me/advise me, how should this script look like for correct execution?
(Oracle 12.1)
You are using SQL-JDBC plugin for Urban Code Deploy.
According to their documentation/troubleshooting:
The SQL-JDBC plugin does not support deploying stored procedures.
There is a separate SQL*Plus plugin which you may be able to use instead.

Why inside of a trigger the code before raise_application_error isn't executed?

IF I create this trigger, then the error is raised when drop or truncate is used on tables, but there is nothing inserted into logTable, but if I delete RAISE_APPLICATION_ERROR... then the values are inserted into logTable, but the drop/truncate are executed too. Why? How can I avoid drop/truncate on Schema (If I use instead of trigger, it is fired only if owner of the schema is dropping/truncating something).
CREATE OR REPLACE TRIGGER trigger_name
BEFORE DROP OR TRUNCATE ON DATABASE
DECLARE
username varchar2(100);
BEGIN
IF ora_dict_obj_owner = 'MySchema' THEN
select user INTO username from dual;
INSERT INTO logTable VALUES(username , SYSDATE);
RAISE_APPLICATION_ERROR (-20001,'ERROR, YOU CAN NOT DELETE THIS!!');
END IF;
END;
According to the documentation:
Statement-Level Atomicity
Oracle Database supports statement-level atomicity, which means that a SQL statement is an atomic unit of work
and either completely succeeds or completely fails.
A successful statement is different from a committed transaction. A
single SQL statement executes successfully if the database parses and
runs it without error as an atomic unit, as when all rows are changed
in a multirow update.
If a SQL statement causes an error during execution, then it is not
successful and so all effects of the statement are rolled back. This
operation is a statement-level rollback.
The procedure is a PL/SQL statement, it is atomic, if you raise an error within the procedure, then the whole procedure fails and Oracle performs a rollback of all the changes done by this procedure.
But you can create a procedure with AUTONOMOUS_TRANSACTION Pragma in order to bypass this behaviour, in this way:
CREATE TABLE logtable(
username varchar2(200),
log_date date
);
CREATE OR REPLACE PROCEDURE log_message( username varchar2 ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO logtable( username, log_date ) VALUES ( username, sysdate );
COMMIT;
END;
/
CREATE OR REPLACE TRIGGER trigger_name
BEFORE DROP OR TRUNCATE ON DATABASE
DECLARE
username varchar2(100);
BEGIN
IF ora_dict_obj_owner = 'TEST' THEN
log_message( user );
RAISE_APPLICATION_ERROR (-20001,'ERROR, YOU CAN NOT DELETE THIS!!');
END IF;
END;
And now:
drop table table1;
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: ERROR, YOU CAN NOT DELETE THIS!!
ORA-06512: at line 6
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
can be corrected, do so; otherwise contact Oracle Support.
select * from logtable;
USERNAME LOG_DATE
-------- -------------------
TEST 2018-04-27 00:16:34

Can't alter password

I am trying to alter the password of a user in plsql:
DECLARE
BEGIN
ALTER USER BOB IDENTIFIED BY PASS123;
END;
I keep getting the error when I create it and cannot make it out what it wrong:
ORA-06550: line 4, column 1: PLS-00103: Encountered the symbol "ALTER"
when expecting one of the following: ( begin case declare exit for
goto if loop mod null pragma raise return select update while with
<< continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
According to doc
Only dynamic SQL can execute the following types of statements within
PL/SQL program units:
Data definition language (DDL) statements such as CREATE, DROP, GRANT,
and REVOKE
Session control language (SCL) statements such as ALTER SESSION and
SET ROLE
The TABLE clause in the SELECT statem
DECLARE
BEGIN
EXECUTE IMMEDIATE 'ALTER USER BOB IDENTIFIED BY PASS123';
END;
You can use DDL statements (alter, create, grant etc) without begin-end block.
ALTER USER BOB IDENTIFIED BY PASS123;