簡體   English   中英

sql:使用動態列和值更新動態表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM