我正在创建一个存储过程,但在执行该过程时,我收到了特定的错误。
消息217,级别16,状态1,过程SendMail_Renewapp,第77行 超出最大存储过程,函数,触发器或视图嵌套级别(限制32)。
任何人都可以帮我解决这个问题。
我的程序如下..
`ALTER PROCEDURE [dbo].[SendMail_Renewapp]
-- Add the parameters for the stored procedure here
AS
BEGIN
declare @xml nvarchar(max)
declare @body nvarchar(max)
declare @currentdate datetime;
declare @ExpDate datetime;
declare @mailsendingdate datetime;
declare @renewtime varchar(10);
DECLARE @AgencyId int;
DECLARE @ApplicationID int;
declare @emailid varchar(100);
set @currentdate=getdate();
--Fetching the application details: start--
DECLARE AppCursor CURSOR FOR
Select top 5 applications.ap_id,applications.ap_expiry_date,agency.ag_co_email from applications join agency on applications.ap_agency_id=agency.ag_id
where ap_status='AS' and ap_iame_flag='IA' and ap_expiry_date != ''
OPEN AppCursor
FETCH NEXT FROM AppCursor INTO @ApplicationID,@ExpDate,@emailid
WHILE @@FETCH_STATUS = 0
BEGIN
SET @renewtime = ABS(DATEDIFF(day, @currentdate, @ExpDate))
if(@renewtime=180)
BEGIN
--SET @xml = CAST(( SELECT [ag_id] AS 'td','',[ag_name] AS 'td','',[ag_co_email] AS 'td','',[ag_mobile] AS 'td'FROM beesl.dbo.Agency where @renewtime < 180
--FOR XML PATH('tr'), ELEMENTS ) AS NVARCHAR(MAX))
SET @body ='<html>
<body>
<div>
<div>
<H3>Agencies Details whose payment are still pending for last 3 months</H3>
</div>
<table cellpadding="4" cellspacing="1" bgcolor=#FFFFFF border=1 rules=none frame=box >
<tr >
<th style=border:1px solid #000000; align=left bgcolor=#c2c2c2> Agency ID </th>
<th style=border:1px solid #000000; align=left bgcolor=#c2c2c2> Agency Name </th>
<th style=border:1px solid #000000; align=left bgcolor=#c2c2c2> Agency Email </th>
<th style=border:1px solid #000000; align=left bgcolor=#c2c2c2> Contact Number </th>
</tr>'
SET @body = @body + @xml +'</table></div></body></html>'
EXEC msdb.dbo.sp_send_dbmail
@profile_name='BEE',
@recipients='emailid@emailid.com',
@subject='Renew Applications',
--@file_attachments = 'D:\beelogo.png',
@importance= High,
--@body = 'Testing'
@body = @body,
@body_format ='HTML';
END
FETCH NEXT FROM AppCursor INTO @ApplicationID,@ExpDate,@emailid
END
CLOSE AppCursor
DEALLOCATE AppCursor
--Fetching the application details: end--
END`
答案 0 :(得分:29)
使用 “走” 之后 结束 声明
答案 1 :(得分:15)
该过程是在其内部使用EXEC创建的。因此,GO必须放在EXEC之前,因此在执行之前将创建/更改过程。因此,避免了RECURSION。
答案 2 :(得分:5)
删除BEGIN
声明
END
和IF
例如
WHILE @@FETCH_STATUS = 0
BEGIN
IF @variable
--NO BEGIN
--Do this
--NO END
END
答案 3 :(得分:3)
使用TRIGGER_NESTLEVEL
功能在触发开始时检查触发嵌套级别,如果触发级别大于1,则停止触发器执行操作。
IF TRIGGER_NESTLEVEL() > 1
RETURN
由于嵌套级别超出其限制而发生错误,因为我们都知道触发器连续触发并且难以控制触发器的行为。函数TRIGGER_NESTLEVEL
返回嵌套级别,我们可以停止嵌套级别的增加。
答案 4 :(得分:1)
更改您的数据库 RECURSIVE_TRIGGERS 。
如果允许嵌套触发器并且链中的触发器开始无限循环,则超出嵌套级别并且触发器终止。那个时候你确实得到了这个错误。所以简单地说明这个问题。
USE yourdatabase
GO
-- Turn recursive triggers OFF in the database.
ALTER DATABASE yourdatabase
SET RECURSIVE_TRIGGERS OFF
GO
希望你的问题能够解决。
答案 5 :(得分:0)
好的,所以这个很老了,所以我想我会提供正确的答案。您应在存储过程的顶部添加SET NOCOUNT ON,然后在尝试返回结果(最终选择)之前将SET NOCOUNT OFF添加。
没有此语句,您的执行将把每个select语句视为要输出的结果。当外部ADO或ADO.NET尝试调用存储过程并获得结果时,您将收到“已超过最大存储过程,函数,触发器或视图嵌套级别(限制32)”的消息。它是您的游标的select语句,它使事情变得一团糟。
参考:https://docs.microsoft.com/en-us/sql/t-sql/statements/set-nocount-transact-sql?view=sql-server-ver15
答案 6 :(得分:0)
我的问题是存储过程,而不是触发器,也没有游标。程序中的EXEC
命令是其他答案指出的原因。但是,在SSMS v18.5的GO
命令之前,我无法在任何地方添加EXEC
。它给了我一个错误。事实证明,嵌套在其中的过程有其自己的TRY / CATCH块。在该过程的末尾添加GO
不能解决问题。我必须在那里删除TRY / CATCH块才能使它工作。不确定这只是我还是对其他人有帮助。
答案 7 :(得分:0)
使用
RETURN
在过程结束时
答案 8 :(得分:0)
就我而言,问题是 UPDATE 有 2(两个)存储过程。所以,尝试只创建一个存储过程。谢谢!