开发者

How to insert row in table with foreign key to itself?

I have table that has foreign key for itself. Column parentid is for开发者_运维知识库eign key and it cannot be NULL.

if I doINSERT INTO mytable(name) VALUES('name'), so it says that can't insert NULL to parentid. 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


Remove the NOT NULL constraint, as it is an inappropriate constraint. If you do not have a ParentId then the value is NULL and should be allowed. Creating a dummy row just to have a dummy parentid creates unnecessary dependencies.


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. And do it in a transaction.


Disable the FK in charge. Then do the insert Then do an update with the new (generated?) PK-ID into the Self-FK-Field Then Enable the FK back.

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:

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.

But as others said, it might be better to just remove the NOT NULL constraint from the parentid field.


You can alter the column to allow null then set the fk to the new identity and enable not null again.

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.

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

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. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜