Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

truncate and insert within procedure don't work together

I need to do truncate table and then insert data in that table using procedure.

However, one does like dinamic sql but the other one doesn't:

create or replace 
procedure   RECREATE_AGGREGATE
AUTHID DEFINER
AS
BEGIN
    TRUNCATE TABLE AGGREGATE;    
    INSERT INTO AGGREGATE SELECT * FROM OLD_AGGREGATE;
END;

Error(6,14): PLS-00103: Encountered the symbol "TABLE" when expecting one of the following: := . ( @ % ; The symbol ":= was inserted before "TABLE" to continue.

If I add execute immediate around TRUNCATE statement, it works fine, but insert is erroring out. If I remove it, TRUNCATE TABLE complains...

create or replace 
    procedure   RECREATE_AGGREGATE
    AUTHID DEFINER
    AS
    BEGIN
        execute immediate 'TRUNCATE TABLE AGGREGATE';    
        INSERT INTO AGGREGATE SELECT * FROM OLD_AGGREGATE;
    END;

Error(7,5): PL/SQL: SQL Statement ignored Error(7,84): PL/SQL: ORA-00942: table or view does not exist

Can some shed some light here?

like image 972
Angelina Avatar asked Feb 24 '14 18:02

Angelina


People also ask

What are the restriction while using TRUNCATE?

The TRUNCATE statement fails if any of the following conditions exist: The user does not hold the Delete access privilege on the table. The table has an enabled Delete trigger, but the user lacks the Alter privilege. The specified table or synonym does not exist in the local database.

Can TRUNCATE be used in stored procedure?

The goal of the TRUNCATE TABLE statement is to remove all records from a table. Since this is not possible in a partitioned stored procedure, VoltDB does not allow TRUNCATE TABLE statements within partitioned stored procedures. You can perform TRUNCATE TABLE statements in ad hoc or multi-partition procedures only.

What is TRUNCATE insert?

The DELETE statement removes rows one at a time and inserts an entry in the transaction log for each removed row. On the other hand, the TRUNCATE TABLE statement deletes the data by deallocating the data pages used to store the table data and inserts only the page deallocations in the transaction logs.

Can we use TRUNCATE inside trigger?

TRUNCATE is a DDL statement and will not cause the trigger to fire even if present for the table. before or after truncate statements in trigger is used for a schema and not on a specific table. TRUNCATE removes all rows from a table. The operation cannot be rolled back and no triggers will be fired.


1 Answers

create or replace 
procedure   RECREATE_AGGREGATE
AUTHID DEFINER
AS
BEGIN
    EXECUTE IMMEDIATE 'TRUNCATE TABLE AGGREGATE';    
    INSERT INTO AGGREGATE SELECT * FROM OLD_AGGREGATE;
END;

will work assuming that you have appropriate privileges.

Based on your edit (and echoing @OracleUser's comment), you're likely getting an error running your INSERT statement because old_aggregate is owned by another user and you only have SELECT privileges on that table via a role. If you want to do something in a definer's rights stored procedure, you'll need to have those privileges granted directly to you (or be using 12c which lets you grant privileges to blocks of code rather than to users).

Assuming you want to use a definer's rights stored procedure, you'd need the owner of old_aggregate (or the DBA) to

GRANT SELECT 
   ON old_user.old_aggregate
   TO new_user;

You can verify that you only have the privilege via a role by disabling roles for the session. I'll wager that if you do

SQL> set role none;
SQL> SELECT * FROM old_aggregate

that you'll get an ORA-00942 error as well. This is a good way of simulating what privileges will be available to the user inside a definer's rights stored procedure.

like image 90
Justin Cave Avatar answered Oct 01 '22 18:10

Justin Cave