使用共享标识主键

时间:2016-04-14 08:43:52

标签: sql-server database stored-procedures identity

我已经将一些表链接在一起,其中应该使用存储过程插入数据。表格是:

create table contactpersoon
(
    contactpersoonnr    integer identity(1,1),
    klantnr             integer,
    naam                varchar(50) not null,
    telefoonnr          varchar(10) not null,
    emailadres          varchar(50) not null,

    constraint pk_contactpersoon 
        primary key(contactpersoonnr, klantnr),
    constraint fk_contactpersoon_klantnr 
        foreign key(klantnr) references klant(klantnr)
)

create table klant 
(
    klantnr        integer identity(1,1) primary key,
    bedrijfsnaam   varchar(50) not null
)

create table Logins
(
    GebruikersNaam  varchar(30),
    Wachtwoord      varchar(30),
    Klantnr         int,
    MdwNr           int,

    constraint pk_logID primary key(GebruikersNaam),
    constraint fk_klantnr foreign key(klantnr) references klant(klantnr),
    constraint fk_mdwnr foreign key(mdwnr) references medewerker(mdwnr)
)

向这些表添加数据的存储过程:

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'spKlantAanmaken') 
   DROP PROCEDURE spKlantAanmaken
GO 

Create Procedure spKlantAanmaken
(
    @bedrijfsnaam as varchar(255),
    @contactnaam as varchar(255),
    @telnr as integer,
    @email as varchar(255),
    @gebruikersnaam as varchar(255),
    @wachtwoord as varchar(255)
)
AS
Begin transaction 
Declare @klantnr integer
Declare @contactpersoonnr integer

Insert into Klant Values (@klantnr, @bedrijfsnaam);
Insert into contactpersoon values(@contactpersoonnr, @klantnr, @contactnaam, @telnr, @email);
Insert into Logins values (@gebruikersnaam, @wachtwoord ,@klantnr, NULL);
Select * from contactpersoon
    IF @@ERROR <> 0 
    BEGIN 
        ROLLBACK 
        RAISERROR ('Error tijdens uitvoeren van stap 2.', 16, 1) 
        RETURN 
    END 
    COMMIT 
GO

我不知道是否有必要在插入中使用这些标识值。 如果我尝试这个存储过程,我会收到以下错误:

  

Msg 8101,Level 16,State 1,Procedure spKlantAanmaken,Line 923
  表格中的标识列的显式值&#39; Klant&#39;只能是   使用列列表且IDENTITY_INSERT为ON时指定。

如果我从插入中删除标识值,我会收到此错误:

  

Msg 213,Level 16,State 1,Procedure spKlantAanmaken,923行   列名或提供的值数与表定义不匹配。

我做错了什么?

5 个答案:

答案 0 :(得分:1)

由于您有identity列,必须INSERT语句中指定要插入的列的列表,不提供标识列的值 - 如下所示:

而不是

Insert into Klant Values (@klantnr, @bedrijfsnaam);

使用

Insert into Klant(bedrijfsnaam) Values (@bedrijfsnaam);

并为所有您的INSERT操作执行此操作。

这是任何时间在表格中插入内容时普遍接受的“最佳做法” - 建议始终明确指定表格中的列表您正在插入(以避免恼人的错误和意外)。

答案 1 :(得分:1)

使用Identity时,应用identity的列不必位于INSERT声明VALUES中。所以编辑你的代码如下

修改

您似乎也错过了要插入

的列
Insert into Klant (bedrijfsnaam) Values (@bedrijfsnaam)
Insert into contactpersoon (klantnr, contactnaam, telnr, email) Values (@klantnr, @contactnaam, @telnr, @email)

似乎所有的答案都说同样的事情,所以希望你的问题得到解决

答案 2 :(得分:0)

在SP中编辑这两行

Insert into Klant (bedrijfsnaam) 
Values (@bedrijfsnaam);
Insert into contactpersoon(klantnr,naam,telefoonnr,emailadres)
values(@klantnr, @contactnaam, @telnr, @email);

提供列列表,不包括identity语句中的insert

答案 3 :(得分:0)

避免INSERT查询中的identityklantnrcontactpersoonnr并明确定义列名称:

以下代码适用于您的情况:

Insert into Klant(bedrijfsnaam) Values (@bedrijfsnaam);

Insert into contactpersoon(klantnr, naam, telefoonnr, emailadres) values(@klantnr, @contactnaam, @telnr, @email);

答案 4 :(得分:0)

只需在INSERT语句中指定列名和内容,如:

INSERT INTO klant (bedrijfsnaam) VALUES ('XYZ');

如果没有指定列名列表,那么SQL解释器暗示,您也需要标识列。在这种情况下,您可能希望为2列设置数据,但只提供一个内容元素,这解释了后面的错误消息。