PGAgent - Scheduling a job to drop my old partitions - postgresql

I have a script below which is running fine when i'm executing directly via PGAdmin however when i schedule it to run using PGAgent though, it's showing successful but my partitions were still untouched.
Below is the PostgreSQL version our company is currently using.
"PostgreSQL 14.2 (EnterpriseDB Advanced Server 14.2.1) on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1), 64-bit"
DECLARE
TYPE tbl_arr IS VARRAY(5) OF VARCHAR2(30);
partncnt INTEGER;
drop_sql varchar2(500);
tbnames tbl_arr;
t_partition_name user_tab_partitions.partition_name%TYPE;
BEGIN
tbnames := tbl_arr('MYTABLE');
FOR i IN 1..1 LOOP
select count(1) into partncnt from user_tab_partitions where table_name=tbnames(i);
IF (partncnt) > 7 THEN
select partition_name into t_partition_name from user_tab_partitions where table_name=tbnames(i) and partition_position=2;
drop_sql := 'alter table '|| tbnames(i) ||' drop partition ' || t_partition_name;
execute immediate drop_sql;
ELSE
DBMS_OUTPUT.PUT_LINE('No Partition to drop');
END IF;
END LOOP;
END;
Checking on it's last run you can see that it's running successfully:
screenshot of successful ran job

Manage to find the root cause apparently for postgres you will need to ensure that PGAgent is running for the user/schema. As soon as we had it running., the job were been executed successfully base on the interval i've set.

Related

I got error when trying to run docker-compose up --build. And i got an error in my sql seed data

I got this error while trying to run docker-compose up --build, I'm using postgresql as my database service. I think there's wrong with my query.When i remove the CREATE TRIGGER it somehow run without erros.
LINE 13: CREATE TRIGGER update_communication
backend-postgres-1 |^
Here is my sql file
CREATE OR REPLACE FUNCTION dts.save_communication_revision()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
INSERT INTO dts.communication_revisions(com_id, class_id, com_subject, user_id, com_source_name, "com_dateCreated", "com_dateReceived", com_urgency, com_source_position, com_source_office, com_draft, com_other_remarks, "com_controlNo", com_due_date)
VALUES(OLD.com_id, OLD.class_id, OLD.com_subject, OLD.user_id, OLD.com_source_name, OLD."com_dateCreated", OLD."com_dateReceived", OLD.com_urgency, OLD.com_source_position, OLD.com_source_office, OLD.com_draft, OLD.com_other_remarks, OLD."com_controlNo", OLD.com_due_date);
END;
$$
CREATE TRIGGER update_communication
AFTER UPDATE
ON dts.communications
FOR EACH ROW
EXECUTE PROCEDURE dts.save_communication_revision();
END;
$$;
Just added this semicolon.

How to create a function in PostgreSQL like SQL Server BACKUP DATABASE TO DISK

I'm trying without success to create a function in Postgres that save a table or database taking one or two parameters. In this case I was trying to create it with only one parameter(name of the table or database) and backup this table/db
--SELECT backup_table(sports)
CREATE FUNCTION backup_table(TEXT) RETURNS BOOLEAN AS
$$
DECLARE
table_x ALIAS FOR $1;
BEGIN
COPY table_x FROM 'C:/path/backup_db' WITH (FORMAT CSV);
RAISE NOTICE 'Saved correctly the table %',$1;
RETURN BOOLEAN;
END;
$$ LANGUAGE plpgsql;
I've always receive the error when I try to execute the function SELECT backup_table(sports):
"The column sports doesnt exists."
SQL state: 42703
Character: 21
The idea is to create the function like the equivalent of SQL Server BACKUP DATABASE TO DISK, or equivalent to pg_dump command
pg_dump -U -W -F t sports > C:/path/backup_db;
I know about SQL but now I'm just stuck with this error.

Writing a for-loop using psql

I am trying to run a for loop via psql command in Linux to do some spatial operations in PostGIS database
My SQL command which I successfully ran in dbeaver looks something like this
DO $$
declare
the_name varchar(50);
BEGIN
FOR the_name IN
SELECT "name" FROM myschema.mytable WHERE "idcolumn" = 'selected id' LIMIT 4
LOOP
some operations inside the loop...
END LOOP;
RAISE NOTICE 'the name - (%)', the_name;
END;
$$;
I usually copy-paste the dbeaver SQL command inside psql -c and it runs fine. But I am getting a syntax error when using the above code. I am a beginner in SQL and any help is appreciated. Thanks.
Edit
This is the error message - it's weird because I don't have this number in the code. It's probably reading from memory or something.
ERROR: syntax error at or near "377643"
LINE 1: DO 377643 declare the_name varchar(50); BEGIN FOR the_...

Catch Block for Insert Trigger Not Firing for Error Launching SSA Job

I'm setting up an AFTER INSERT trigger to launch an SSA job which executes a SSIS package to report on an ETL log file after its process completes. The syntax for the TRY...CATCH block appears correct but the error handling doesn't work for the error code when it detects the SSA job it's told to launch is already running.
The trigger is for a user table in a SQL Server 2012 SP4 instance (with SQL 2012 (110) compatibility). I tried handling the one error (#22022) for a SQL job already running but it seems that you can't error trap the execution of a system stored procedure.
CREATE TRIGGER InterfaceSupport.trg_XMLTrigger_Insert
ON [InterfaceSupport].[XMLLogReaderTriggers]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
EXEC msdb.dbo.sp_start_job 'Launch job'
END TRY
BEGIN CATCH
IF ERROR_NUMBER()=22022 --Job already running
EXEC msdb.dbo.sp_send_dbmail NULL,'name#domain.org',NULL,NULL,'Interface XML Log Reader Already Running','The SSA Job reading Interface logs is already running. The job will attempt to catch the new request at the end of the current cycle.'
ELSE
BEGIN
DECLARE #Errormsg nvarchar(max)
SELECT #Errormsg=ERROR_MESSAGE()
EXEC msdb.dbo.sp_send_dbmail NULL,'name#domain.org',NULL,NULL,'Interface XML Log Reader Spawn Error',#Errormsg
END
END CATCH
END
GO
I'm getting the following error despite the error handling block. It's as if the CATCH block is non-existent.
Msg 22022, LeveSQLServerAgent Error: Request to run job Launch Job (from User xxx) refused because the job is already running from a request by User xxx. l 16, State 1, Line 17
This error can't be caught by TRY/CATCH unfortunately.
You should check if the job is running and start only if it's not, although the job might start in between the check and the EXEC statement.
DECLARE #JobID UNIQUEIDENTIFIER = (SELECT job_id FROM msdb.dbo.sysjobs AS J WHERE J.name = 'Launch job')
IF NOT EXISTS (
SELECT
'job is running'
FROM
msdb.dbo.sysjobactivity ja
INNER JOIN msdb.dbo.sysjobs j ON ja.job_id = j.job_id
WHERE
ja.session_id = (SELECT TOP 1 session_id FROM msdb.dbo.syssessions ORDER BY agent_start_date DESC) AND
ja.start_execution_date is not null AND
ja.stop_execution_date is null AND
ja.job_id = #JobID
)
BEGIN
EXEC msdb.dbo.sp_start_job #job_name = 'Launch job'
END
ELSE
BEGIN
EXEC msdb.dbo.sp_send_dbmail NULL,'name#domain.org',NULL,NULL,'Interface XML Log Reader Already Running','The SSA Job reading Interface logs is already running. The job will attempt to catch the new request at the end of the current cycle.'
END

How to log an error into a Table from SQLPLus

I am very new to Oracle so please base with me if this is covered else where.
I have a MS SQL box running Jobs calling batch files running scripts in SQLPLUS to ETL to an Oracle 10G database.
I have an intermittent issue with a script that is causing the ETL to fail which at the minute without error logging is something of an unknown. The current solution highlights the load failure based on rowcounts for before and after the script has finsihed.
I'd like to be able to insert any errors encoutered whilst running the offending script into an error log table on the same database receiving the data loads.
There's nothing too technical about the script, at a high level is performs the following steps all via SQL code and no procedural calls.
Updates a table with Date and current row counts
Pulls data from a remote source into a staging table
Merges the Staging table into an intermediate staging table
Performs some transformational actions
Merges the intermediate staging table into the final Fact table
Updates a table with new row counts
Please advise whether it is possible to pass error messages, codes, line number etc etc via SQLPLUS into a Database table? and if so the easiest method to achieve this.
A first few lines of the script are shown below to give a flavour
/*set echo off*/
set heading off
set feedback off
set sqlblanklines on
/* ID 1 BATCH START TIME */
INSERT INTO CITSDMI.CITSD_TIMETABLE_ORDERLINE TGT
(TGT.BATCH_START_TIME)
(SELECT SYSDATE FROM DUAL);
COMMIT;
insert into CITSDMI.CITSD_TIMETABLE_ALL_LOADS
(LOAD_NAME, LOAD_CRITICALITY,LOAD_TYPE,BATCH_START_TIME)
values
('ORDERLINE','HIGH','SMART',(SELECT SYSDATE FROM DUAL));
commit;
/* Clear the Staging Tables */
TRUNCATE TABLE STAGE_SMART_ORDERLINE;
Commit;
TRUNCATE TABLE TRANSF_FACT_ORDERLINE;
Commit;
and so it goes on with the rest of the steps.
Any assistant will be greatly appreciated.
Whilst not fully understanding your requirement, a couple of pointers.
The WHENEVER command will help you control what sqlplus should do when an error occurs, e.g.
WHENEVER SQLERROR EXIT FAILURE ROLLBACK
WHENEVER OSERROR EXIT FAILURE ROLLBACK
INSERT ...
INSERT ...
This will cause sqlplus to exit with error status 1 if any of the following statements fail.
You can also have WHENEVER SQLERROR CONTINUE ...
Since the WHENEVER ... EXIT FAILURE/SUCCESS controls the exit status, the calling script/program will know if it worked failed.
Logging
use SPOOL to spool the out to a file.
Logging to table.
Best way is to wrap your statements into PLSQL anonymous blocks and use exception hanlders to log errors.
So, putting the above together, using a UNIX shell as the invoker:
sqlplus -S /nolog <<EOF
WHENEVER SQLERROR EXIT FAILURE ROLLBACK
CONNECT ${USRPWD}
SPOOL ${SPLFILE}
BEGIN
INSERT INTO the_table ( c1, c1 ) VALUES ( '${V1}', '${V2}' );
EXCEPTION
WHEN OTHERS THEN
INSERT INTO the_error_tab ( name, errno, errm ) VALUES ( 'the_script', SQLCODE, SQLERRM );
COMMIT;
END;
/
SPOOL OFF
QUIT
EOF
if [ ${?} -eq 0 ]
then
echo "Success!"
else
echo "Oh dear!! See ${SPLFILE}"
fi