光标触发中的存储过程只有一次

时间:2015-08-04 15:34:50

标签: sql-server stored-procedures cursor

我从存储过程中获取输出,但在我的光标中它只返回第一个值。

SP 1

ALTER PROCEDURE [dbo].[register_system_email_audits]
    @UserId int,
    @EmailFor varchar(500),
    @DateSent datetime,
    @UniqueKey varchar(20) output
AS
BEGIN
    INSERT INTO [SystemEmailsAudit]
           ([UserId]
           ,[EmailFor]
           ,[DateSent]
           ,[UniqueKey]
           )
     VALUES
           (@UserId 
           ,@EmailFor
           ,@DateSent
           ,(SELECT CAST( CAST(RAND() * 100000000 AS int) as varchar(20)))
           );
     SELECT @UniqueKey=s.UniqueKey FROM [SystemEmailsAudit] s 
        WHERE s.RecordId=SCOPE_IDENTITY();

END

SP2

    ALTER PROCEDURE [SendNewsletterMails] (@nLID int,
@Category varchar(50))
AS
  DECLARE @html varchar(max),
          @Description varchar(100),
          @Subject varchar(50),
          @Email varchar(100),
          @listID int,
          @DLC smalldatetime,
          @Date datetime = NULL
  SET @html = (SELECT
    html
  FROM NewsLetter
  WHERE nLID = @nLID)
  DECLARE crsEmailList CURSOR FOR
  SELECT
    email,
    ListID
  FROM lists
  WHERE category = @Category
  AND (DLC < DATEADD(DAY, -1, GETDATE())
  OR DLC IS NULL)
  OPEN crsEmailList
  FETCH NEXT FROM crsEmailList INTO @email, @ListID
  WHILE @@FETCH_STATUS = 0
  BEGIN
    --Add Beacon
    DECLARE @UniqueKey varchar(20)
    EXEC [register_system_email_audits] @ListID,
                                        @email,
                                        @Date,
                                        @UniqueKey OUTPUT
    SET @html = REPLACE(@html, '[keyvalue]', @UniqueKey)
    EXEC msdb.dbo.sp_send_dbmail @profile_Name = 'Local Server',
                                 @recipients = @email,
                                 @subject = @Subject,
                                 @body = @html,
                                 @body_format = 'HTML'
    FETCH NEXT FROM crsEmailList INTO @email, @ListID
  END
  CLOSE crsEmailList
  DEALLOCATE crsEmailList
GO

存储过程返回正确的@UniqueKey但仅针对游标中的第一条记录。我一直在考虑使用while循环或临时表,但现在确定了光标路径。

1 个答案:

答案 0 :(得分:0)

你第一次这样做:

SET @html = Replace(@html,'[keyvalue]', @UniqueKey)

@html将不再包含[keyvalue]。执行相同操作的下一个循环迭代将不再使用[keyvalue]替换您的uniquekey,因此它仍将具有旧的唯一键。您可能必须将@html设置回原来的值,其中包含[keyvalue]。

我还建议将SP1更改为:

ALTER PROCEDURE [dbo].[register_system_email_audits]
    @UserId int,
    @EmailFor varchar(500),
    @DateSent datetime,
    @UniqueKey varchar(20) output
AS
BEGIN
    SELECT @UniqueKey = CAST( CAST(RAND() * 100000000 AS int) as varchar(20))
    INSERT INTO [SystemEmailsAudit]
           ([UserId]
           ,[EmailFor]
           ,[DateSent]
           ,[UniqueKey]
           )
     VALUES
           (@UserId 
           ,@EmailFor
           ,@DateSent
           ,@UniqueKey
           );

END

它将避免使用不必要的附加Select语句。