I have a function with a SELECT using a SIMILAR TO expression with a variable and I don’t know how to do it:
DECLARE pckg_data cl_data;
DECLARE contacts contacts_reg%ROWTYPE;
DECLARE sim_name varchar;
BEGIN
SELECT client_reg._name,
client_reg.last_name,
client_reg.id_card,
client_reg.address
INTO pckg_data
FROM client_reg WHERE(client_reg._name = (cl_name ||' '|| cl_lastname));
RETURN NEXT pckg_data;
SELECT ('%'||cl_name || ' ' || cl_lastname ||'%') INTO sim_name;
FOR contacts IN SELECT contacts_reg.id
FROM contacts_reg, contactscli_asc, client_reg
WHERE(contacts_reg._name SIMILAR TO sim_name) LOOP
SELECT client_reg._name, client_reg.last_name, client_reg.id_card,
client_reg.address, client_reg.id
INTO pckg_data
FROM client_reg, contactscli_asc WHERE(contactscli_asc.contact = contacts.id
AND client_reg.id = contactscli_asc.client);
END LOOP;
END;
Your query that feeds the loop has
CROSS JOINover three (!) tables. I removed the last two on the notion that they are not needed. One of them is repeated in the body of the loop. Also consider @kgrittn’s note onCROSS JOIN.In the body of the loop you select data into a variable repeatedly, which does nothing. I assume you want to return those rows – that’s what my edited version does, anyway.
I rewrote the
LOOPconstruct with a simpleSELECTwithRETURN QUERY, because that’s much faster and simpler.Actually, I rewrote everything in a way that would make sense. What you presented is still incomplete (missing function header) and syntactically and logically a mess.
This is an educated guess, no more:
Else, consider the features used.
Some advise:
You can assign a variable at declaration time.
The keyword
DECLAREis only needed once.Use table aliases to make your code easier to read.
You don’t have to enclose the
WHEREclause in parenthesis.Most likely you don’t need
SIMILAR TOandLIKEdoes the job faster. I never useSIMILAR TO.LIKEor regular expressions (~) do a better job: