Related
We have implemented the partitioning on a Postgres table using a flyway script.
In the flyway script, we are also creating a trigger defined as below -
CREATE TRIGGER raw_event_insert_or_partition
BEFORE INSERT
ON public.raw_event
FOR EACH ROW
EXECUTE FUNCTION public.raw_event_insert_or_partition();
public.raw_event_insert_or_partition() creates a partition if not exist and do the insertion.
Below is the complete flyway script for the reference -
CREATE OR REPLACE FUNCTION public.parcel_event_insert_partition()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
partition_date TEXT;
partition TEXT;
start_ts TIMESTAMP ;
end_ts TIMESTAMP ;
BEGIN
partition_date := to_char(NEW.carrier_status_time_gmt,'YYYY_MM_01');
start_ts := partition_date::timestamp ;
end_ts := start_ts + interval '1 month' ;
partition := TG_RELNAME || '_' || to_char(start_ts,'YYYY_MM_01') || '_' || to_char(end_ts,'YYYY_MM_01');
IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
EXECUTE 'CREATE TABLE ' || quote_ident(partition)
|| ' (check (carrier_status_time_gmt >= ''' || start_ts || ''' '
|| ' AND carrier_status_time_gmt < ''' || end_ts || ''')) '
|| ' INHERITS (' || TG_RELNAME || ');';
EXECUTE 'CREATE INDEX ON ' || quote_ident(partition) || ' (carrier_status_time_gmt,carrier_code,value)';
RAISE NOTICE 'A partition has been created %', partition;
END IF;
EXECUTE 'INSERT INTO ' || quote_ident(partition) || ' SELECT(' || TG_RELNAME || ' ' || quote_literal(NEW) || ').* RETURNING id;';
RETURN NULL;
END;
$BODY$;
-- Register TRIGGER
CREATE TRIGGER parcel_event_insert_or_partition
BEFORE INSERT
ON public.parcel_event
FOR EACH ROW
EXECUTE FUNCTION public.parcel_event_insert_partition();
When we are running the insertion query in the PgAdmin console, it's working fine and data is getting inserted in the expected partition.
But when we are trying to insert the data using the save() method of the crudRepository we are getting the below error -
org.springframework.orm.ObjectOptimisticLockingFailureException: Unexpected row count: 0; expected: 1;
On enabling show_sql we are getting the below queries in the logs-
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into parcel_event (carrier_code,
carrier_status, carrier_status_code, carrier_status_time_gmt,
carrier_sub_status, carrier_sub_status_code,
carrier_sub_status_description, destination_location,
extra_info, status, status_code, status_description,
sub_status, sub_status_code, sub_status_description,
last_updated_at, latitude, location_code, location_name,
longitude, order_no, org_id, previous_status,
previous_status_time, status_identifier_value,
status_received_at, type, value, id) values (?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Any help is appreciated.
when merge native query is used using JPA, it is resulting into following error:
{"ts":"2022-05-05T17:03:12.124+0000","level":"ERROR","message":"SQL Error: 50004, SQLState: HY004 Unknown data type: "SYS_USER_ID"; SQL statement:\nMERGE INTO USER TARGET USING (SELECT ? AS USER_ID, ? CLNT_ID, ? WPI, ? U_TYPE_CD, ? ENBL_SW, ? TRD FROM DUAL ) SOURCE ON(TARGET.TRD = SOURCE.TRD AND TARGET.CLNT_ID = SOURCE.CLNT_ID AND TARGET.USER_ID = SOURCE.USER_ID ) WHEN MATCHED THEN UPDATE SET TARGET.WPI = SOURCE.WPI, TARGET.U_TYPE_CD = SOURCE.U_TYPE_CD, TARGET.ENBL_SW = SOURCE.ENBL_SW WHEN NOT MATCHED THEN INSERT (USER_ID, USER_ID , CLNT_ID, WPI, U_TYPE_CD, ENBL_SW, TRD) VALUES (11001 , ? , ?, ?, ?, ?, ?)
Above query is working very well with Oracle db - not working in H2 database.
The sql in your call stack shows:
MERGE INTO USER
TARGET
USING (SELECT ? AS USER_ID, ? CLNT_ID, ? WPI, ? U_TYPE_CD, ? ENBL_SW, ? TRD FROM DUAL )
SOURCE
ON(TARGET.TRD = SOURCE.TRD AND TARGET.CLNT_ID = SOURCE.CLNT_ID AND TARGET.USER_ID = SOURCE.USER_ID )
WHEN MATCHED THEN UPDATE SET TARGET.WPI = SOURCE.WPI, TARGET.U_TYPE_CD = SOURCE.U_TYPE_CD, TARGET.ENBL_SW = SOURCE.ENBL_SW
WHEN NOT MATCHED THEN INSERT (USER_ID, USER_ID , CLNT_ID, WPI, U_TYPE_CD, ENBL_SW, TRD)
VALUES (11001 , ? , ?, ?, ?, ?, ?)
You need check the above SQL executing result in your H2 database.
The better is that you can provide the whole reproducing code line for a check.
Different DBMS can have different result. Not all the same.
I have java application that execute native query, I have tried to execute the query using entityManager.createNativeQuery, jdbcTemplate, and java.sql.PreparedStatement.executeUpdate, none succeeded. The query completed without error, but no data is inserted.
Here's my actual SQL:
WITH stmt AS (
INSERT INTO account_statements (
amount,
sum_amount,
available_balance,
previous_available_balance,
hold_amount,
previous_hold_amount,
type,
note,
partner_id,
incoming_transfer_id
)
(
SELECT
?,
?,
(available_balance + ?),
available_balance,
hold_amount,
hold_amount,
?,
?,
?::uuid,
?::uuid
FROM account_statements
WHERE partner_id = ?::uuid
ORDER BY created_at
DESC LIMIT 1
) RETURNING id, available_balance, hold_amount), debit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
), credit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
)
UPDATE partners
SET
available_balance = (select available_balance from stmt),
hold_amount = (select hold_amount from stmt)
WHERE id = ?::uuid;
Not sure what I did wrong, but when I tried the SQL above in pg console and replace all the placeholders, it worked. Does anyone have an idea why the SQL above is not working?
I am sorry that i ask a very stupid question but i cant find the place where i miss the comma in the code..
sqlStr.append("INSERT INTO DS_GOAL ");
sqlStr.append("(DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID, DS_GOAL_ID, ");
sqlStr.append("DS_DESC, TO_CHAR(DS_PLAN_END_DATE, \"dd/MM/YY\"),");
sqlStr.append("DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER, ");
sqlStr.append("DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT, DS_FTE, ");
sqlStr.append("DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER ) ");
sqlStr.append("VALUES ");
sqlStr.append("(?, ?, ?, ?, ?,");
sqlStr.append("?, ?,");
sqlStr.append("?, ?, ?, ?,");
sqlStr.append("?, ?, ?, ?,");
sqlStr.append("?, ?, ?)");
sqlStr_insertGoal = sqlStr.toString();
After the
sqlStr.toString()
the console shows
INSERT INTO DS_GOAL (DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID,
DS_GOAL_ID,
DS_DESC, TO_CHAR(DS_PLAN_END_DATE, 'dd/MM/YYYY'),
DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER,
DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT,
DS_FTE, DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER)
VALUES (?, ?, ?, ?, ?,?, ?,?, ?, ?, ?,?, ?, ?, ?,?, ?, ?)
After Edited the code
the console shows
INSERT INTO DS_GOAL (DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID,
DS_GOAL_ID,
DS_DESC, DS_PLAN_END_DATE,
DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER,
DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT,
DS_FTE, DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER)
VALUES (?, ?, ?, ?, ?,?, TO_CHAR(DS_PLAN_END_DATE, 'dd/MM/YYYY'),?, ?, ?, ?,?, ?, ?,
?,?, ?, ?)
But the consoles shows invalid column index error
Thanks for help
I suspect your problem isn't actually a case of a missing comma (in my experience ORA errors are notorious for telling you the wrong thing). My suspicion is that your real issue is the use of " around the format string in your TO_CHAR call. To demonstrate, try this:
SELECT TO_CHAR(SYSDATE, "dd/MM/YY")
FROM DUAL;
If I run the above I get an ORA-00904: "dd/MM/YY": invalid identifier error. If I change the quotes to apostrophes instead:
SELECT TO_CHAR(SYSDATE, 'dd/MM/YY')
FROM DUAL;
I get 16/04/14. Double quotes are for identifiers, not strings:
SELECT TO_CHAR(SYSDATE, 'dd/MM/YY') AS "The Date"
FROM DUAL; // ^ This is an identifier
prints:
The Date
--------
16/04/14
EDIT:
Sorry, I should have spotted this one sooner! You're using TO_CHAR in your columns list, which you can't do. The below example nicely produces an ORA-00917: missing comma error:
CREATE TABLE JON_TEST (COL1 VARCHAR2(20));
COMMIT;
INSERT INTO JON_TEST (TO_CHAR(COL1, 'DD/MM/YYYY'))
VALUES (SYSDATE);
Whereas this works:
INSERT INTO JON_TEST (COL1)
VALUES (TO_CHAR(SYSDATE, 'dd/MM/YYYY'));
So you need to correct three things:
You need to change TO_CHAR to TO_DATE, and
You need to move the call to TO_DATE to your VALUES clause, and
You need to ensure that you use ' instead of " with the format string.
This is how Oracle define the syntax for INSERT statements:
Notice that in the middle section that it only says column_name and not sql_expression.
Try changing your query to the following:
sqlStr.append("INSERT INTO DS_GOAL ")
.append("(DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID, DS_GOAL_ID, ")
.append("DS_DESC, DS_PLAN_END_DATE, ")
.append("DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER, ")
.append("DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT, DS_FTE, ")
.append("DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER ) ")
.append("VALUES ")
.append("(?, ?, ?, ?, ?,")
.append("?, TO_DATE(?, 'dd/MM/YY'),")
.append("?, ?, ?, ?,")
.append("?, ?, ?, ?,")
.append("?, ?, ?)");
sqlStr_insertGoal = sqlStr.toString();
Hello friends i am running code given below which contains the setLogTimeEntery function and when this function is executed i am getting
"Error : java.sql.SQLException: ORA-00917: missing comma"
error and my database is oracle plese any one tell me wht is the problem.
public int setLogTimeEntery(Connection con, LogTimeBean ltb) {
int ans = 0;
try{
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual) , Prj_Id=?,Area_Id=?,Actvity_Id=?,ID_No=?,Work_Date=(select to_date(?,'dd/mm/yyyy')from dual) ,Work_Hours=?,Division=?,Description=?,Remarks=?,Work_Week=?)");
psmt.clearParameters();
psmt.setString(1,ltb.getLt_Prj_Id());
psmt.setInt(2,ltb.getLt_Area_Id());
psmt.setInt(3,ltb.getLt_Actvity_Id());
psmt.setInt(4, ltb.getLt_ID_No());
psmt.setString(5, ltb.getLt_Work_Date());
psmt.setFloat(6,ltb.getLt_Work_Hours());
psmt.setInt(7,ltb.getLt_Division());
psmt.setString(8, ltb.getLt_Description());
psmt.setString(9, ltb.getLt_Remarks());
psmt.setInt(10, ltb.getLt_Work_Week());
ans=psmt.executeUpdate();
psmt.close();
}catch(Exception e){
System.err.println("Error : "+e);
}
return ans;
}
I don't think your Oracle SQL statement (as defined in the prepared statement) is valid. When using the insert into [table] values(...) syntax, you don't use column=value expressions.
If you're specifying all of the column values in the correct order, then use this:
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual), ?, ?, ?, ?,(select to_date(?,'dd/mm/yyyy')from dual) ,?,?,?,?,?)");
Otherwise, if you're only specifying a subset of the columns, use the syntax of
insert into TR_LogTime (col1, col2, col3, ...) values (?, ?, ?, ...)
(I didn't specify the exact column names in your example since I don't know all of them)
More on this syntax.
try this:
Insert into TR_LogTime (XXX, YYY, Prj_Id, Area_id, Activity_Id, ID_No, Work_Date, Work_Hours, Division, Description, Remarks, Work_Week) values (
(Select count(*) from Tr_LogTime) + 1 , (select sysdate from dual) , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
You'll need to replace XXX and YYY with the appropriate column names