[英]sql: update dynamic table with dynamic columns and values
目標:我想創建一個可以更新表的函數,並且條件(在哪里)是動態的。如下:
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;
-當然,它不能通過! -問題:-如何為列設置值? -因為表格是動態的,所以列的類型是未知的!
我改變了功能:
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;
經過一些測試:我通過了參數: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}]'
和我得到的SQL字符串為:更新測試集名稱=“ ssqhan”,工資=“ 5200.00”,其中1 = 1和ID =“ 1”
但是,這不是我的意思:id int名稱文本,salay號! sql應該像:更新測試集名稱=“ ssqhan”,工資= 5200.00其中1 = 1和id = 1,這就是我想要的。
我得到了另一個這樣的代碼:
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;
當我將參數傳遞為:'test'時,'[{“ feild_name”:“ name”,“ feild_value”:“ ssqhan”},{“ feild_name”:“ salary”,“ feild_value”:5200.00}]'',' [{“ feild_name”:“ id”,“ feild_value”:2}]'
返回SQL,如:update test set name ='ssqhan',salary = 5200.00 where 1 = 1 and id = 2
是的,這就是我想要的,當數據類型是文本或數字時,這可能有效,但是如果數據類型是復合的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.