Sample code trimmed down the the bare essentials to demonstrate question:
CREATE OR REPLACE FUNCTION mytest4() RETURNS TEXT AS $$
DECLARE
wc_row wc_files%ROWTYPE;
fieldName TEXT;
BEGIN
SELECT * INTO wc_row FROM wc_files WHERE "fileNumber" = 17117;
-- RETURN wc_row."fileTitle"; -- This works. I get the contents of the field.
fieldName := 'fileTitle';
-- RETURN format('wc_row.%I',fieldName); -- This returns 'wc_row."fileTitle"'
-- but I need the value of it instead.
RETURN EXECUTE format('wc_row.%I',fieldName); -- This gives a syntax error.
END;
$$ LANGUAGE plpgsql;
How can I get the value of a dynamically generated field name in this situation?
Use a trick with the function to_json()
, which for a composite type returns a json object with column names as keys:
create or replace function mytest4()
returns text as $$
declare
wc_row wc_files;
fieldname text;
begin
select * into wc_row from wc_files where "filenumber" = 17117;
fieldname := 'filetitle';
return to_json(wc_row)->>fieldname;
end;
$$ language plpgsql;
You don't need tricks. EXECUTE
does what you need, you were on the right track already. But RETURN EXECUTE ...
is not legal syntax.
CREATE OR REPLACE FUNCTION mytest4(OUT my_col text) AS
$func$
DECLARE
field_name text := 'fileTitle';
BEGIN
EXECUTE format('SELECT %I FROM wc_files WHERE "fileNumber" = 17117', field_name)
INTO my_col; -- data type coerced to text automatically.
END
$func$ LANGUAGE plpgsql;
Since you only want to return a scalar value use
EXECUTE .. INTO ...
- optionally you can assign to theOUT
parameter directly.RETURN QUERY EXECUTE ..
is for returning a set of values.Use
format()
to conveniently escape identifiers and avoid SQL injection. Provide identifiers names case sensitive!filetitle
is not the same asfileTitle
in this context.Use an
OUT
parameter to simplify your code.
来源:https://stackoverflow.com/questions/39808133/how-to-get-the-value-of-a-dynamically-generated-field-name-in-pl-pgsql