SQL: невозможно получить значение IDENTITY в Trigger - PullRequest
1 голос
/ 16 декабря 2010

Я новичок в SQL. Я создаю фиктивный проект. В моем проекте у меня одна страница регистрации, и я хочу создать имя пользователя (FirstName + LastName + UserID). Но проблема в том, что я не могу поймать UserIDзначение. Я использовал и после триггера и вместо триггера.Ниже мой сценарий -

Таблица -

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.

Скажите, пожалуйста, как я могу это сделать?

Заранее спасибо.

Ответы [ 3 ]

5 голосов
/ 16 декабря 2010

У вас проблемы

  • Почему у вас есть сохраненный процесс и INSTEAD OF? Используйте либо сохраненный процесс, либо вместо триггера: не оба
  • Во-вторых, триггеры кодируются только для одной строки
  • Триггер после вставки новой строки, должно быть обновление

Почему:

Хранимый процесс не имеет INSERT для перехвата значения IDENTITY: область действия INSERT фактически вместо триггера. Если вы переключитесь на @@ IDENTITY (плохая практика), вы получите значение IDENTITY из триггера AFTER.

Что делать:

  • Отбросьте оба триггера: они не добавляют значения

  • Либо добавьте вычисляемый столбец в таблицу, если имя пользователя нельзя изменить

например

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
1 голос
/ 16 декабря 2010

Попробуйте этот триггер:

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
0 голосов
/ 16 декабря 2010

Если у вас SQL-Server 2005+, вы можете использовать предложение output для вставки.

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 

РЕДАКТИРОВАТЬ: Добавлено недостающее ключевое слово, обновление столбца UserName

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...