SQL:无法在触发器中获取 IDENTITY 值

发布于 2024-10-07 17:01:31 字数 2313 浏览 0 评论 0原文

我是 SQL 新手。我正在创建一个虚拟项目。在我的项目中,我有一个注册页面,我想创建一个用户名(名字 + 姓氏 + 用户 ID)。但问题是,我无法捕获用户 ID 值。我已经使用了 After Trigger 和 Replace Of Trigeer。下面是我的脚本 -

表 -

CREATE TABLE UserInfo
(
    UserID INT IDENTITY(1,1),
    FirstName NVARCHAR(500),
    LastName NVARCHAR(500),
    [Password] NVARCHAR(200),
    EmailID NVARCHAR(200),
    [Address] NVARCHAR(500),
    CountryID INT,
    StateID INT,
    UserName NVARCHAR(500)
)

插入数据过程 -

CREATE PROC Create_User    
 @FirstName NVARCHAR(500),    
 @LastName NVARCHAR(500),    
 @Password NVARCHAR(200),    
 @EmailID NVARCHAR(200),    
 @Address NVARCHAR(500),    
 @CountryID INT,    
 @StateID INT,    
 @UserID INT OUTPUT    
AS    
 BEGIN    
 INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)    
 VALUES    
 (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)    

 SET @UserID = SCOPE_IDENTITY();    

 END 

触发器之后 -

CREATE TRIGGER Create_UserName
ON UserInfo
AFTER INSERT
AS
BEGIN
DECLARE @_UName VARCHAR(200);
SET @_UName = (SELECT FirstName+LastName+Cast(UserID AS NVARCHAR(100)) from INSERTED )

INSERT INTO UserInfo (UserName) VALUES (@_UName)
END
    GO

输出 - 插入两行

而不是触发器 -

CREATE TRIGGER Create_UserName
ON UserInfo
INSTEAD OF INSERT
AS
BEGIN
DECLARE @UName NVARCHAR(200);
DECLARE @FName NVARCHAR(200);
DECLARE @LName NVARCHAR(200);
DECLARE @UPassword NVARCHAR(200);
DECLARE @UEmailID NVARCHAR(200);
DECLARE @UAddress NVARCHAR(200);
DECLARE @UCountryID INT;
DECLARE @UStateID INT;
SET @UName = (SELECT FirstName+LastName+Cast(UserID AS NVARCHAR(100)) from INSERTED )
SET @FName = (SELECT FirstName from INSERTED )
SET @LName = (SELECT LastName from INSERTED )
SET @UPassword = (SELECT [Password] from INSERTED )
SET @UEmailID = (SELECT EmailID from INSERTED )
SET @UAddress = (SELECT [Address] from INSERTED )
SET @UCountryID = (SELECT CountryID from INSERTED )
SET @UStateID = (SELECT StateID from INSERTED )




INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID,UserName)  
VALUES (@FName,@LName,@UPassword,@UEmailID,@UAddress,@UCountryID,@UStateID,@UName)
END
    GO

输出 - 这工作正常,但身份为 0。

请告诉我如何做到这一点?

提前致谢。

I am newbie in SQL.I am creating a dummy project.In my project, I have one register page and I want to create a UserName(FirstName + LastName + UserID).But the problem is, I cant catch the UserID value.I have used both After Trigger and Instead Of Trigeer. Below is my script -

Table -

CREATE TABLE UserInfo
(
    UserID INT IDENTITY(1,1),
    FirstName NVARCHAR(500),
    LastName NVARCHAR(500),
    [Password] NVARCHAR(200),
    EmailID NVARCHAR(200),
    [Address] NVARCHAR(500),
    CountryID INT,
    StateID INT,
    UserName NVARCHAR(500)
)

Proc of Insert Data -

CREATE PROC Create_User    
 @FirstName NVARCHAR(500),    
 @LastName NVARCHAR(500),    
 @Password NVARCHAR(200),    
 @EmailID NVARCHAR(200),    
 @Address NVARCHAR(500),    
 @CountryID INT,    
 @StateID INT,    
 @UserID INT OUTPUT    
AS    
 BEGIN    
 INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)    
 VALUES    
 (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)    

 SET @UserID = SCOPE_IDENTITY();    

 END 

After Trigger -

CREATE TRIGGER Create_UserName
ON UserInfo
AFTER INSERT
AS
BEGIN
DECLARE @_UName VARCHAR(200);
SET @_UName = (SELECT FirstName+LastName+Cast(UserID AS NVARCHAR(100)) from INSERTED )

INSERT INTO UserInfo (UserName) VALUES (@_UName)
END
    GO

Output - Inserted two rows

Instead Of Trigger -

CREATE TRIGGER Create_UserName
ON UserInfo
INSTEAD OF INSERT
AS
BEGIN
DECLARE @UName NVARCHAR(200);
DECLARE @FName NVARCHAR(200);
DECLARE @LName NVARCHAR(200);
DECLARE @UPassword NVARCHAR(200);
DECLARE @UEmailID NVARCHAR(200);
DECLARE @UAddress NVARCHAR(200);
DECLARE @UCountryID INT;
DECLARE @UStateID INT;
SET @UName = (SELECT FirstName+LastName+Cast(UserID AS NVARCHAR(100)) from INSERTED )
SET @FName = (SELECT FirstName from INSERTED )
SET @LName = (SELECT LastName from INSERTED )
SET @UPassword = (SELECT [Password] from INSERTED )
SET @UEmailID = (SELECT EmailID from INSERTED )
SET @UAddress = (SELECT [Address] from INSERTED )
SET @UCountryID = (SELECT CountryID from INSERTED )
SET @UStateID = (SELECT StateID from INSERTED )




INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID,UserName)  
VALUES (@FName,@LName,@UPassword,@UEmailID,@UAddress,@UCountryID,@UStateID,@UName)
END
    GO

Output - this works fine but Identity is 0.

Please tell me how I can do this?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栀子花开つ 2024-10-14 17:01:31

你有问题

  • 为什么你有一个存储过程而不是?使用存储过程或代替触发器:不能同时使用第二
  • 个,触发器仅针对一行进行编码
  • 后触发器插入新行,应该是更新

至于原因:

存储过程没有 INSERT 来捕获 IDENTITY value:INSERT 的作用域实际上是stead of 触发器。如果您切换到@@IDENTITY(不好的做法),您将从 AFTER 触发器中获取 IDENTITY 值。

该怎么做:

  • 删除两个触发器:它们不添加任何值

  • 如果无法更改用户名,则向表中添加计算列

    >

例如

ALTER TABLE UserInfo ADD UserName AS FirstName+LastName+Cast(UserID AS NVARCHAR(100)
  • ...或者将更新添加到存储过程 用户名稍后可以更改

,例如

CREATE PROC Create_User    
...
AS    

SET NOCOUNT, XACT_ABORT ON

BEGIN TRY
 BEGIN TRAN

 INSERT INTO UserInfo
   (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)    
 VALUES    
   (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)

 SET @UserID = SCOPE_IDENTITY();    

 UPDATE UserInfo
 SET UserName = @FirstName+@LastName+Cast@UserID AS NVARCHAR(100)
 WHERE UserID = @UserID

   COMMIT TRAN
END TRY
BEGIN CATCH
   IF XACT_STATE() <> 0 ROLLBACK TRAN
END CATCH
GO

You have problems

  • Why do you have a stored proc and INSTEAD OF? Use either a stored proc OR an instead of trigger: not both
  • Second, the triggers are coded for one row only
  • The after trigger is inserting a new row, should be an update

As to why:

The stored proc has no INSERT to trap the IDENTITY value: the scope for the INSERT is actually the instead of trigger. If you switch to @@IDENTITY (bad practice) you'd get the IDENTITY value from the AFTER trigger.

What to do:

  • Drop both of the triggers: they add no value

  • Either add a computed column to the table if UserName cannot be changed

eg

ALTER TABLE UserInfo ADD UserName AS FirstName+LastName+Cast(UserID AS NVARCHAR(100)
  • ...or add an UPDATE to the stored proc UserName could be changed later

eg

CREATE PROC Create_User    
...
AS    

SET NOCOUNT, XACT_ABORT ON

BEGIN TRY
 BEGIN TRAN

 INSERT INTO UserInfo
   (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)    
 VALUES    
   (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)

 SET @UserID = SCOPE_IDENTITY();    

 UPDATE UserInfo
 SET UserName = @FirstName+@LastName+Cast@UserID AS NVARCHAR(100)
 WHERE UserID = @UserID

   COMMIT TRAN
END TRY
BEGIN CATCH
   IF XACT_STATE() <> 0 ROLLBACK TRAN
END CATCH
GO
自由如风 2024-10-14 17:01:31

试试这个触发器:

CREATE TRIGGER Create_UserName
ON UserInfo
AFTER INSERT
AS
BEGIN
    --DECLARE @_UName VARCHAR(500), @user_id INT
    --SELECT @_UName = FirstName + LastName + Cast(UserID AS NVARCHAR(100)), @user_id = UserId FROM INSERTED

    UPDATE UserInfo 
    SET UserName = i.FirstName + i.LastName + Cast(i.UserID AS NVARCHAR(100))
    FROM UserInfo u
    INNER JOIN Inserted I ON (i.UserId = u.UserId)
    --WHERE   UserId = @user_id
END

Try this trigger:

CREATE TRIGGER Create_UserName
ON UserInfo
AFTER INSERT
AS
BEGIN
    --DECLARE @_UName VARCHAR(500), @user_id INT
    --SELECT @_UName = FirstName + LastName + Cast(UserID AS NVARCHAR(100)), @user_id = UserId FROM INSERTED

    UPDATE UserInfo 
    SET UserName = i.FirstName + i.LastName + Cast(i.UserID AS NVARCHAR(100))
    FROM UserInfo u
    INNER JOIN Inserted I ON (i.UserId = u.UserId)
    --WHERE   UserId = @user_id
END
再可℃爱ぅ一点好了 2024-10-14 17:01:31

如果您有 SQL-Server 2005+,则可以使用 insert 语句的输出子句。

CREATE PROC Create_User    
 @FirstName NVARCHAR(500),    
 @LastName NVARCHAR(500),    
 @Password NVARCHAR(200),    
 @EmailID NVARCHAR(200),    
 @Address NVARCHAR(500),    
 @CountryID INT,    
 @StateID INT,    
 @UserID INT OUTPUT    
AS    
 BEGIN
    DECLARE @OV Table (id int);

    INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)
    inserted.id into @OV  
    VALUES (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)    

    SELECT @UserID = id FROM @OV;    
    update UserInfo set UserName = FirstName + LastName + Cast(UserID AS NVARCHAR) where UserID  = @userid
END 

编辑:添加了缺少的关键字,更新了用户名列

If you have SQL-Server 2005+ you can use the output clause of the insertstatement.

CREATE PROC Create_User    
 @FirstName NVARCHAR(500),    
 @LastName NVARCHAR(500),    
 @Password NVARCHAR(200),    
 @EmailID NVARCHAR(200),    
 @Address NVARCHAR(500),    
 @CountryID INT,    
 @StateID INT,    
 @UserID INT OUTPUT    
AS    
 BEGIN
    DECLARE @OV Table (id int);

    INSERT INTO UserInfo (FirstName,LastName,[Password],EmailID,[Address],CountryID,StateID)
    inserted.id into @OV  
    VALUES (@FirstName,@LastName,@Password,@EmailID,@Address,@CountryID,@StateID)    

    SELECT @UserID = id FROM @OV;    
    update UserInfo set UserName = FirstName + LastName + Cast(UserID AS NVARCHAR) where UserID  = @userid
END 

EDIT: Missing keyword added, update of UserName column

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文