target: i wanna create a function which can update table,and the condition(in where) is dynamic .as following:
create or replace function f_update(
tablename text, --the table name updated
update_fields text, --fields and values as json
--[{"fieldName":"id","fieldValue":1},
--{"fieldName":"name","fieldValue":"admin"},
--{"fieldName":"salary,"fieldValue":6000.00}]
condition_fields text, --condition: json like above
out return_value text --return value
) as $$
declare
ex_sql text;
recs record;
begin
ex_sql:='update '||quote_ident(tablename)||' set ';
--set values to the column
for recs in select * from json_to_recordset(update_fields::json) as x( field_name text,field_value text) loop
if json_typeof(recs.field_value) ='numeric' then
ex_sql:=ex_sql|| recs.field_name || '=' || recs.field_value ||',';
else
ex_sql:=ex_sql|| recs.field_name || '='''|| recs.field_value || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql)-1);
--setting conditions
ex_sql:=ex_sql||' where 1=1';
for recs in select * from json_to_recordset(condition_fields::json) as x( field_name text,field_value text) loop
if json_typeof(recs.field_value) ='numeric' then
ex_sql:=ex_sql|| ' and ' || recs.field_name || '=' || recs.field_value ||',';
else
ex_sql:=ex_sql|| ' and ' || recs.field_name || '='''|| recs.field_value || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql)-1);
return_value:=ex_sql;
end;
$$ language plpgsql;
--of cource ,it cannot pass! --the question: --how to set value to the columns? --because the table is dynamic,so the type of the column is unknown!
i changed the function:
create or replace function f_update(
tablename text,
update_feilds text,
condition_feilds text,
out return_value text
) as $$
declare
ex_sql text;
recs record;
begin
ex_sql:='update '||quote_ident(tablename)||' set ';
for recs in select * from json_to_recordset(update_feilds::json) as x( feild_name text,feild_value text) loop
if json_typeof(to_json(recs.feild_value)) ='number' then
ex_sql:=ex_sql|| recs.feild_name || '=' || recs.feild_value ||',';
else
ex_sql:=ex_sql|| recs.feild_name || '='''|| recs.feild_value || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql));
ex_sql:=ex_sql||' where 1=1';
for recs in select * from json_to_recordset(condition_feilds::json) as x( feild_name text,feild_value text) loop
if json_typeof(to_json(recs.feild_value)) ='number' then
ex_sql:=ex_sql|| ' and ' || recs.feild_name || '=' || recs.feild_value ||',';
else
ex_sql:=ex_sql|| ' and ' || recs.feild_name || '='''|| recs.feild_value || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql));
return_value:=ex_sql;
end;
$$ language plpgsql;
after some testing: i pass the parameters like : tableName:'test' update_feilds '[{"field_name":"name","field_value":"ssqhan"},{"field_name":"salary","field_value":5200.00}]' condition_feilds '[{"field_name":"id,"field_value":1}]'
and i got the sql string as: update test set name='ssqhan',salary='5200.00' where 1=1 and id='1'
however,this is not what i mean: id int name text, salay number! sql should be like: update test set name='ssqhan',salary=5200.00 where 1=1 and id=1, that's what i want.
i got another code like that:
create or replace function f_update_all(
tablename text,
update_feilds text,
condition_feilds text,
out return_value text
) as $$
declare
ex_sql text;
recs record;
_key text ;
_value text;
begin
ex_sql:='update '||quote_ident(tablename)||' set ';
--setting values for updated table
for recs in select * from json_array_elements(update_feilds::json) loop
_key := recs.value ->> 'feild_name';
_value := recs.value ->> 'feild_value' ;
if json_typeof(recs.value -> 'feild_value') ='number' then
ex_sql:=ex_sql|| _key || '=' || _value ||',';
else
ex_sql:=ex_sql|| _key || '='''|| (recs.value ->> 'feild_value') || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql));
--setting condition in where
ex_sql:=ex_sql||' where 1=1';
for recs in select * from json_array_elements(condition_feilds::json) loop
_key := recs.value ->> 'feild_name';
_value := recs.value ->> 'feild_value' ;
if json_typeof(recs.value -> 'feild_value') ='number' then
ex_sql:=ex_sql|| ' and ' || _key || '=' || _value ||',';
else
ex_sql:=ex_sql|| ' and ' || _key || '='''|| (recs.value ->> 'feild_value') || ''',';
end if;
end loop;
ex_sql:= substring(ex_sql from 0 for length(ex_sql));
return_value:=ex_sql;
end;
$$ language plpgsql;
when i pass the parameters as : 'test' ,'[{"feild_name":"name","feild_value":"ssqhan"},{"feild_name":"salary","feild_value":5200.00}]' ,'[{"feild_name":"id","feild_value":2}]'
the return sql like: update test set name='ssqhan',salary=5200.00 where 1=1 and id=2
Yeah,this what i want ,this may work when the datatype is text or number, but if the data type is composited?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.