SQL Error: ERROR: not all tokens processed - postgresql

Am getting below error in Postgres while executing insert and delete queries. I have around 50 inserts and 50 delete statements. When executed an getting the error as,
SQL Error: ERROR: not all tokens processed
The error is not consistent all the time,
For example,
My 20th delete statement is getting failed
Next time when the same queries are executed, 25th delete statement is getting failed
And when those statements are executed alone, there is no failure.
Not sure if it is a database load issue or infrastructure related issue.
Any suggestion would be helpful
Below is the query,
WITH del_table_1 AS
(
delete from table_1 where to_date('01-'||col1,'DD-mm-YYYY') < current_date-1
RETURNING *
)
update control_table set deleted_count = cnt, status = 'Completed',
update_user_id = 'User', update_datetime = current_date from
(select 'Table1' as table_name, count(*) as cnt from del_table_1) aa
where
control_table.table_name = aa.table_name
and control_table.table_name = 'Table1'
and control_table.status = 'Pending';

Related

Creating anonymous block on Postgres to update rows

I ran this anonymous block on Postgres and got this error:
DO
$$BEGIN
FOR diag_file IN
SELECT d_file.diagnostic_file_id AS diagnostic_file_id,
controller.controller_id AS controller_id
FROM diagnostic_file d_file
JOIN decoder_mapping d_mapping ON d_mapping.decoder_mapping_id = d_file.decoder_mapping_id
JOIN device_model d_model ON d_model.device_model_id = d_mapping.device_model_id
JOIN controller ON controller.device_model_id = d_model.device_model_id
WHERE d_file.controller_id IS NULL
LOOP
UPDATE diagnostic_file SET controller_id = diag_file.controller_id WHERE diagnostic_file.diagnostic_file_id = diag_file.diagnostic_file_id;
COMMIT;
END LOOP;
END;$$;
An It returns me this error:
WARNING: there is no transaction in progress
Query 1 OK: COMMIT
An It returns me this error:
WARNING: there is no transaction in progress
Not an error, a warning. You tried to commit, but there's no transaction.
Often this happens when you've turned on autocommit and then commit. It's warning you that the commit does nothing.
Your loop should not work at all in PostgreSQL 9.5, you can't begin nor end transactions inside PL/pgSQL in that version. THat is not introduced until PostgreSQL 11.
ERROR: cannot begin/end transactions in PL/pgSQL
HINT: Use a BEGIN block with an EXCEPTION clause instead.
CONTEXT: PL/pgSQL function inline_code_block line 11 at SQL statement
If you're writing a loop in SQL, you can probably do it easier and faster without the loop. In this case with an update from a sub-select.
update diagnostic_file set controller_id = diag_file.controller_id
from (
SELECT d_file.diagnostic_file_id AS diagnostic_file_id,
controller.controller_id AS controller_id
FROM diagnostic_file d_file
JOIN decoder_mapping d_mapping ON d_mapping.decoder_mapping_id = d_file.decoder_mapping_id
JOIN device_model d_model ON d_model.device_model_id = d_mapping.device_model_id
JOIN controller ON controller.device_model_id = d_model.device_model_id
WHERE d_file.controller_id IS NULL
) diag_file
WHERE diagnostic_file.diagnostic_file_id = diag_file.diagnostic_file_id
The update docs have many examples.

Delete duplicate records in Postgres , ctid does not exist

I have a table with duplicate records.
Upon googling, I stumbled upon this one: How to delete duplicate rows without unique identifier.
So I followed the solution to use the ctid.
However, running it returns an error for me:
SQL Error [42703]: ERROR: column "ctid" does not exist in t2
this is the code I ran:
update my_schema.my_table
set control_flag = 'deleted'
where customer_id = 'A001'
and date between '2019-10-30' and '2020-09-29'
and mrr = 69
and exists (select ctid, 1
from my_schema.my_table t2
where t2.gateway_id = my_schema.my_table.gateway_id and
t2.gateway_item_id = my_schema.my_table.gateway_item_id and
t2.customer_id = my_schema.my_table.customer_id and
t2.mrr = my_schema.my_table.mrr and
t2.date = my_schema.my_table.date and
t2.ctid > my_schema.my_table.ctid
);

Get postgres query log statement and duration as one record

I have log_min_duration_statement=0 in config.
When I check log file, sql statement and duration are saved into different rows.
(Not sure what I have wrong, but statement and duration are not saved together as this answer points)
As I understand session_line_num for duration record always equals to session_line_num + 1 for relevant statement, for same session of course.
Is this correct? is below query reliable to correctly get statement with duration in one row?
(csv log imported into postgres_log table):
WITH
sql_cte AS(
SELECT session_id, session_line_num, message AS sql_statement
FROM postgres_log
WHERE
message LIKE 'statement%'
)
,durat_cte AS (
SELECT session_id, session_line_num, message AS duration
FROM postgres_log
WHERE
message LIKE 'duration%'
)
SELECT
t1.session_id,
t1.session_line_num,
t1.sql_statement,
t2.duration
FROM sql_cte t1
LEFT JOIN durat_cte t2
ON t1.session_id = t2.session_id AND t1.session_line_num + 1 = t2.session_line_num;

TSQL OUTPUT clause in MERGE statement raise Msg 596 "Cannot continue the execution because the session is in the kill state"

I wrote T-SQL MERGE query to merge staging data into a data warehouse (you can find it at the bottom).
If I uncomment the OUTPUT statement the I get error mentioned in the title.
However, if I do not include it, everything works perfectly fine and MERGE succeeds.
I know that there are some issue connected to the MERGE clause, however there are more connected to the type of merge.
I checked the following answer: [https://dba.stackexchange.com/questions/140880/why-does-this-merge-statement-cause-the-session-to-be-killed], however in my execution plan I cannot find exactly index insert followed by index merge.
Rather, what I see is the following execution plan
Code was developed on database attached to SQL Server 2012 (SP4) instance
I would really appreciate good explanation of this problem, ideally referencing steps from my execution plan.
Thank you.
declare #changes table (chgType varchar(50),Id varchar(18))
begin try
set xact_abort on
begin tran
;with TargetUserLogHsh as (select
hsh =hashbytes('md5',concat(coalesce([AccountName],'')
,coalesce([TaxNumber],'')))
,LastLoginCast = coalesce(CONVERT(datetime,LastLogin,103),getdate())
,* from
dw.table1)
,SourceUserLogHsh as (select
hsh =hashbytes('md5',concat(coalesce([AccountName],'')
,coalesce([TaxNumber],'')))
,LastLoginCast = coalesce(CONVERT(datetime,LastLogin,103),getdate())
,* from
sta.table1)
merge TargetUserLogHsh target
using SourceUserLogHsh source
on target.ContactId = source.ContactId and target.Lastlogincast >= source.LastLoginCast
when not matched then insert (
[AccountName]
,[TaxNumber]
,[LastLogin]
)
values (
source.[AccountName]
,source.[TaxNumber]
,source.[LastLogin]
)
when matched and target.lastlogincast = source.lastlogincast
and target.hsh != source.hsh then
update
set
[AccountName] = source.[AccountName]
,[TaxNumber] = source.[TaxNumber]
,[LastLogin] = source.[LastLogin]
output $action,inserted.contactid into #changes
;
commit tran
end try
begin catch
if ##TRANCOUNT > 0 rollback tran
select ERROR_MESSAGE()
end catch

group by error with postgres and pomm orm

I want to execute the following SQL query :
SELECT date, COUNT(id_customers)
FROM event
WHERE event_id = 3
GROUP BY date
When I try this query in my database, it works perfectly. But in my code I get an error which I can't resolve.
I use symfony2 with the orm pomm. It's Postgresql.
Here is my code :
$sql = "SELECT e.date, COUNT(id_customers) FROM event e WHERE event_id = $* GROUP BY e.date";
return $this->query($sql, [$eventId])->extract();
Here is the error :
request.CRITICAL: Uncaught PHP Exception InvalidArgumentException:
"No such field 'id'. Existing fields are {date, count}"
at /home/vagrant/sourcefiles/vendor/pomm-project/model-manager/sources/lib/Model/FlexibleEntity/FlexibleContainer.php line 64
{"exception":" [object] (InvalidArgumentException(code: 0): No such field 'id'.
Existing fields are {date, count}
at /home/vagrant/sourcefiles/vendor/pomm-project/model-manager/sources/lib/Model/FlexibleEntity/FlexibleContainer.php:64)"} []
So I tried to had the id in my select, by I get this error :
request.CRITICAL: Uncaught PHP Exception
PommProject\Foundation\Exception\SqlException: "
SQL error state '42803' [ERROR] ==== ERROR: column "e.id" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT e.id, e.date, COUNT(id_customers) FROM event e WHERE ... ^
==== «PREPARE === SELECT e.id, e.date, COUNT(id_customers) FROM event e WHERE event_id = $1 GROUP BY e.date ===»." at /home/vagrant/sourcefiles/vendor/pomm-project/foundation/sources/lib/Session/Connection.php line 327 {"exception":"[object] (PommProject\Foundation\Exception\SqlException(code: 0): \nSQL error state '42803' [ERROR]\n====\nERROR: column \"e.id\" must appear in the GROUP BY clause or be used in an aggregate function\nLINE 1: SELECT e.id, e.date, COUNT(id_customers) FROM event e WHERE ...\n ^\n\n====\n«PREPARE ===\nSELECT e.id, e.date, COUNT(id_customers) FROM event e WHERE event_id = $1 GROUP BY e.date\n ===». at /home/vagrant/sourcefiles/vendor/pomm-project/foundation/sources/lib/Session/Connection.php:327)"} []
The only thing that works is when I had the id in the group by, but this is not the result I want.
Someone can explain me why this is working in the database and not in the php ?
this is because you are fetching flexible entities without their primary key. There is an identity mapper behind the scene that ensure fetching twice the same entity will return the same instance.
In this case, you do not need to fetch entities (hence the extract after the query). So you can just use the QueryManager pooler to return converted arrays like the following:
$sql = "SELECT e.date, COUNT(id_customers) FROM event e WHERE event_id = $* GROUP BY e.date";
// Return an iterator that fetches converted arrays on demand:
return $this
->getSession()
->getQueryManager()
->query($sql, [$eventId])
;
i think its because the alias,
try this
$sql = "SELECT e.date, COUNT(e.id_customers) FROM event e WHERE event_id = $* GROUP BY e.date";
return $this->query($sql, [$eventId])->extract();
This is exactly how GROUP BY works in PostgreSQL:
When GROUP BY is present, it is not valid for the SELECT list
expressions to refer to ungrouped columns except within aggregate
functions, since there would be more than one possible value to return
for an ungrouped column.
It means that each field in your query either must be present in GROUP BY statement or handled by any of the aggregation functions. This is one of the differences between GROUP BY in MySQL and PostreSQL.
In other words you can add id at GROUP BY statement and do not worry about it ;)