我table有自己的外键。列 parentid 是外键,不能为NULL。
如果我INSERT INTO mytable(name) VALUES('name')
,则表示无法向 parentid 插入NULL。但是,如果还没有插入行,我可以设置什么值?!
如何编写将向该表添加行的脚本?
谢谢
答案 0 :(得分:5)
技巧:有一个带虚拟键的虚拟行,比如说99999.将其作为FK插入,然后将FK更改为其实际值。并在交易中完成。
答案 1 :(得分:5)
删除NOT NULL约束,因为它是一个不合适的约束。如果您没有ParentId,则值为NULL并且应该被允许。创建一个虚拟行只是为了产生一个虚拟的parentid会产生不必要的依赖。
答案 2 :(得分:2)
如何使id
和parentid
等于-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 |
如果您要将其他表中的许多数据传输到此表中,可以将IDENTITY_INSERT变量设置为ON,插入数据然后再将其设置为OFF。
但正如其他人所说,最好从NOT NULL
字段中删除parentid
约束。
答案 3 :(得分:2)
禁用FK负责人。 然后插入 然后使用新的(生成的?)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]
答案 4 :(得分:1)
您可以将列更改为允许null,然后将fk设置为新标识,并再次启用not null。
这应该有用,但也许有更好的方法
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
答案 5 :(得分:1)
根据我的理解,您在插入之前已经拥有了id,并且您无法插入它,因为身份字段不允许您这样做。
就像你在评论中提到的那样:
在1个表格中我有第34行'name1' 34,35'name2'34(id,name,parentid) 我想把它们复制到其他表
第一张表
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)
第二张表:
create table Table2
(
id int identity(1, 1) primary key,
name varchar(20) not null,
parentId int not null foreign key references Table2(id)
)
将数据从第一个表复制到第二个表:
set identity_insert Table2 on
insert Table2(id, name, parentId)
select *
from Table1
set identity_insert Table2 on
<强> [更新] 强>
如果第二个表已经有值:
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
答案 6 :(得分:0)
不要将IDENTITY列引用为自引用外键。请改用表格的替代键。我猜您使用IDENTITY作为代理键,但每个表都应该有一个自然键,因此IDENTITY列不应该是表的唯一键。