简体   繁体   English

PostgreSQL - 根据另一个值更新列值

[英]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' '51682815'
'51261728' '51261728'
'56682815' '56682815'
'56261728' '56261728'
'57682815' '57682815'
'57261728' '57261728'

Based on the " mobile_phone " information I want to assign their country automatically with this logic:基于“ mobile_phone ”信息,我想用这个逻辑自动分配他们的国家:

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

And based on that logic the table should update AUTOMATICALLY with this information:并且基于该逻辑,该表应使用以下信息自动更新:

mobile_phone手机 country国家
'51682815' '51682815' 'PE' 'PE'
'51261728' '51261728' 'PE' 'PE'
'56682815' '56682815' 'CL' 'CL'
'56261728' '56261728' 'CL' 'CL'
'57682815' '57682815' 'CO' '一氧化碳'
'57261728' '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:我正在考虑创建这样的触发器,但问题是我不知道如何创建将更新列国家/地区的 function:

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.由于要更新的记录已在数据库中找到,因此您应该首先使用UPDATE语句更新当前行。 You can do it using a CASE expression that will assign the " country " value conditionally with respect to the " mobile_phone ".您可以使用CASE表达式执行此操作,该表达式将根据“ mobile_phone ”有条件地分配“ country ”值。

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 function “ update_country() ”,它返回一个触发器,该触发器使用NEW从插入行访问值并更新其国家/地区值
  • the trigger creation definition (which you included in the post as well), that uses " update_country() " to update records featured in the insertion statement.触发器创建定义(您也包含在帖子中),它使用“ update_country() ”更新插入语句中的记录。
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 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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