I have a table fepu00 and trigger on it.
The part of code causing tha problem looks like follows:
if (old_record.potime = NEW.putime --new AP (read in statement above)
or old_record.pupisb::NUMERIC != NEW.pupisb::NUMERIC) then
insert into dl356_table
values (old_record.poid, old_record.poidma, old_record.ponmaf,
old_record.adstr, old_record.adpsc, old_record.adcit, old_record.adidze,
NEW.pupisb::numeric,
case when old_record.potime = NEW.putime then '1' else '2' end,
NEW.putime);
end if;
The query I'm executing is really simple:
update fepu00 set pudas = ? where puid = ?
It works, but only for some quantity of times. Then it throws:
ERROR: type of parameter 25 (numeric) does not match that when preparing the plan (text)
Where: PL/pgSQL function dl356_trigger() line 75 at IF
Number of updated records varies from a few to a few hundreds.
When I run the same query (with the same parameters) again, it works properly until the next fail.
Thanks for any suggestions.
Related
In my trigger I want to throw an exeption, but it is not working properly, got exception. Using DB2 LUW
{0:0} An unexpected token "SQLSTATE '1234'" was found following "
SIGNAL". Expected tokens may include: "<space>".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.28.11
CREATE OR REPLACE TRIGGER "TRG_ABC_DELETE_CHECK"
NO CASCADE BEFORE DELETE ON ABC
REFERENCING OLD AS OLD_OBJ
FOR EACH ROW MODE DB2SQL
BEGIN
SELECT CASE WHEN (SELECT 1 FROM ABC WHERE ID = 2 OR NAME = 'AA' AND OLD_OBJ.TYPE = 2) THEN
SIGNAL SQLSTATE '1234' ('Wrong Parameters');
END FROM SYSIBM.SYSDUMM1;
END
You can't use another statements (like SIGNAL) in the SELECT statement.
Use the RAISE_ERROR function instead to make SELECT raise an exception conditionally.
Or use CASE statement instead of the CASE expression you use in the question.
Not sure if this is a Supabase issue or a psycopg2 issue honestly and would love some help debugging.
I have the following code:
args = [('HaurGlass','60000','2022-10-20T21:15:39.751Z','10130506261','ac76e8db-ace0-40df-b6fa-f470641805e9','ad43639e-f66e-49d5-8fe8-d1ce5cd26193','{}')]
statement = ('''
INSERT INTO %s (%s) VALUES %s ON CONFLICT (company_id, crm_id)
DO UPDATE SET (%s)=(%s) RETURNING crm_id, id''')
statement = cur.mogrify(statement,
(AsIs(db_table), AsIs(','.join(keys)),
AsIs("%s"), AsIs(','.join(update_keys)),
AsIs(','.join(excluded_keys))))
output = execute_values(cur, statement, args, fetch=True)
The weird thing is that if args is <=100 rows in length, this query works without any problems. As soon as I increase the length of args to 101 rows or more, my Postgres logs show:
INSERT INTO licenses (name,value,subscription_end,crm_id,company_id,csm_id,custom_data) VALUES ('HaurGlass','60000','2022-10-20T21:15:39.751Z','10130506261','ac76e8db-ace0-40df-b6fa-f470641805e9','ad43639e-f66e-49d5-8fe8-d1ce5cd26193','{}')...
which would be good, except that it's immediately followed by:
INSERT INTO licenses (name,value,subscription_end,crm_id,company_id,csm_id,custom_data) VALUES ('HaurGlass','60000','2022-10-20T21:15:39.751Z','10130506261','ac76e8db-ace0-40df-b6fa-f470641805e9',NULL,'{}'),...
I've also confirmed that the number of records in the second "NULLifying" query is exactly equal to len(args)-100.
Any idea what is going on?
OK so it turns out I was missing the page_size parameter. All I had to do was:
output = execute_values(cur, statement, args, fetch=True, page_size=len(args))
I am trying to add a declared variable to replace a hardcoded list of values in a "where in" clause.
Researching how Hana handles array variables it seems like I can do this by declaring an array and then either using a select directly on it or by unnesting it first into a table but I keep getting errors I can't resolve.
When I try it this way:
DO
BEGIN
DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
SELECT T0."ItemCode"
FROM OITM T0
INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
WHERE "WhsCode" IN (SELECT "code" FROM :CODES_ARRAY); -- line 9 where error occurs
END;
I get this error message sql syntax error: incorrect syntax near ")": line 9 col 54 (at pos 239)
I can't figure out what the syntax error resolution is.
So then I tried inserting a declared table variable like this:
DO
BEGIN
DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
DECLARE CODES_TABLE TABLE = UNNEST(:CODES_ARRAY) AS ("code"); -- line 5 where error occurs
SELECT T0."ItemCode"
FROM OITM T0
INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
WHERE "WhsCode" IN (SELECT "code" FROM CODES_TABLE); -- I know : is missing here but when adding, the same error from previous block shows up
END;
and I get this error message: identifier must be declared: 1: line 5 col 38 (at pos 123)
As far as I can tell the array variable is declared as it should be so I don't know how to resolve the error.
I've read the SAP Hana SQL Reference documentation (for array/table variables, unnest function, etc.) over and over and it seems like I've got everything setup correctly but can't figure out these errors. I would like to be able to use both of these approaches at different times if possible (the "array variable to table variable" and the "array variable only" approaches)
I don't know exactly what is going on here, but one thing I notice that the two different error messages referenced in my post (see difference from errors in the first two code blocks) is that each error is occurring either immediately before the use of the variable with the : (in the case of the UNNEST) or immediately following the variable with the : (in the case of using in the SELECT * FROM in the query).
Because of that, I wondered if the issue is "upstream" at the Hana ADO.NET application query preparation and execution call level, but I ran a test and when I double checked the query string just before it is executed, it appears unchanged and the variables with : still look as they should, so at least as far as just before execution through Hana ADO.NET HanaCommand it looks correct - but once executing the query using HanaDataReader or HanaDataAdapter it returns the error messages referred to above. It may be a red herring to chase the problem from the Hana ADO.NET level but don't know what else to do.
Update
To further troubleshoot, I tried executing this code block below using hdbsql.exe -n XXX.XXX.XXX.XXX:30015 -u XXX -p XXX -m -I "c:\temp\test.sql" -c "#" and it works! So, the errors I see only show up when executing the same query through the Hana ADO.NET interface.
DO
BEGIN
DECLARE CODES_ARRAY NVARCHAR(10) ARRAY = ARRAY('01','02','03','04');
DECLARE CODES_TABLE TABLE ("code" NVARCHAR(10)) = UNNEST(:CODES_ARRAY) AS ("code");
SELECT T0."ItemCode"
FROM OITM T0
INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
WHERE "WhsCode" IN (SELECT "code" FROM :CODES_TABLE); -- line 10 where error occurs when using Hana ADO.NET
END;
#
The above fails when through Hana ADO.NET with the error message: sql syntax error: incorrect syntax near ")": line 10 col 54 (at pos 325) but works when executed through hdbsql.
Update
The C# code that executes the query is fairly straight forward, but for completeness of troubleshooting effort I am including the interesting parts of our HanaHelper class. This code works successfully to execute 100s of queries a day without errors or problems. This is the first time where a variable of any type has been attempted to be declared or used in a query through this code and when the errors started showing up. As far as I can tell, the issue is tied to the use of the : when using the variable in the query.
public class HanaHelper
{
public HanaConnection objConn = null;
public HanaHelper(string ConnectionString)
{
try
{
objConn = new HanaConnection(ConnectionString);
}
catch (Exception e)
{
Console.WriteLine(#"Exception thrown by HanaConnection: {0}\n{1}", e.Message, e.InnerException);
}
}
public DataSet GetData(string strSQL)
{
using (HanaCommand objCmd = new HanaCommand(strSQL, objConn))
{
using (HanaDataAdapter objDA = new HanaDataAdapter(objCmd))
{
DataSet objDS = new DataSet();
try
{
objDA.Fill(objDS);
}
catch (Exception)
{
throw;
}
finally
{
// do something interesting regardless of success or failure
}
objConn.Close();
return objDS;
}
}
}
}
Any clue here why the same query works through hdbsql but fails when executing through Hana ADO.NET?
Update
I figured out how to use HanaSQLTrace in the C# code so that I can inspect the prepared query text and viola, the source of error messages becomes apparent, all occurrences of ":VARNAME" are replaced with "? " (a ? replaces the : and a space for each character in the variable name). I suppose it is trying to pre-substitute occurrences of : with a ? as if there were parameters to be substituted.
How can this behavior be disabled, or worked with, or worked around so that I can use variables in a query in Hana ADO.NET effectively?
Updated based on the OP feedback.
To refer to a variable (in order to access its value(s)) in SQLScript it's
necessary to put a colon : in front of the variable name.
The main issue, however, turns out to be the declaration of the CODES_TABLE table variable.
With HANA 2 SPS 4 the error message is
`SAP DBTech JDBC: [264]: invalid datatype: unknown type SYSTEM.TABLE: line 5 col 23`
This points to the declaration of the TABLE typed variable CODES_TABLE which lacks the definition of what columns should be in the table.
Adding this fixes the issue.
With these changes, your code should work:
DO
BEGIN
DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
DECLARE CODES_TABLE TABLE ("code" NVARCHAR(100)) = UNNEST(:CODES_ARRAY) AS ("code");
-- ^^^^^^^^^^^^^^^^^^^^^^
-- |
---------------------------------------+
SELECT
T0."ItemCode"
FROM
OITM T0
INNER JOIN OITW T1
ON T0."ItemCode" = T1."ItemCode"
WHERE
"WhsCode" IN (SELECT "code" FROM :CODES_TABLE);
-- ^
-- |
---------------------------------------+
END;
An alternative option to declare and assign the table variable is to not use the DECLARE command.
DO
BEGIN
DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
CODES_TABLE = UNNEST(:CODES_ARRAY) AS ("code");
SELECT
T0."ItemCode"
FROM
OITM T0
INNER JOIN OITW T1
ON T0."ItemCode" = T1."ItemCode"
WHERE
"WhsCode" IN (SELECT "code" FROM :CODES_TABLE);
END;
I am creating function in which update command is used consecutively two times the first update is working and the second one is not
Have tried execute format () for the second update not working
While running the function the updation2 is not working but when I manually run this updation command the table get updated...
The code is as follows:
update edmonton.weekly_pmt_report
set permit_number = pmt.prnum
from(select permit_details,
split_part(permit_details,'-',1) as prnum
from edmonton.weekly_pmt_report) as pmt
where edmonton.weekly_pmt_report.permit_details =
pmt.permit_details;
execute format('update edmonton.weekly_pmt_report
set address = ds_dt.adr,
job_description = ds_dt.job,
applicant = ds_dt.apnt
from(select split_part(per_num,''-'',1) as job_id,
job_des as job,addr as adr, applic as apnt
from edmonton.descriptive_details ) as ds_dt
where edmonton.weekly_pmt_report.permit_number =
ds_dt.job_id');
That the second update query has value only 400 out of 1000 so the null columns are on the Top, that's why It seemed to be not working...
I have two simple (only for explain my problem) tables
X with columns (among others): IDX,CODE,NUMBER
Y with columns (among others): CODE,NUMBER,id_fromX
I want to (after insert or update table X) update table Y using variables from actual record from X.
To do this I try to use trigger (in table X) like below:
SET TERM ^^ ;
CREATE TRIGGER XYZFOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
begin
if (new.CODE is distinct old.CODE) then
BEGIN
EXECUTE STATEMENT ('UPDATE Y SET CODE=:old.CODE, id_fromX=:old.IDX WHERE NUMBER=:old.NUMBER');
END
end ^^
but I get error from the server:
Execute statement error at jrd8_prepare :\
335544569 : Dynamic SQL Error
335544436 : SQL error code = -104
335544634 : Token unknown - line 1, column 23
335544382 : .
Statement : UPDATE Y SET CODE=:old.CODE, id_fromX=:old.IDX WHERE NUMBER=:old.NUMBER\
Data source : Internal::
At trigger 'XYZ' line: 15, col: 7
Static update like this below:
CREATE TRIGGER XYZ FOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
begin
if (new.CODE is distinct from old.CODE) then
BEGIN
EXECUTE STATEMENT ('UPDATE Y SET CODE=1, id_fromX=111 WHERE NUMBER=1');
END
end ^^
SET TERM ; ^^
works perfect.
How to reference to X table fields to update table Y (fields with similar names)?
You're using a colon, but the old/new records don't use it. Also, don't use a execute statement here, since the sql statement is static.
Change it to:
SET TERM ^^ ;
CREATE TRIGGER XYZFOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
begin
if (new.CODE is distinct old.CODE) then
BEGIN
UPDATE Y
SET CODE = old.CODE, id_fromX = old.IDX
WHERE NUMBER = old.NUMBER;
END
end ^^
You can't write parameters directly into statement with EXECUTE STATEMENT, see documentation for correct syntax. Basically, it should be something like
EXECUTE STATEMENT ('UPDATE Y SET CODE = :CODE, id_fromX = :IDX WHERE NUMBER=:NUMBER')
(CODE := old.CODE, IDX := old.IDX, NUMBER := old.NUMBER);
But you actually don't need the EXECUTE STATEMENT here, use UPDATE statement "directly".
You can't use the trigger context variables (old.<column> and new.<column>) in EXECUTE STATEMENT as they are separate contexts (the statement in EXECUTE STATEMENT can't see them). You either need to use a normal UPDATE statement without resorting to EXECUTE STATEMENT, or you should pass parameters. Like:
EXECUTE STATEMENT
('UPDATE Y SET CODE=:code, id_fromX=:idx WHERE NUMBER=:number')
(code := old.CODE, idx := old.IDX, number := old.NUMBER);
Shouldn't :old.CODE be old.CODE?