I am not very much experienced in plpgsql so I am having 2 questions here.
Here is my oracle script which runs fine:
DECLARE
CURSOR cur_tables IS
SELECT NAME,
'SELECT PROPERTY_VALUE FROM '
|| USERNAME
|| '.P_PROPERTY WHERE PROPERTY_NAME = ''VERSION'''
AS dsql
FROM CB_DATASOURCE
WHERE (UPPER(USERNAME) LIKE 'NAV_PS_%' or UPPER(USERNAME) LIKE 'CBPS_%' or UPPER(USERNAME) LIKE 'DEFAULTPS');
CURR_VERSION VARCHAR2(1000);
BEGIN
FOR r_tables IN cur_tables LOOP
begin
EXECUTE IMMEDIATE r_tables.dsql INTO CURR_VERSION;
DBMS_OUTPUT.put_line(r_tables.NAME || ': ' || CURR_VERSION);
exception
when others then
DBMS_OUTPUT.put_line(r_tables.NAME || ' no table');
end;
END LOOP;
END;
/
and here is my postgres function which I am not able to get it working but eventually would like to refrain from using a permanent function
create or replace function upgrade_version() returns setof record as $$
declare
r record;
loopy record;
isql text;
CURR_VERSION text;
begin
for r in SELECT 'SELECT PROPERTY_VALUE FROM '
|| USERNAME
|| '.P_PROPERTY WHERE PROPERTY_NAME = ''VERSION'''
AS dsql
FROM CB_DATASOURCE
WHERE (UPPER(USERNAME) LIKE 'NAV_PS_%' or UPPER(USERNAME) LIKE 'CBPS_%' or UPPER(USERNAME) LIKE 'DEFAULTPS') loop
isql := r.dsql;
EXECUTE isql INTO CURR_VERSION;
RETURN next loopy;
end loop;
return;
end;
$$ language 'plpgsql';
I would really appreciate any inputs on this.
What you seem to be trying should work with a DO
statement:
DO
$do$
DECLARE
r record;
curr_version text;
BEGIN
FOR r IN
SELECT name, format($$
SELECT property_value
FROM %I.p_property
WHERE property_name = 'VERSION'$$, username) AS dsql
FROM cb_datasource
WHERE upper(username) LIKE ANY ('{NAV_PS_%, CBPS_%, DEFAULTPS}')
LOOP
BEGIN
EXECUTE r.dsql INTO curr_version;
RAISE NOTICE '%: %', r.name, curr_version;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '%: no table', r.name;
END;
END LOOP;
END
$do$
You cannot RETURN
from a DO
statement, but you can RAISE
notices et al.
Seems to be perfect for you since you eventually would like to refrain from using a permanent function
.
Note that the default procedural language for DO
statements is still plpgsql
.
In Postgres, unquoted identifiers are cast to lower case (as opposed to Oracle, where they are upper-cased).
To catch exceptions in a loop you need to wrap the body in a separate block. Read the manual here.
You need to sanitize identifiers in dynamically built SQL strings lest you are vulnerable to SQL injection and other problems from non-standard names. Your Oracle code is lacking there as well.
I am using format()
with %I
for the purpose. More info:
How to use EXECUTE FORMAT ... USING in postgres function
Shortened your WHERE
clause with ANY
You are aware that _
is a placeholder character in LIKE
patterns? For literal _
, escape it: \_
.