Reputation: 4635
I am writing a stored procedure to find the sub-items of a main item and update it. The scenario is like this
Id Item Name Parent Id
1 Item A 14.1 NULL
2 Item B 14.1.1 1
3 Item C 14.1.2 1
4 Item B 14.1.3 1
5 Item A 14.1.1.1 2
I have posted another question on SO String matching in PostgreSQL 8.4 to get the children of an item. According to that answer i have to escape the item code and have to use it in the query. But I haven't got any method to escape that. The SP is as below:
CREATE OR REPLACE FUNCTION updateitemparentnew(bigint, int) RETURNS text
LANGUAGE plpgsql STRICT
AS $$
DECLARE
itemdetail RECORD;
codeSearch text;
codeEscapedSearch text;
result text;
BEGIN
--Get th details of the current item
SELECT INTO itemdetail * FROM om_item WHERE item_id = $1;
codeSearch = itemdetail.item_code||'.';
codeEscapedSearch = codeSearch; --Need to be corrected. It should escape the item code
-- Event 1=> add 2 => edit 3 => delete
IF $2 = 1 THEN
--Find new children and update then
result = 'UPDATE om_item SET item_parentid = '||itemdetail.item_id
||' WHERE item_id IN (
SELECT item_id FROM om_item
WHERE item_code LIKE \''||codesearch||'%\'
AND item_code ~ \''||codeEscapedsearch||'[^.]+$\');';
END IF;
return result;
END;
$$;
In the query codeEscapedSearch
should be escaped to handle the .
in the code itself and the .
in the regex.
Upvotes: 2
Views: 355
Reputation: 659207
Consider this direct approach:
CREATE OR REPLACE FUNCTION updateitemparentnew(_id bigint, _operation text)
RETURNS void LANGUAGE plpgsql STRICT AS
$func$
DECLARE
code_like text;
code_regex text;
BEGIN
SELECT INTO code_like, code_regex
p.item_code || '.%'
, '^' || replace(p.item_code, '.', '\.') || '\.[^.]+$'
FROM om_item p
WHERE p.item_id = _id;
CASE _operation -- ins / upd / del
WHEN 'upd' THEN -- Find new children and update then
UPDATE om_item c
SET item_parentid = _id
WHERE c.item_code LIKE code_like
AND c.item_code ~ code_regex;
-- WHEN 'ins' THEN ...
-- WHEN 'del' THEN ...
END CASE;
END
$func$;
This does not return a query string but executes the UPDATE
directly. Much shorter and faster.
Also using replace()
, btw.
Thorough solution to escape all LIKE
and regexp patterns:
Upvotes: 1
Reputation: 4635
Since no proper solution is identified, I decided to use simple replace
codeEscapedSearch = replace(codeSearch,'.','\\.');
Upvotes: 0