danmurphy
04/29/2022, 4:05 PMprocessed
field set to N
and record_created_date
set to the current date/time. SAP PI (middleware software) polls the table for unprocessed records, creates SAP IDOCs from the data, then updates the processed
flag to Y
. Here is the kicker…the way the SAP PI JDBC sender works, there are 2 separate SQL statements that make this happen that have no knowledge of each other. The 1st is a SELECT to get the records to create the IDOCS. Then a totally separate UPDATE statement to update the records that have been processed. The polling interval can be set to whatever timeframe. So you might just say…
1. SELECT * FROM table WHERE processed = 'N'
2. Process the records and create IDOCs
3. UPDATE table SET processed = 'Y' WHERE processed = 'N'
The problem is, if processing the records takes 3 seconds (or 10ms, or 30s, etc), the records that are inserted in-between step 1 and 3 don’t get IDOCs created but are updated in the table as processed.
Is there any way to make sure all records are processed?danmurphy
04/29/2022, 4:20 PMMyka Forrest
04/29/2022, 4:57 PMwhere processed = 'N'
, can you set processed
to 'P'
(pending), and then only update where processed = 'P'
?Myka Forrest
04/29/2022, 4:58 PMdanmurphy
04/29/2022, 4:59 PMdanmurphy
04/29/2022, 5:00 PMMyka Forrest
04/29/2022, 5:15 PMdanmurphy
04/29/2022, 5:26 PMMyka Forrest
04/29/2022, 5:51 PMdanmurphy
04/29/2022, 5:54 PMwebsolete
04/29/2022, 5:55 PMdanmurphy
04/29/2022, 5:56 PMMyka Forrest
04/29/2022, 5:58 PMwebsolete
04/29/2022, 5:59 PMdanmurphy
04/29/2022, 5:59 PMrecord_created_date
field to try and help, for example.danmurphy
04/29/2022, 6:00 PMMyka Forrest
04/29/2022, 6:01 PMdanmurphy
04/29/2022, 6:02 PMMyka Forrest
04/29/2022, 6:08 PMselect ID
(from origTable) into helperTable where processed = 'N'
.
Then Select * from helperTable
for processing IDOCs.
Update origTable SET processed = 'Y' WHERE id in (select id from helperTable).
Truncate helperTable
so the next batch starts from scratch.websolete
04/29/2022, 6:09 PMINSERT INTO helpertable ( col1, col2 )
SELECT col1, col2
FROM tablename
WHERE processed = 'N';
SELECT col1, col2
FROM tablename
WHERE processed = 'N';
-------------------------
UPDATE t
SET t.processed = 'Y'
FROM tablename t
INNER JOIN helpertable h ON t.col1 = h.col1
WHERE t.processed = 'N';
you'd have to update the update sql to match how oracle does update/inner joins, of course. you'd also want to have something that cleans up helpertable although if the above works you could forego that (but have lots of leftover useless rows)websolete
04/29/2022, 6:09 PMwebsolete
04/29/2022, 6:10 PMdanmurphy
04/29/2022, 6:12 PMMyka Forrest
04/29/2022, 6:13 PMselect * from table where processed = 'n'
take place?websolete
04/29/2022, 6:13 PMMyka Forrest
04/29/2022, 6:13 PMMyka Forrest
04/29/2022, 6:13 PMdanmurphy
04/29/2022, 6:13 PMMyka Forrest
04/29/2022, 6:14 PMwebsolete
04/29/2022, 6:14 PMwebsolete
04/29/2022, 6:14 PMwebsolete
04/29/2022, 6:14 PMdanmurphy
04/29/2022, 6:14 PMMyka Forrest
04/29/2022, 6:15 PMdanmurphy
04/29/2022, 6:15 PMwebsolete
04/29/2022, 6:15 PMwebsolete
04/29/2022, 6:16 PMwebsolete
04/29/2022, 6:16 PMdanmurphy
04/29/2022, 6:17 PMdanmurphy
04/29/2022, 6:17 PMwebsolete
04/29/2022, 6:17 PMwebsolete
04/29/2022, 6:17 PMdanmurphy
04/29/2022, 6:18 PMwebsolete
04/29/2022, 6:18 PMdanmurphy
04/29/2022, 6:19 PMMyka Forrest
04/29/2022, 6:22 PMdanmurphy
04/29/2022, 6:22 PMEXECUTE sproc;
statement, right? Sorry if I’m too Oracle-ized and this sounds ridiculous. But Returning data = SELECT statements = SQL. Stored procedures are in the PL/SQL realm. Right?danmurphy
04/29/2022, 6:23 PMwebsolete
04/29/2022, 6:23 PMwebsolete
04/29/2022, 6:24 PMdanmurphy
04/29/2022, 6:25 PMwebsolete
04/29/2022, 6:25 PMdanmurphy
04/29/2022, 6:27 PMdanmurphy
04/29/2022, 6:28 PMwebsolete
04/29/2022, 6:29 PMdanmurphy
04/29/2022, 6:30 PMwebsolete
04/29/2022, 6:30 PMdanmurphy
04/29/2022, 6:31 PMdanmurphy
04/29/2022, 6:32 PMwebsolete
04/29/2022, 6:32 PMwebsolete
04/29/2022, 6:32 PMwebsolete
04/29/2022, 6:33 PMwebsolete
04/29/2022, 6:33 PMdanmurphy
04/29/2022, 6:35 PMwebsolete
04/29/2022, 6:37 PMwebsolete
04/29/2022, 6:42 PMwebsolete
04/29/2022, 6:45 PMdanmurphy
04/29/2022, 6:47 PMwebsolete
04/29/2022, 6:49 PMWHERE processed = 'N' AND processAfter < now()
any newly inserted records that have occurred will be flagged for 20 mins in the futurewebsolete
04/29/2022, 6:51 PMwebsolete
04/29/2022, 6:52 PMwebsolete
04/29/2022, 6:53 PMdanmurphy
04/29/2022, 6:54 PMdanmurphy
04/29/2022, 6:54 PMWHERE record_created_date <= trunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60)
AND processed = 'N';
danmurphy
04/29/2022, 6:55 PMwebsolete
04/29/2022, 6:56 PMwebsolete
04/29/2022, 6:56 PMwebsolete
04/29/2022, 6:58 PMdanmurphy
04/29/2022, 6:59 PMwebsolete
04/29/2022, 6:59 PMwebsolete
04/29/2022, 6:59 PMwebsolete
04/29/2022, 7:00 PMwebsolete
04/29/2022, 7:00 PMdanmurphy
04/29/2022, 7:01 PMprocessAfter
become the same thing as record_create_date
, but just 10 minutes later?websolete
04/29/2022, 7:01 PMwebsolete
04/29/2022, 7:03 PMdanmurphy
04/29/2022, 7:05 PMtrunc(sysdate, 'mi') - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 5) / (24 * 60)
websolete
04/29/2022, 7:05 PMdanmurphy
04/29/2022, 7:06 PMdanmurphy
04/29/2022, 7:06 PMwebsolete
04/29/2022, 7:07 PMdanmurphy
04/29/2022, 7:13 PMwebsolete
04/29/2022, 7:24 PMhourBatch
or batchId or whatever whose value will be the hour part of a 24 hour clock + 1.
id col1 col2 processed hourBatch timestamp
1 92 hello N 12 11:01:33 am
1 93 blah N 12 11:11:43 am
1 94 fred N 13 12:32:00 pm
1 95 mary N 15 02:01:33 pm
then, your SELECT will target only records from the current hour:
SELECT col1, col1
FROM tablename
WHERE processed = 'N' AND hourBatch = hour(now()) -- let's say it's 11:02am right now, so this would be 11
you process those records (which were inserted an hour ago) and then your UPDATE statement targets the same set
UPDATE tablename
SET processed = 'Y'
WHERE processed = 'N' AND hourBatch = hour(now()) -- 11
the trick would be finding the smallest time increment (quarter hour, half hour, hour, whatever) you can get away with and not risk any records slipping into the current batch. in this exaggerated scenario of one hour lag, you're fine as long as any one batch doesn't take more than an hour to complete.
it's the disconnect between the select and update and the forced simplicity of the sql statements you can use that are going to make any solution that does not include a third agent getting involved to try and bridge the gap really difficultdanmurphy
04/29/2022, 7:37 PMdanmurphy
04/29/2022, 7:37 PMwebsolete
04/29/2022, 7:46 PMdanmurphy
04/29/2022, 7:49 PMwebsolete
04/29/2022, 7:51 PMdanmurphy
04/29/2022, 7:53 PMwebsolete
04/29/2022, 7:54 PMSELECT col1, col2, @@lastprocessed = now() FROM tablename WHERE processed = 'N'
do the processing and then UPDATE tablename SET processed = 'Y' WHERE processed = 'N' AND record_date < @@lastprocessed
?websolete
04/29/2022, 7:54 PMdanmurphy
04/29/2022, 7:58 PM@@lastprocessed
get set?websolete
04/29/2022, 7:59 PMwebsolete
04/29/2022, 7:59 PMdanmurphy
04/29/2022, 8:01 PMdanmurphy
04/29/2022, 8:01 PMwebsolete
04/29/2022, 8:02 PMdanmurphy
04/29/2022, 8:06 PMSELECT bleh INTO myVariable
with Oracle and you can use it within the same function/procedure, but that would only be in PL/SQL, not normal ’ol SQL.websolete
04/29/2022, 8:10 PMMyka Forrest
04/29/2022, 8:11 PMdanmurphy
04/29/2022, 8:12 PMdanmurphy
04/29/2022, 8:16 PM