简体   繁体   English

如何在表中插入带有外键的行?

[英]How to insert row in table with foreign key to itself?

I have table that has foreign key for itself. 我有自己的外键 Column parentid is foreign key and it cannot be NULL. parentid是外键, 不能为NULL。

if I do INSERT INTO mytable(name) VALUES('name') , so it says that can't insert NULL to parentid . 如果我执行INSERT INTO mytable(name) VALUES('name') ,那么它表示无法向parentid插入NULL。 BUT, what value I can set to it if no row was inserted yet?! 但是,如果没有插入行,我可以设置什么值?!

How I can write script that will add row to this table? 我如何编写将向该表添加行的脚本?

Thank you 谢谢

A trick: Have a dummy row with a dummy key, say 99999. Insert with this as the FK, and then change the FK to its real value. 一个技巧:有一个带虚拟键的虚拟行,比如99999.用此作为FK插入,然后将FK更改为其实际值。 And do it in a transaction. 并在交易中完成。

Remove the NOT NULL constraint, as it is an inappropriate constraint. 删除NOT NULL约束,因为它是一个不合适的约束。 If you do not have a ParentId then the value is NULL and should be allowed. 如果您没有ParentId,则值为NULL并且应该被允许。 Creating a dummy row just to have a dummy parentid creates unnecessary dependencies. 创建虚拟行只是为了产生虚拟parentid会产生不必要的依赖关系。

Disable the FK in charge. 禁用FK负责。 Then do the insert Then do an update with the new (generated?) PK-ID into the Self-FK-Field Then Enable the FK back. 然后执行插入然后使用新的(生成的?)PK-ID更新到Self-FK-Field然后启用FK。

LIke so: 喜欢这样:

ALTER TABLE [Client] NOCHECK CONSTRAINT [FK_Client_MainClient]
INSERT INTO Client VALUES ...
@ClientID = SCOPE_IDENTITY()
IF @IsMainClient=1  
BEGIN
    UPDATE [Client] 
    SET MainClientID = @ClientID 
    WHERE ClientID = @ClientID 
END 
ALTER TABLE [Relatie] WITH CHECK CHECK CONSTRAINT [FK_Relatie_Relatie]

How to make a dummy row with both id and parentid equal to -1 : 如何使idparentid等于-1的虚拟行:

CREATE TABLE mytable(
    id int NOT NULL IDENTITY,
    parentid int  NOT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (parentid) REFERENCES mytable(id)
)  ;


SET IDENTITY_INSERT mytable ON ;      <-- this allows you to insert the 
INSERT INTO mytable(id, parentid)     <-- auto incremented identity field
    VALUES (-1, -1);
SET IDENTITY_INSERT mytable OFF ;

SELECT * FROM mytable ;

| id | parentid |
| -1 | -1       |

If you have many data from other tables that you want to transfer into this table, you can set the IDENTITY_INSERT variable to ON, insert the data and then set it to OFF again. 如果要将其他表中的许多数据传输到此表中,可以将IDENTITY_INSERT变量设置为ON,插入数据,然后再将其设置为OFF。

But as others said, it might be better to just remove the NOT NULL constraint from the parentid field. 但正如其他人所说,从parentid字段中删除NOT NULL约束可能更好。

You can alter the column to allow null then set the fk to the new identity and enable not null again. 您可以将列更改为允许null,然后将fk设置为新标识并再次启用not null。

This should work, though maybe there is a better way 这应该有用,但也许有更好的方法

CREATE TABLE mytable
(
 id int IDENTITY(1,1) primary key,
 name varchar(50) not null,
 parentid int not null
)
go
alter table mytable
add constraint FK_mytable_parentid FOREIGN KEY ( parentid ) references mytable(id)

ALTER TABLE mytable alter column parentid int null;

insert into mytable(name)
select 'test'

update mytable
set parentid = SCOPE_IDENTITY()
where id = SCOPE_IDENTITY()

ALTER TABLE mytable alter column parentid int not null;

select * from mytable
drop table mytable

From what I understood you already have id before inserting and you can't insert it because identity field isn't letting you to. 根据我的理解,你在插入前已经有了id,你不能插入它,因为身份字段不允许你。

Like you mentioned in your comment: 就像你在评论中提到的:

in 1 table I have the rows 34 'name1' 34, 35 'name2' 34 (id,name,parentid) and I want to copy them to other table 在1表中,我有行34'name1'34,35'name2'34(id,name,parentid),我想将它们复制到其他表

First table 第一张桌子

create table Table1
(
    id int not null primary key,
    name varchar(20) not null,
    parentId int not null
)

insert Table1
values
    (34, 'name1', 34),
    (35, 'name2', 34)

Second table: 第二表:

create table Table2
(
    id int identity(1, 1) primary key,
    name varchar(20) not null,
    parentId int not null foreign key references Table2(id)
)

Copying data from the first table to the second one: 将数据从第一个表复制到第二个表:

set identity_insert Table2 on

insert Table2(id, name, parentId)
select *
from  Table1

set identity_insert Table2 on

[Update] [更新]

If the second table already has values then: 如果第二个表已经有值,那么:

alter table Table2
    add oldId int null

alter table Table2
    alter column parentId int null
go

insert Table2(name, oldId)
select name, id
from  Table1

update tt3
set parentId = tt2.id
from Table2 tt3
    join Table1 tt1 on
        tt1.id = tt3.oldId
    join Table2 tt2 on
        tt1.parentId = tt2.oldId

alter table Table2
    drop column oldId

alter table Table2
    alter column parentId int not null

Don't reference an IDENTITY column as a self-referencing foreign key. 不要将IDENTITY列引用为自引用外键。 Use an alternative key of the table instead. 请改用表格的替代键。 I guess you are using IDENTITY as a surrogate key but every table ought to have a natural key as well, so the IDENTITY column shouldn't be the only key of your table. 我猜你使用IDENTITY作为代理键,但每个表都应该有一个自然键,所以IDENTITY列不应该是你表的唯一键。

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

相关问题 用外键将行插入表中 - Insert row into a table with foreign key 是否可以在FOREIGN KEY的子表中插入行? - Is it possible to insert row into the child table of FOREIGN KEY? 在PHP中使用外键将行插入表中 - Insert row into a table with foreign key inside PHP 如何在表中插入外键 - how to insert foreign key in a table 当表本身存在外键约束时,postgresql 多次插入如何工作? - How postgresql multiple insert works when there is foreign key constraint in the table itself? SQL-SERVER 程序如何在一个表中插入行,然后将行插入到另一个表中作为外键链接到另一个表 - SQL-SERVER Procedure How do i insert row one table then insert row into another table link to another table as foreign key 如何在我的数据库中插入具有外键的行而不在链接表中添加行? - How can I insert a row in my database that has a foreign key without adding a row in the linked table? 如何使用引用复合主键的复合外键将行插入到表中 - How to insert a row into a table with a composite foreign key referencing a composite primary key 如何根据同一个表中的外键将一个表与自身连接起来? - How to join a table with itself based on a foreign key in same table? 用外键插入表中 - Insert into table with a foreign key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM