【问题标题】:SQL Server error.Explicit value for Identity Column....can only be specified when a column list is used and IDENTITY_INSERT is ONSQL Server 错误。标识列的显式值....只能在使用列列表并且 IDENTITY_INSERT 为 ON 时指定
【发布时间】:2013-06-05 21:17:30
【问题描述】:

我正在尝试创建程序,该程序正在生成错误说明

tblRegisterUser中标识列的显式值只能在使用列列表和IDENTITY_INSERT is ON时指定。

我试图用INDENTITY_INSERT to ON 包围插入语句,但这也不起作用。我遗漏了什么还是我包含的子查询有错误?

下面是存储过程

CREATE PROCEDURE dbo.spInsertUserRegister
(
    @FirstName nvarchar(50),
    @LastName nvarchar(50),
    @Username nvarchar(50),
    @Password nvarchar(50),
    @Designation nvarchar(50),
    @Department nvarchar(50),
    @IsAdmin bit
)
AS
BEGIN
    INSERT INTO tblRegisterUser Values
    (
        @FirstName, @LastName, @Username, @Password,@Designation,@Department,@IsAdmin
    )
    DECLARE @UID INT
    SET @UID = @@IDENTITY
    INSERT INTO tblLogin(Username,Password,UID,IsAdmin) 
    Values(@Username, @Password, @UID,(SELECT IsAdmin FROM tblRegisterUser WHERE     Username=@Username AND Password=@Password))
END

【问题讨论】:

  • "that too doesn't work" 不是有效的 SQL Server 错误消息。
  • tblRegisterUser 对应的create table 是什么?
  • 除非有一个触发器改变了您第一次插入的行为,或者您允许多人拥有相同的用户名(顺便说一句,密码),否则(SELECT IsAdmin FROM tblRegisterUser ... 的意义何在?第二个INSERT?为什么不再只是@IsAdmin

标签: sql-server sql-server-2008 stored-procedures


【解决方案1】:

如果tblRegisterUser 表的结构类似于

ID int primary_key autoincrement
FirstName varchar
LastName varchar 
Username varchar
Password varchar
Designation varchar
Department varchar
IsAdmin bit

这个说法是错误的:

INSERT INTO tblRegisterUser Values
(
    @FirstName, @LastName, @Username, @Password, 
    @Designation,@Department,@IsAdmin
)

您应该使用明确的列列表来指定列:

INSERT INTO tblRegisterUser 
(  FirstName, LastName, Username, Password,
   Designation, Department, IsAdmin) 
VALUES 
(
    @FirstName, @LastName, @Username, @Password, 
    @Designation,@Department,@IsAdmin
)

这样 ID 字段会自动填充,@@Identity 语句应该会正确返回它。


也就是说,SQL Server has a few functions 返回为最后一行生成的 ID,每行都有自己的特定优势和劣势。

基本上:

  • 如果您不使用触发器,@@IDENTITY 可以工作
  • SCOPE_IDENTITY() 适用于您明确调用的代码。
  • IDENT_CURRENT(‘tablename’) 适用于所有范围内的特定表。

在几乎所有情况下,SCOPE_IDENTITY() 都是您所需要的,使用它是一个好习惯,与其他选项相反。
here 也可以很好地讨论这些方法的优缺点。

复制自this answer

【讨论】:

  • 谢谢,它现在可以工作了,实际上它是一个身份列,但是我在创建 tblRegisterUser 时错过了一个列,我必须在发布之前做了一些跟踪和错误:(。抱歉发布这样一个愚蠢的问题。
【解决方案2】:

试试这个 -

CREATE PROCEDURE dbo.spInsertUserRegister 
(
    @FirstName NVARCHAR(50),
    @LastName NVARCHAR(50),
    @Username NVARCHAR(50),
    @Password NVARCHAR(50),
    @Designation NVARCHAR(50),
    @Department NVARCHAR(50),
    @IsAdmin BIT
)
AS BEGIN

    INSERT INTO dbo.tblRegisterUser (FirstName, LastName, Username, [Password], Designation, Department, IsAdmin)
    SELECT @FirstName, @LastName, @Username, @Password, @Designation, @Department, @IsAdmin

    DECLARE @ID BIGINT
    SELECT @ID = SCOPE_IDENTITY()

    --SET IDENTITY_INSERT dbo.tblLogin ON;

    INSERT INTO dbo.tblLogin (UserName, [password], [uid], IsAdmin)
    SELECT @Username, @Password, @ID, IsAdmin 
    FROM tblRegisterUser 
    WHERE UserName = @Username 
        AND [password] = @Password

    --SET IDENTITY_INSERT dbo.tblLogin OFF;

END

【讨论】:

  • 谢谢,它现在可以工作了,实际上它是一个身份列,但是我在创建 tblRegisterUser 时错过了一个列,我必须在发布之前做了一些跟踪和错误:(。抱歉发布这样一个愚蠢的问题。
猜你喜欢
  • 2011-01-01
  • 2011-07-08
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2018-05-05
  • 1970-01-01
相关资源
最近更新 更多