If I have a table
Table
{
ID int primary key identity,
ParentID int not null foreign key references Table(ID)
}
how does one insert first row into a table?
From a business logic point of view not null constraint on ParentID should not be dropped.
Self-referencing table is a table that is a parent and a dependent in the same referential constraint. I. e. in such tables a foreign key constraint can reference columns within the same table.
Basic INSERT syntax Here is the basic syntax for adding rows to a table in SQL: INSERT INTO table_name (column1, column2, column3,etc) VALUES (value1, value2, value3, etc); The first line of code uses the INSERT statement followed by the name of the table you want to add the data to.
Referenced Tables allow a category's or case. definition's index fields to reference data in an external database. This provides a convenient way to link an index field to a database table from another system.
In SQL Server, a simple INSERT will do:
create table dbo.Foo
(
ID int primary key identity,
ParentID int not null foreign key references foo(ID)
)
go
insert dbo.Foo (parentId) values (1)
select * from dbo.Foo
results in
ID ParentID
----------- -----------
1 1
If you're trying to insert a value that will be different from your identity seed, the insertion will fail.
UPDATE:
The question is not too clear on what the context is (i.e. is the code supposed to work in a live production system or just a DB setup script) and from the comments it seems hard-coding the ID might not be an option. While the code above should normally work fine in the DB initialization scripts where the hierarchy root ID might need to be known and constant, in case of a forest (several roots with IDs not known in advance) the following should work as intended:
create table dbo.Foo
(
ID int primary key identity,
ParentID int not null foreign key references foo(ID)
)
go
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
Then one could query the last identity as usual (SCOPE_IDENTITY
, etc.). To address @usr's concerns, the code is in fact transactionally safe as the following example demonstrates:
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
select * from dbo.Foo
select IDENT_CURRENT('dbo.Foo')
begin transaction
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
rollback
select IDENT_CURRENT('dbo.Foo')
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
select * from dbo.Foo
The result:
ID ParentID
----------- -----------
1 1
2 2
3 3
currentIdentity
---------------------------------------
3
currentIdentity
---------------------------------------
4
ID ParentID
----------- -----------
1 1
2 2
3 3
5 5
If you need to use an explicit value for the first ID, when you insert your first record, you can disable the checking of the IDENTITY value (see: MSDN: SET IDENTITY_INSERT (Transact-SQL)).
Here's an example that illistrates this:
CREATE TABLE MyTable
(
ID int PRIMARY KEY IDENTITY(1, 1),
ParentID int NOT NULL,
CONSTRAINT MyTable_ID FOREIGN KEY (ParentID) REFERENCES MyTable(ID)
);
SET IDENTITY_INSERT MyTable ON;
INSERT INTO MyTable (ID, ParentID)
VALUES (1, 1);
SET IDENTITY_INSERT MyTable OFF;
WHILE @@IDENTITY <= 5
BEGIN
INSERT INTO MyTable (ParentID)
VALUES (@@IDENTITY);
END;
SELECT *
FROM MyTable;
IF OBJECT_ID('MyTable') IS NOT NULL
DROP TABLE MyTable;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With