简体   繁体   中英

PostgreSQL - Updating a column value based on another value

I have been trying to accomplish an automatic update of a table based on a column value. Here is the example. The idea is that the user will enter their phone, but not their country like this:

mobile_phone country
'51682815'
'51261728'
'56682815'
'56261728'
'57682815'
'57261728'

Based on the " mobile_phone " information I want to assign their country automatically with this logic:

  • WHERE left(mobile_phone,2) = '51' then 'PE'
  • WHERE left(mobile_phone,2)='56' then 'CL'
  • WHERE left(mobile_phone,2)='57' then 'CO'

And based on that logic the table should update AUTOMATICALLY with this information:

mobile_phone country
'51682815' 'PE'
'51261728' 'PE'
'56682815' 'CL'
'56261728' 'CL'
'57682815' 'CO'
'57261728' 'CO'

I was thinking to create a trigger like this, but the problem is that I don't know how to create the function that will update the column country:

CREATE TRIGGER update_country AFTER INSERT ON info
FOR EACH ROW EXECUTE PROCEDURE function_name()

Thanks in advance for your help.

Since your records to be updated are already found within your database, you should first use an UPDATE statement to update your current rows. You can do it using a CASE expression that will assign the " country " value conditionally with respect to the " mobile_phone ".

UPDATE "info"
SET country = CASE WHEN LEFT(mobile_phone,2) = '51' THEN 'PE'
                   WHEN LEFT(mobile_phone,2) = '56' THEN 'CL'
                   WHEN LEFT(mobile_phone,2) = '57' THEN 'CO' END;

Then create the corresponding trigger, that will update your record before the insertion. It splits into:

  • the function " update_country() ", which returns a trigger that uses NEW to access values from the inserting row and update its country value
  • the trigger creation definition (which you included in the post as well), that uses " update_country() " to update records featured in the insertion statement.
CREATE OR REPLACE FUNCTION update_country()
RETURNS TRIGGER AS
'
BEGIN
    NEW.country = CASE WHEN LEFT(NEW.mobile_phone,2) = ''51'' THEN ''PE''
                       WHEN LEFT(NEW.mobile_phone,2) = ''56'' THEN ''CL''
                       WHEN LEFT(NEW.mobile_phone,2) = ''57'' THEN ''CO'' END;
    RETURN NEW;
END;
'
LANGUAGE plpgsql;

CREATE TRIGGER update_country_trigger
BEFORE INSERT ON "info"
FOR EACH ROW
EXECUTE PROCEDURE update_country();

Check the demo here .

You can use Generated Columns. With Generated Columns you can not do
update info set country = 'x'; or
insert into info(country) value ('x');
https://www.postgresql.org/docs/current/ddl-generated-columns.html

BEGIN;
CREATE temp TABLE info (
    mobile_phone text
    , country text GENERATED ALWAYS AS ( CASE WHEN
    LEFT (mobile_phone , 2) = '51' THEN
        'PE'
    WHEN
    LEFT (mobile_phone , 2) = '52' THEN
        'XY'
    WHEN
    LEFT (mobile_phone , 2) = '53' THEN
        'AB'
    WHEN
    LEFT (mobile_phone , 2) = '54' THEN
        'CD'
    WHEN
    LEFT (mobile_phone , 2) = '55' THEN
        'EF'
    WHEN
    LEFT (mobile_phone , 2) = '56' THEN
        'CL'
    WHEN
    LEFT (mobile_phone , 2) = '57' THEN
        'CO'
    ELSE
        'NA'
    END) STORED
) ON COMMIT DROP;
INSERT INTO info (mobile_phone)
    VALUES ('51682815')
    , ('51261728')
    , ('56682815')
    , ('56261728')
    , ('57682815')
    , ('57261728');
TABLE info;
END;

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM