如何创建INSTEAD OF INSERT触发器

时间:2011-11-10 07:34:21

标签: sql sql-server stored-procedures triggers

我创建了触发器

CREATE TRIGGER PartnersTrigger on Partners
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON


Declare @Key nvarchar(10);

EXEC @Key = sp_GeneratePassword 5;

UPDATE Partners SET KeyInvitation  = @Key WHERE Id IN (SELECT Id FROM inserted);
INSERT INTO Partners(Email,KeyInvitation)
   SELECT Email, KeyInvitation
FROM inserted
END
GO

但我需要设置为KeyInvitation变量@Key。 并在sp_GeneratePassword 5中设置@Key(过程)。

怎么做?

更新

CREATE PROCEDURE sp_GeneratePassword
 (
     @Length int
 )

 AS

 DECLARE @RandomID varchar(32)
 DECLARE @counter smallint
 DECLARE @RandomNumber float
 DECLARE @RandomNumberInt tinyint
 DECLARE @CurrentCharacter varchar(1)
 DECLARE @ValidCharacters varchar(255)
 SET @ValidCharacters = 'abcdefghijklmnopqrstuvwxyz0123456789'
 DECLARE @ValidCharactersLength int
 SET @ValidCharactersLength = len(@ValidCharacters)
 SET @CurrentCharacter = ''
 SET @RandomNumber = 0
 SET @RandomNumberInt = 0
 SET @RandomID = ''

 SET NOCOUNT ON

 SET @counter = 1

 WHILE @counter < (@Length + 1)

 BEGIN

         SET @RandomNumber = Rand()
         SET @RandomNumberInt = Convert(tinyint, ((@ValidCharactersLength - 1) * @RandomNumber + 1))

         SELECT @CurrentCharacter = SUBSTRING(@ValidCharacters, @RandomNumberInt, 1)

         SET @counter = @counter + 1

         SET @RandomID = @RandomID + @CurrentCharacter

 END

 SELECT @RandomID  AS 'Password'



GO

这不起作用:

Declare @Key nvar char(10);  -- can't post when I use "nvarchar" here
EXEC @Key = sp_GeneratePassword 5;

错误:

  

&#39; char&#39;附近的语法不正确。必须声明标量变量&#34; @ Key&#34;。   必须声明标量变量&#34; @ Key&#34;。必须声明标量   变量&#34; @ Key&#34;。

2 个答案:

答案 0 :(得分:3)

除了Michal Powaga指出的信息之外,触发器看起来还不错:

Declare @Key nvarchar(10);  -- can't post when I use "nvarchar" here
EXEC @Key = sp_GeneratePassword 5;

除非sp_GeneratePassword的{​​{1}}具有特定值,否则通常会给出0,因为此类调用会将RETURN的值分配给RETURN。但是,这只能用于@Key值,int是nvarchar。

我会使用输出参数,如昨天的答案:Returning a value from a stored procedure

请注意;您正在为INSERT中的所有行分配相同的密码(不要假设触发器在单行上运行)。我会考虑调用UDF的@Key列上的DEFAULT约束。这样可以避免触发并给出不同的值(我假设)

答案 1 :(得分:1)

为什么不按照下面描述的方式插入@Key

修改:在@gbn回答后更改

首先,SP应该看起来像这样(它的全部是关于output值):

CREATE PROCEDURE sp_GeneratePassword 
    @param_in INT, @key_out NVARCHAR(10) OUTPUT
AS
BEGIN
    -- here is your password generation
    SET @key_out = 'your result'
END
GO

更新:在@Deniskad解释后更改

你的SP:

CREATE PROCEDURE sp_GeneratePassword @Length int, @RandomID varchar(32) OUTPUT
AS
    DECLARE @counter smallint,
        @RandomNumber float,
        @RandomNumberInt tinyint,
        @CurrentCharacter varchar(1),
        @ValidCharacters varchar(255),
        @ValidCharactersLength int

    SET @ValidCharacters = 'abcdefghijklmnopqrstuvwxyz0123456789'

    SELECT @ValidCharactersLength = len(@ValidCharacters),
        @CurrentCharacter = '',
        @RandomNumber = 0,
        @RandomNumberInt = 0,
        @RandomID = ''

    SET NOCOUNT ON

    SET @counter = 1

    WHILE @counter < (@Length + 1)

    BEGIN
        SET @RandomNumber = Rand()
        SET @RandomNumberInt = Convert(tinyint, ((@ValidCharactersLength - 1) * @RandomNumber + 1))

        SELECT @CurrentCharacter = SUBSTRING(@ValidCharacters, @RandomNumberInt, 1)

        SET @counter = @counter + 1

        SET @RandomID = @RandomID + @CurrentCharacter
    END
GO

..然后触发器看起来像这样:

CREATE TRIGGER PartnersTrigger on Partners
INSTEAD OF INSERT
AS
BEGIN
    SET NOCOUNT ON
    Declare @Key nvarchar(10);

    EXEC sp_GeneratePassword 5, @Key OUTPUT

    INSERT INTO Partners(Email,KeyInvitation)
    SELECT Email, @Key
    FROM inserted
END
GO