【问题标题】:Proc errors when run by outer procedure, runs by itself, then won't error from outer runs由外部程序运行时的 Proc 错误,自行运行,然后不会从外部运行出错
【发布时间】:2022-06-15 04:37:33
【问题描述】:

当我执行执行内部存储过程的外部控制器过程时出现此错误。如果我直接执行内部过程,它工作得很好。 在每个内部 proc 至少运行一次之后,外部现在每次都可以工作。它仍然会在以前没有独立的任何程序上失败。我认为重置它的是改变内部过程,就像在可以调用嵌套过程之前,它必须在数据库中至少运行一次。这只是一个已知的怪癖,还是我可以做些什么来防止它。

消息 207,级别 16,状态 1,程序 usp_Invalid_Country_Code_with_Proper_US_State_Code,第 65 行 列名“TeamID”无效。 消息 207,级别 16,状态 1,程序 usp_Invalid_Country_Code_with_Proper_US_State_Code,第 67 行 列名“TeamID”无效。 消息 207,级别 16,状态 1,程序 usp_Invalid_Country_Code_with_Proper_US_State_Code,第 87 行 列名“TeamID”无效。

这是我的 Controller Proc 的代码,它循环执行要执行的 Procs 列表:

select distinct ID,Proc_Name
into #ControlTable 
from Audit_Main
where IsActive = 1

declare @ID int
declare @ProcName varchar(255)

while exists (select * from #ControlTable)
begin

    select top 1 @ID = ID, @ProcName = Proc_Name
    from #ControlTable
    order by ID asc

    EXECUTE @ProcName

    Insert into audit_Log (Log_Message,Num_Records,Create_Date)
    Select 'Proc Completed: ' + @ProcName,1, getdate()

    delete #ControlTable
    where ID = @ID

end

drop table #ControlTable

Procs 都是一样的,只是对不同的审计有不同的看法:


IF OBJECT_ID('dbname.dbo.TEMP', 'U') IS NOT NULL 
  DROP TABLE dbname.dbo.TEMP; 
Select * into dbname.dbo.TEMP from dbname.dbo.vw_viewname

insert into audit_History (Main_id,team_id,Last_Modified_ID,ICE_ID,IsActive,Create_Date,Completion_Date,histrec_last_modified_date)
select main_id,teamid,[modified by id], [ice id], 1,getdate(),null,getdate() from TEMP
where History_Action = 'Insert'
Insert into audit_Log (Log_Message,Num_Records,Create_Date)
Select 'Insert into Audit_History from vw_VIEWNAME',@@ROWCOUNT, getdate()

UPDATE ah 
SET ah.Last_Modified_ID = vw.[modified by id],ah.IsActive = 1,completion_date = null,ah.histrec_last_modified_date = getdate()
From Audit_History ah join TEMP vw
on ah.main_id = vw.main_id and ah.team_id = vw.teamid and ah.ice_id = vw.[ice id]
where vw.history_action = 'Update'
Insert into audit_Log (Log_Message,Num_Records,Create_Date)
Select 'Update Audit_History from vw_VIEWNAME',@@ROWCOUNT, getdate()

select distinct TeamID
into #ControlTable 
from TEMP
where history_action = 'Insert'

declare @TeamID int
declare @TeamName varchar(255)
declare @TeamEmail varchar(255)
declare @SubjectLine varchar(255)
declare @FileName varchar(255)
declare @Squery varchar(255)

while exists (select * from #ControlTable)
    begin

        select top 1 @TeamID = TeamID
        from #ControlTable
        order by TeamID asc

        select @TeamName = Team, @TeamEmail = Email_Address from membership_Services..audit_Teams where ID = @TeamID;
        Set @SubjectLine = @TeamName + ' on ' + CONVERT(CHAR(10),  GETDATE(), 120)
        Set @FileName = CONVERT(CHAR(8),  GETDATE(), 112) + '.csv'
        Set @Squery = Concat('SET NOCOUNT ON select * from dbname.dbo.TEMP Where history_action = ''insert'' and TeamID = ',@TeamID,' SET NOCOUNT OFF')

        EXEC msdb.dbo.sp_send_dbmail 
        @profile_name = 'test' ,
        @recipients = @TeamEmail,
        @subject = @SubjectLine,
        @query_result_header = 1,
        @query = @Squery, 
        @attach_query_result_as_file = 1,
        @query_result_separator = ',',
        @query_attachment_filename = @FileName,
        @query_result_no_padding = 1,
        @query_result_width=500

        delete #ControlTable
        where TeamID = @TeamID

        Insert into audit_Log (Log_Message,Num_Records,Create_Date)
        Select 'Email sent: ' + @SubjectLine,@@ROWCOUNT, getdate()

    end

drop table #ControlTable

【问题讨论】:

  • 跨过程调用的临时表的作用域规则错综复杂且有趣,最好不要依赖它们,因为在存储过程之间传递数据不是绝对必要的。问题是在外部和内部存储过程中都使用名称#ControlTable,但使用不同的模式。重命名其中一个,您的问题就会消失。
  • 是的!那成功了。我很愚蠢,因为没有考虑让多个同名的临时表浮动。废话命名约定转过来咬我。泰!!

标签: sql-server loops tsql stored-procedures


猜你喜欢
  • 1970-01-01
  • 2020-09-05
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多