patternsqlMinor
Dynamic casting from text within plpgsql
Viewed 0 times
textcastingwithinplpgsqldynamicfrom
Problem
Many tables in my database share a common layout, in particular they have a
This is so common that I have a stored procedure that performs this task:
Unfortunately this doesn't work for non-text types. For instance, updating a
serial primary key named after the relation name. Updating these tables from within a web application often involves a query of the form:UPDATE table SET attribute = x WHERE table_id = yThis is so common that I have a stored procedure that performs this task:
CREATE OR REPLACE FUNCTION setvalue(
relname text,
row_id integer,
colname text,
newvalue text)
RETURNS void AS
$BODY$
BEGIN
EXECUTE format('UPDATE %I SET %I = $1 WHERE %I = $2', relname, colname, relname || '_id', colname) USING row_id;
END;
$BODY$
LANGUAGE plpgsql;Unfortunately this doesn't work for non-text types. For instance, updating a
date column gives ERROR: column ... is of type date but expression is of type text. Assuming the text is a valid literal representation of the intended type, is there a safe way to get the DBMS to figure out the right type and do the right thing?Solution
My own solution so far is to paste the string literal into the query:
or just
This works for, e.g., appropriately formatted date types (
EXECUTE format(
'UPDATE %I SET %I = ' || quote_literal(newvalue) || ' WHERE %I = $1 ',
relname, colname, relname || '_id') USING row_id;or just
EXECUTE format(
'UPDATE %I SET %I = %L WHERE %I = $1',
relname, colname, newvalue, relname || '_id') USING row_id;This works for, e.g., appropriately formatted date types (
'1990-05-04'). Probably this sacrifices being able to re-use query plan.Code Snippets
EXECUTE format(
'UPDATE %I SET %I = ' || quote_literal(newvalue) || ' WHERE %I = $1 ',
relname, colname, relname || '_id') USING row_id;EXECUTE format(
'UPDATE %I SET %I = %L WHERE %I = $1',
relname, colname, newvalue, relname || '_id') USING row_id;Context
StackExchange Database Administrators Q#111507, answer score: 4
Revisions (0)
No revisions yet.