Unable to convert the trigger from Oracle to PostgreSQL - postgresql

I'm trying to convert the below trigger which is written Oracle to PostgreSQL:
create or replace TRIGGER "SCHEMA1".table1_ta
after delete
on table1
for each row
begin
if :old.hid = 0 or :old.hid = -1
then
err.raise(-12345, 'Error Message');
end if;
end table1_ta;
Below is the code which is getting generated as part of the schema conversion process of the AWS Schema Conversion Tool (SCT) but getting an error when I'm trying to apply it to the target PostgreSQL database.
CREATE TRIGGER table1_ta
AFTER DELETE
ON schema1.table1
FOR EACH ROW
EXECUTE PROCEDURE schema1.table1_ta$table();
Below is the error that I'm getting when AWS SCT is trying to create this trigger:
ERROR: function schema1.table1_ta$table(); does not exists.
How can I fix this?

Related

create table-space in PostgreSQL 12 by passing a string value. how to go about passing values to creating table-space using my custom values?

When I run the command below in PostgreSQL
CREATE TABLESPACE 'forex_eurusd_2020_07'
OWNER 'forex'
LOCATION 'f:\data\forex\eurusd\2020_07';
I get the following error.
ERROR: syntax error at or near "'forex_eurusd_2020_07'"
LINE 3: CREATE TABLESPACE 'forex_eurusd_2020_07'
^
SQL state: 42601
Character: 21
What I am trying to do here is to create table-space and later partition by passing the values in my function as string .
Though this is my test statement
Here is something else I tried below
do $$
declare
tbl_spc varchar(50) := 'forex_eurusd_2020_07';
forex_owner varchar(10) :='forex';
begin
CREATE TABLESPACE tbl_spc
OWNER forex_owner
LOCATION 'f:\data\forex\eurusd\2020_07';
end $$;
And got the following result
ERROR: CREATE TABLESPACE cannot be executed from a function
CONTEXT: SQL statement "CREATE TABLESPACE tbl_spc
OWNER forex_owner
LOCATION 'f:\data\forex\eurusd\2020_07'"
PL/pgSQL function inline_code_block line 6 at SQL statement
SQL state: 25001
In the end I am open to suggestions on how to go about passing values to creating table-space using my custom values?
'forex_eurusd_2020_07' is an identifier so it needs to be double quoted(same with OWNER name). quote_ident(string text)(Docs) is your friend. So:
quote_ident('forex_eurusd_2020_07')
The function issue is explained by the error:
ERROR: CREATE TABLESPACE cannot be executed from a function
That is because Tablespace:
"CREATE TABLESPACE cannot be executed inside a transaction block."
And a function runs inside a transaction block. So you can't use a function for this.
I found the solution by using python. As I was using python to get data which I was trying to post in a partitioned table with its own table-space. I was facing issues dynamically creating the table-space. Which I have achieved by writing the following in my code. I used the code given to create table, instead of table, I modified to create the table-space.
connection = psycopg2.connect(user="forex",
password="MXXXXXX#XXXX",
host="127.0.0.1",
port="5432",
database="MyDB")
connection.autocommit = True
cursor = connection.cursor()
tbl_spc = 'forex_eurusd_2020_07'
forex_owner = 'forex'
location_tbl_spc = "'f:\\data\\forex\\eurusd\\2020_07'"
print(location_tbl_spc)
create_tbl_spc_query = ''' CREATE TABLESPACE '''+tbl_spc+'''
OWNER '''+forex_owner+'''
LOCATION '''+location_tbl_spc+''';'''
print(create_tbl_spc_query)
cursor.execute(create_tbl_spc_query)
connection.commit()
print("Table-space created successfully in PostgreSQL ")
except (Exception, psycopg2.Error) as error:
print("Error while creating PostgreSQL table-space", error)
finally:
closing database connection.
if (connection):
cursor.close()
connection.close()
print("PostgreSQL connection is closed")

PostgreSQL: Creating a Trigger that tries to do work on a non existing table

as we start to migrate our Application from using Oracle to PostgreSQL we ran into the following problem:
A lot of our Oracle scripts create triggers that work on Oracle specific tables which dont exist in PostgreSQL. When running these scripts on the PG database they will not throw an error.
Only when the trigger is triggered an error is thrown.
Example code:
-- Invalid query under PostgreSQL
select * from v$mystat;
-- Create a view with the invalid query does not work (as expected)
create or replace view Invalid_View as
select * from v$mystat;
-- Create a test table
create table aaa_test_table (test timestamp);
-- Create a trigger with the invalid query does(!) work (not as expected)
create or replace trigger Invalid_Trigger
before insert
on aaa_test_table
begin
select * from v$mystat;
end;
-- Insert fails if the trigger exists
insert into aaa_test_table (test) values(sysdate);
-- Select from the test table
select * from aaa_test_table
order by test desc;
Is there a way to change this behavior to throw an error on trigger creation instead?
Kind Regards,
Hammerfels
Edit:
I was made aware, that we actually dont use basic PostgreSQL but EDB instead.
That would probably explain why the syntax for create trigger seems wrong.
I'm sorry for the confusion.
It will trigger an error, unless you have configured Postgres to postpone validation when creating functions.
Try issuing this before creating the trigger:
set check_function_bodies = on;
Creating the trigger should show
ERROR: syntax error at or near "trigger"
LINE 1: create or replace trigger Invalid_Trigger

PostgreSQL: skip erros in SQL clients using JDBC

I want to execute a SQL script in a client using JDBC (not the postgreSQL pslq client). In this script I would like to do something like that:
skip errors on;
alter table foo ...;
skip errors off;
Is there a way to do this with PostgreSQL >= 9.1?
I found this thread with a good solution usind DO blocks and error codes:
How to continue sql script on error?
And creating a function for my problem:
create or replace function continueOnError(v_sqlStatement text)
returns void
language plpgsql
as '
BEGIN
execute v_sqlStatement;
EXCEPTION
WHEN invalid_schema_name
OR undefined_table
OR undefined_column
THEN RAISE WARNING ''Continued on error sql statement: %'', v_sqlStatement;
END;
';
...use it:
select continueOnError('alter table test add constraint fk_test_valueid foreign key (valueid) references value(id)');

PostgreSQL Delete Trigger

I´m creating a trigger on PGAdminIII where I want to delete the rows that have the foreign key on the other table. However I´m getting a Syntax error and I can´t find where the problem is:
CREATE TRIGGER clienteDelete
BEFORE DELETE ON cliente
FOR EACH ROW
BEGIN
DELETE FROM contacto WHERE contacto.id = OLD.contacto_idcontacto;
END;
ERROR: syntax error at or near "BEGIN"
LINE 4: BEGIN
^
********** Error **********
ERROR: syntax error at or near "BEGIN"
SQL state: 42601
Character: 68
I´m not used to the syntax of triggers on Postgres but that´s what I know according to the SQL standard. Any help will be highly apreciated
So Postgresql triggers has some limitations, for instance
PostgreSQL only allows the execution of a user-defined function for
the triggered action.
So to accomplish what you want you need to define a function and make the trigger fire that. Something like this should work:
CREATE FUNCTION clienteDelete() RETURNS TRIGGER AS $_$
BEGIN
DELETE FROM contacto WHERE contacto.id = OLD.contacto_idcontacto;
RETURN OLD;
END $_$ LANGUAGE 'plpgsql';
And the trigger:
CREATE TRIGGER delete_contacto
BEFORE DELETE ON cliente
FOR EACH ROW
EXECUTE PROCEDURE clienteDelete();
I'm no Postgresql expert though so expect the code above to not be perfect.

Postgres trigger syntax

Using SQLFiddle, PostgreSQL 9.3.1.
I am learning to define triggers in PostgreSQL, and after doing some research I've found out the following:
Triggers in Postgres are different from MYSQL. Where in Postgres you must create a function that RETURNS TRIGGER, in MySQL you can just create a trigger. So this is what I've come up with:
On Employee Insert, we want to update Departments Total Salary.
CREATE FUNCTION update_sal() RETURNS TRIGGER AS $$
BEGIN
IF NEW.dno IS NOT NULL THEN
UPDATE Department SET Total_sal = total_sal + NEW.salary
WHERE department.dno = NEW.dno;
END IF;
RETURN NULL;
END;
$$ Language plpgsql;
CREATE TRIGGER updateInsert
AFTER INSERT ON Employee
FOR EACH ROW
EXECUTE PROCEDURE update_sal();
And I'm getting the following error:
Schema Creation Failed: ERROR: unterminated dollar-quoted string at or near "$$
BEGIN IF NEW.dno IS NOT NULL THEN UPDATE Department
SET Total_sal = total_sal +NEW.salary WHERE department.dno = NEW.dno":
I've solved the issue thanks to Database Function giving an error - Postgresql
It seems just changing the query terminator at the bottom of the Scheme Window solves this issue.
If you copy-pasted the code, then you've got a simple syntax error: ENDl should be END; in the last-but-one line of the function definition.
Otherwise, it looks good to me.