当在PostgreSQL中插入一行时,如何自动填充外键

发布于 2025-02-02 06:33:43 字数 1586 浏览 3 评论 0原文

我目前正在Postgres 14下工作。 我有两个桌子的客户和联系人,当我在桌面联系人中添加新联系人时,我想自动从客户名称中找到客户。

CREATE TABLE customers(
   customer_id INT GENERATED ALWAYS AS IDENTITY,
   customer_name VARCHAR(255) NOT NULL UNIQUE,
   PRIMARY KEY(customer_id)
);

CREATE TABLE contacts(
   contact_id INT GENERATED ALWAYS AS IDENTITY,
   customer_id INT,
   contact_name VARCHAR(255) NOT NULL UNIQUE,
   PRIMARY KEY(contact_id),
   CONSTRAINT fk_customer
      FOREIGN KEY(customer_id) 
      REFERENCES customers(customer_id)
);

INSERT INTO customers(customer_name) VALUES('my_first_customer')

因此,从这里我想做这样的事情:

INSERT INTO contacts(customer_id, contact_name ) VALUES('my_first_customer',"thomas")

我想在联系人表中获得此结果:

contact_idcustomer_idcontact_name
11“ thomas”,

我试图制定一个函数以将值从名称更改为id,但要获得类型错误。 因为在触发之前被捕获的类型误差。这是我的功能

CREATE FUNCTION get_id_fct() 
RETURNS TRIGGER AS $get_id_fct$
DECLARE val_id INTEGER;
BEGIN 
SELECT customer_id INTO val_id FROM customers WHERE customers.customer_id = NEW.customer_id;
NEW.customer_id := val_id; 
RETURN NEW
END
$get_id_fct$  LANGUAGE plpgsql;

CREATE TRIGGER get_id
BEFORE INSERT ON contacts
FOR EACH ROW EXECUTE PROCEDURE get_id_fct();'

是他们解决的方法吗?还是我不知道执行此任务的具体方法? 我是SQL的初学者。

I am currently working under postgres 14.
I got two tables customers and contacts, and i want to automatically find the customer_id from the customer name when i add a new contact in the table contacts.

CREATE TABLE customers(
   customer_id INT GENERATED ALWAYS AS IDENTITY,
   customer_name VARCHAR(255) NOT NULL UNIQUE,
   PRIMARY KEY(customer_id)
);

CREATE TABLE contacts(
   contact_id INT GENERATED ALWAYS AS IDENTITY,
   customer_id INT,
   contact_name VARCHAR(255) NOT NULL UNIQUE,
   PRIMARY KEY(contact_id),
   CONSTRAINT fk_customer
      FOREIGN KEY(customer_id) 
      REFERENCES customers(customer_id)
);

INSERT INTO customers(customer_name) VALUES('my_first_customer')

So from here i want to do something like that :

INSERT INTO contacts(customer_id, contact_name ) VALUES('my_first_customer',"thomas")

and i want to get this result in contacts table :

contact_idcustomer_idcontact_name
11"thomas"

i tried to make a function to change the value from name to id but get an error of type.
Because the the type error is catch before the trigger. Here is my function

CREATE FUNCTION get_id_fct() 
RETURNS TRIGGER AS $get_id_fct$
DECLARE val_id INTEGER;
BEGIN 
SELECT customer_id INTO val_id FROM customers WHERE customers.customer_id = NEW.customer_id;
NEW.customer_id := val_id; 
RETURN NEW
END
$get_id_fct$  LANGUAGE plpgsql;

CREATE TRIGGER get_id
BEFORE INSERT ON contacts
FOR EACH ROW EXECUTE PROCEDURE get_id_fct();'

Is their a way around that ? or specific method to do this task that i don't know about ?
I am quite a beginner at SQL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

满栀 2025-02-09 06:33:43

您可以在插入语句中进行副查询,

INSERT INTO contacts(customer_id, contact_name ) VALUES (
(select customer_id from customers where customer_name = 'my_first_customer') ,'thomas');

如果有一个以上的客户名称有多个客户,并且如果没有给定名称

不同的方法(@WildPlasser提出)

INSERT INTO contacts(customer_id, contact_name ) 
select customer_id,'thomas' from customers where customer_name = 'my_first_customer';

,则将失败,并为Customer_id插入null值,在这种情况下,当没有给定名称的客户时,将不会创建行。当有多个具有给定名称的客户时,将创建每个记录。

或者,您可以使用而不是触发器创建视图。

create view v_contacts as 
select customer_name, contact_name from customers 
  join contacts on customers.customer_id = contacts.customer_id;
CREATE FUNCTION emp () RETURNS trigger AS $
BEGIN
    
  INSERT INTO contacts(customer_id, contact_name ) 
    VALUES((select customer_id from customers where customer_name = 
       NEW.customer_NAME),NEW.contact_NAME);
    
    RETURN NULL;
END;
$ LANGUAGE plpgsql;

CREATE TRIGGER v_contactst
    INSTEAD OF INSERT ON v_contacts
    FOR EACH ROW
EXECUTE FUNCTION emp();    

插入语句

INSERT INTO v_contacts(customer_name, contact_name ) VALUES('my_first_customer','thomas')

,只是注:列customer_namecontact_name不是唯一的,因此此代码不安全,如果customer_name没有存在此customer_name有多个记录

You can make a subquery in insert statement

INSERT INTO contacts(customer_id, contact_name ) VALUES (
(select customer_id from customers where customer_name = 'my_first_customer') ,'thomas');

This query will fail if there is more than one customer with given name, and insert a null value for customer_id if there is no customers with given name

Different approach (proposed by @wildplasser)

INSERT INTO contacts(customer_id, contact_name ) 
select customer_id,'thomas' from customers where customer_name = 'my_first_customer';

In this case, when there is no customer with given name, no row will be created. When there is more than one customer with given name, for each of them record will be created.

Or you can create view with INSTEAD OF trigger.

create view v_contacts as 
select customer_name, contact_name from customers 
  join contacts on customers.customer_id = contacts.customer_id;
CREATE FUNCTION emp () RETURNS trigger AS $
BEGIN
    
  INSERT INTO contacts(customer_id, contact_name ) 
    VALUES((select customer_id from customers where customer_name = 
       NEW.customer_NAME),NEW.contact_NAME);
    
    RETURN NULL;
END;
$ LANGUAGE plpgsql;

CREATE TRIGGER v_contactst
    INSTEAD OF INSERT ON v_contacts
    FOR EACH ROW
EXECUTE FUNCTION emp();    

Insert statement

INSERT INTO v_contacts(customer_name, contact_name ) VALUES('my_first_customer','thomas')

And just a note, that columns customer_name and contact_name are not unique so this code is not safe and throw error if customer_name didn't exists or there is more than one record with this customer_name

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文