【问题标题】:How can I fill empty table rows which references another table's column ID?如何填充引用另一个表的列 ID 的空表行?
【发布时间】:2017-04-19 15:12:05
【问题描述】:

我想为每个已经存在的用户填写空的 notification_settings。 ID (PK) 由 Hibernate 在每个表中自动生成。这是用户表:

CREATE TABLE lottery_user (
    id int8 not null,
    email varchar(255) not null,
    password varchar(255) not null,
    notification_settings_id int8,
    role varchar (50) default 'USER',
    registry_date TIMESTAMP  default now(),
    primary key (id)
ADD CONSTRAINT FK_USER_TO_NOTIFICATION_SETTINGS
FOREIGN KEY (notification_settings_id) REFERENCES notification_settings
);

这是我需要为没有为他们填写的用户填写的 notification_settings 表。

CREATE TABLE notification_settings (
 id int8 not NULL ,
 test1_events bool DEFAULT TRUE ,
 test2_events bool DEFAULT TRUE ,
 test3_events bool DEFAULT TRUE ,
 test4_events bool DEFAULT TRUE ,
 PRIMARY KEY (id)
);

基本上,我需要使用"INSERT INTO notification_settings (test1_events, test2_events, test3_events, test4_events) VALUES (True, True, True, True)" 类似的东西。当然,条件应该是这样的“这些行对用户来说是空的”。我似乎无法正确使用语法。

重要说明: SQL 代码用于演示目的,因此您可以知道我有什么样的表。我只需要正确插入脚本。表工作正常,只需要为已经存在的用户生成 notification_settings 值。

另一个注意事项:使用 Flyway,因此它不仅仅是关于 Hibernate。如果这与任何事情有关。

【问题讨论】:

  • 当您将DEFAULT 值添加到表notification_settings 时,它们将始终为TRUE。只需插入id
  • ID 是由 Hibernate 自动生成的,我该怎么做?
  • 您能解释一下您的数据模型吗?在当前模型中,user 链接到notification_settings,您只需将notification_settings_id int8 的默认值设置为包含true, true, true, true 的(一个)id。虽然我不完全确定这就是你要找的。您可能想使用notification_settings 中的用户标识而不是新标识。然后你可以在你的user-table 上使用insert-trigger 来做到这一点。您也可以将 4 列添加到 user 表本身,而根本没有第二个表。
  • 不,我不需要在notification_settings 中使用userId FK。我对问题进行了一些编辑,对于我造成的任何混乱,我深表歉意。我只需要为已经存在但没有填写的用户填写第二个表。我已经得到了几个可能有帮助的答案。感谢您的关注。

标签: sql database postgresql hibernate


【解决方案1】:

您只是在寻找:

INSERT INTO notification_settings (id)

SELECT       id
FROM         user
WHERE        id NOT IN (SELECT id FROM notifiation_settings)

您可能希望插入身份字段:

SET IDENTITY_INSERT my_table ON

【讨论】:

  • 它的工作就像另一个答案一样,但是 notification_settings_id 保持为空,应该分别用 notification_settings 填充。
【解决方案2】:

由于您的外键约束从 notification_settings 到用户,“这些行对于用户 X 为空”的条件不适用于您的架构。另一方面 - “我想为每个已经存在的用户填写空的 notification_settings”可以通过使用 insert...select 构造来完成:

set @rank=0
select @maxid = max(id) from notification_settings

insert into notification_settings (id)
select @maxid + @rank:=@rank+1 as rank
from user
where notification_settings_id is null

有趣的是您如何将这些新生成的 ID 放回用户表中。下一次的家庭作业:)

【讨论】:

    【解决方案3】:

    插入到 notification_settings (id)

    选择 u.id 来自用户你 在哪里
    不存在(SELECT * FROM notifiation_settings ns where ns.id=i.id)

    【讨论】:

    • 它做的工作,但notification_settings_id保持为空,它应该根据notification_settings填写。
    • 我可以调整它,但是,在我的示例中,notification_settings_id 将始终 = user.Id 也许这是错误的。用户是否可以拥有一组以上的通知?
    【解决方案4】:

    我将回答我自己的问题,我是如何处理它的。首先,我将 ID 插入notification_settings id,然后获取这些 ID 并将它们设置到 lottery_user 表的 FK (notification_settings_id) 中。然后我只删除不需要的 ID。是的,不完美,但它有效。

    INSERT INTO notification_settings  (id) select lu.id from lottery_user lu where lu.id not in(select ns.id from notification_settings ns);
    
    update lottery_user lu set notification_settings_id = (select ns.id from notification_settings ns where ns.id = lu.id) where lu.notification_settings_id is null;
    
    delete from notification_settings ns where not exists (select * from lottery_user lu where lu.notification_settings_id = ns.id);
    

    另外,为新的 Lottery_user 实体更改序列的脚本。

    do $$
    declare maxid int;
    begin
    select max(id) from lottery_user into maxid;
    IF maxid IS NOT NULL THEN
    EXECUTE 'ALTER SEQUENCE notification_settings_seq START with '|| maxid;
    END IF;
    end;
    $$ language plpgsql;
    

    【讨论】:

      猜你喜欢
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 2017-03-02
      • 2017-03-02
      相关资源
      最近更新 更多