Table 1 has error messages with a variable number of numbered placeholders within squiggly brackets. I need to build the completed messsage with values from a 2nd table.
Table 1:
ERROR_ID DESCRIPTION
---------- ------------------------------------------------------------
13706 {0} {1} has an invalid time stamp format
13707 POHEADERTAB{0} {1} has an invalid date format
13708 POGENERALTAB{0} value is invalid
13709 In Line Item {0}, {1} {2} value is invalid.
Table 2
ERROR_ID ARG_SEQ_NBR ARG_VALUE
---------- ----------- ------------------------
13706 0 PODate
13706 1 BadData
13707 0 Due Date
13707 1 BadData
13708 0 Origin Country Code
13709 0 000001
13709 1 Actual Cost
13709 2 BadData
The relationship between the tables is, of course, the error_id and placeholder/arg_seq_nbr values.
A correct result would be, for example: PODate BadData has an invalid time stamp format.
I have tried ‘with cte…’ and a couple things but can’t quite get it to work. I can only get it to return 8 rows (instead of 4) with each of those 8 rows containing the same arg_value in each placeholder.
Advertisement
Answer
If you have a maximum number of arguments, then one method would be:
select replace(replace(replace(replace(t1.description, '{1}', t2.arg_1), '{2}', t2.arg_2), '{3}', t2.arg_3), '{4}', t2.arg_4)
from table1 t1 join
(select error_id,
max(case when ARG_SEQ_NBR = 1 then arg_value end) as arg_1,
max(case when ARG_SEQ_NBR = 2 then arg_value end) as arg_2,
max(case when ARG_SEQ_NBR = 3 then arg_value end) as arg_3,
max(case when ARG_SEQ_NBR = 4 then arg_value end) as arg_4
from table2 t2
group by t2.error_id
) t2
using (error_id)
An alternative to this approach would be a recursive CTE. But I think the above is simpler if it works in your case.