Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Проблема с SP в SP, которая вызывает Trigger с двумя INS ?  [new]
catcher
Member

Откуда:
Сообщений: 2
Попытался ввести лог. Но ниже приведенный код
работает, если в CREATE TRIGGER DR_IA оставить только один INSERT,
а в текущем виде вылетает с ошибкой:
Server: Msg 547, Level 16, State 1, Procedure spGETUSERCNE, Line 18
INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'DU_ROLE_REF'.
The conflict occurred in database 'MYTESTDB', table 'DEFROLE', column 'IDX_DR'.
The statement has been terminated.
которая появляется когда первый раз отрабатывает exec spGETUSERCNE

Может я чего напутал? Напишите мне пожалуйста!
CREATE TABLE DBO.GHISTORY
( IDX_GH  INT       IDENTITY NOT FOR REPLICATION NOT NULL 
                 CONSTRAINT GH_PRI_KEY PRIMARY KEY CLUSTERED,
  GH_TIME  DATETIME  NOT NULL
                 CONSTRAINT GH_CREATE_DEF DEFAULT GETDATE(),
  GH_GUID  UNIQUEIDENTIFIER NOT NULL,
  GH_TABLE       VARCHAR(4) NOT NULL,
  GH_ACTION      VARCHAR(4) NOT NULL,
  GH_FIELD  VARCHAR(20) NOT NULL,
  GH_VALUE  VARCHAR(120))
GO

CREATE TABLE DBO.DEFROLE
( IDX_DR	 INT       IDENTITY NOT FOR REPLICATION NOT NULL 
                 CONSTRAINT DR_PRI_KEY PRIMARY KEY CLUSTERED,
  DR_GUID	 UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL 
                 CONSTRAINT DR_GUID_DEF DEFAULT NEWID()
                 CONSTRAINT DR_GUID_UNI UNIQUE,
  DR_VER	 ROWVERSION NOT NULL,
  DR_NAME	 VARCHAR(60) NOT NULL
                 CONSTRAINT DR_NAME_UNI UNIQUE,
  DR_SHOW	 VARCHAR(60) NOT NULL,
  DR_DESCR	 VARCHAR(4000) NULL)

GO

CREATE TRIGGER DR_IA ON DBO.DEFROLE AFTER INSERT AS
INSERT INTO GHISTORY (GH_GUID, GH_TABLE, GH_ACTION, GH_FIELD, GH_VALUE)
SELECT DR_GUID, 'DR', 'INSA', 'NAME', DR_NAME FROM INSERTED
INSERT INTO GHISTORY (GH_GUID, GH_TABLE, GH_ACTION, GH_FIELD, GH_VALUE)
SELECT DR_GUID, 'DR', 'INSA', 'SHOW', DR_SHOW FROM INSERTED


GO

CREATE PROC DBO.spGETROLECNE 
   (
     @RoleName  AS VARCHAR(60) = 'DEFAULT',
     @Idx_Role  AS INT OUTPUT  
   )
AS  
    SELECT @Idx_Role = IDX_DR 
    FROM DEFROLE 
    WHERE DR_NAME = @RoleName

    IF ( @Idx_Role IS NULL )
    BEGIN 
        INSERT INTO DEFROLE (DR_NAME, DR_SHOW) VALUES (@RoleName, @RoleName)
        SET @Idx_Role = @@IDENTITY
    END

    RETURN (0)

GO

CREATE TABLE DBO.DEFUSER
 (IDX_DU	 INT	IDENTITY NOT FOR REPLICATION NOT NULL 
                 CONSTRAINT DU_PRI_KEY PRIMARY KEY CLUSTERED,
  DU_GUID	 UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL 
                 CONSTRAINT DU_GUID_DEF DEFAULT NEWID()
                 CONSTRAINT DU_GUID_UNI UNIQUE,
  DU_VER	 ROWVERSION NOT NULL,
  DU_NAME	 VARCHAR(60) NOT NULL
                 CONSTRAINT DU_NAME_UNI UNIQUE,
  DU_ROLE	 INT	 NOT NULL
                 CONSTRAINT DU_ROLE_REF REFERENCES DEFROLE (IDX_DR)
                            ON UPDATE NO ACTION ON DELETE NO ACTION,
  DU_DESCR	 VARCHAR(4000) NULL)

GO

CREATE PROC DBO.spGETUSERCNE 
   (
     @UserName  AS VARCHAR(60) = 'DEFAULT',
     @Idx_User  AS INT OUTPUT  
   )
AS  
    SELECT @Idx_User = IDX_DU
    FROM DEFUSER
    WHERE DU_NAME = @UserName

    IF ( @Idx_User IS NULL )
    BEGIN 
        DECLARE @riRoleNone int
        
        exec spGETROLECNE  @RoleName = 'DEFAULTUSERROLE', @Idx_Role = @riRoleNone Output

        INSERT INTO DEFUSER (DU_NAME, DU_ROLE) 
               VALUES (@UserName, @riRoleNone)

        SET @Idx_User = @@IDENTITY
    END

    RETURN (0)

GO


/* первоначальные установки */
DECLARE @retiAdminLic int
DECLARE @retiLogonLic int
DECLARE @riAdminUser int
DECLARE @riPowerUserUser int

/* Есть роли ADMIN и LOGON LICENSE */
exec spGETROLECNE @RoleName = 'ADMIN',         @Idx_Role = @retiAdminLic Output
exec spGETROLECNE @RoleName = 'LOGON LICENSE', @Idx_Role = @retiLogonLic Output

/* определяем несколько пользователей */
exec spGETUSERCNE @UserName = 'ADMIN', @Idx_User = @riAdminUser Output
exec spGETUSERCNE @UserName = 'PowerUser', @Idx_User = @riPowerUserUser Output

GO

С уважением, Анатолий.
18 ноя 05, 00:45    [2081480]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с SP в SP, которая вызывает Trigger с двумя INS ?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

почитайте BOL на предмет разницы между @@identity и scope_identity().
на сколько я понимаю, должно быть так:
CREATE PROC DBO.spGETROLECNE
   (
     @RoleName  AS VARCHAR(60) = 'DEFAULT',
     @Idx_Role  AS INT OUTPUT
   )
AS
    SELECT @Idx_Role = IDX_DR
    FROM DEFROLE
    WHERE DR_NAME = @RoleName

    IF ( @Idx_Role IS NULL )
    BEGIN
        INSERT INTO DEFROLE (DR_NAME, DR_SHOW) VALUES (@RoleName, @RoleName)
        -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        SET @Idx_Role = scope_identity()
        -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    END

    RETURN (0)

GO



Posted via ActualForum NNTP Server 1.3

18 ноя 05, 07:57    [2081729]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с SP в SP, которая вызывает Trigger с двумя INS ?  [new]
catcher
Member

Откуда:
Сообщений: 2
Большое спасибо daw!

Да, действительно я запутался.

daw
почитайте BOL на предмет разницы между @@identity и scope_identity().


Ага, точно! Вот тут http://www.excode.ru/art211p1.html, например, все подробненько написано.

Нужно использовать
SET @Idx_Role = scope_identity()
или (как у меня раньше было)
SELECT @Idx_Role = IDX_DR FROM DR_DEFROLE WHERE DR_NAME = @RoleName

Это я потом исправил на @@identity, вроде работало, а после добавления триггера все пропало

С уважением, Анатолий.
18 ноя 05, 12:44    [2083115]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить