繁体   English   中英

存储过程中的“无效的列名”

[英]'Invalid column name' from within a stored procedure

我编写了一个存储过程,以将将来的日期(星期六和星期日除外)插入永久表。 该例程仅使用一个临时表。 这篇文章的目的不是批评存储过程。 虽然,我相信它可以改善。 但是,本文的目的是分析为什么在一组情况下而非其他情况下调用存储过程时会引发这些错误。

1-这是我收到的错误

Msg 207, Level 16, State 1, Procedure MAKE_FUTURE_DATES, Line 25
Invalid column name 'tdate'.
Msg 207, Level 16, State 1, Procedure MAKE_FUTURE_DATES, Line 31
Invalid column name 'wday'.

2-这是存储过程

ALTER PROCEDURE [dbo].[MAKE_FUTURE_DATES] (@STARTDATE DATE)
AS
BEGIN
-- We need to populate FUTURE_DATES (table) with forward looking dates (week days only) 
-- We do not consider/exclude holidays here. We just exclude Sat/Suns

-- Temp table to hold the dates and days of the week
    CREATE TABLE #TMP_DATES(
        [tdate] [date] NULL,
        [wday] [varchar](10) NULL,  
        )

    -- To generate 'enough' future dates loop up to 1199 days in the future
    -- and insert dates that start with the current date and increase with each loop

    DECLARE @Loop INT
    SET @Loop = 0
    WHILE @Loop < 1200
    BEGIN
        INSERT INTO #TMP_DATES (tdate) VALUES (DATEADD(weekday,@Loop,@STARTDATE))   
        SET @Loop = @Loop + 1
    END

    -- Now update the wday column with the weekday name so we can get rid of
    -- Sat/Sun in the next step

    UPDATE #TMP_DATES
    SET wday = UPPER(LEFT(DATENAME(dw,tdate),3))

    -- Get rid of Sat/Sun
    DELETE FROM #TMP_DATES WHERE wday = 'SAT' or wday = 'SUN'

    -- Now clear the final destination table
    TRUNCATE TABLE FUTURE_DATES

    -- Insert the weekday dates into future_dates

    INSERT INTO FUTURE_DATES (fdate,wday)
    SELECT tdate,wday FROM #TMP_DATES

    DROP TABLE #TMP_DATES

3-我已经在另一个存储过程中将上述存储过程作为后台SQL Server任务(通过SQL Server作业计划程序)在后台调用了大约6个月,没有任何错误或问题。 最近,我创建了一个新的存储过程,我们称之为“ ABC”,它调用了一个存储过程,该存储过程调用了MAKE_FUTURE_DATE。

4-这是我要解决的部分。 当在后台(通过SQL Server作业计划程序)将ABC作为SQL Server任务调用时,它每次(每天)都会引发错误,并且不会产生结果/它会崩溃。 当我第一次启动SQL Server Management Studio并运行ABC时,有时会第一次抛出错误。 此序列中的第二次以及以后的所有第二次都不会引发错误。 另外,请记住,已调用MAKE_FUTURE_DATES 6个月的存储过程仍然很满意,没有出现错误。

我正在寻找有关如何调试或查找内容的建议。 特别是它如何有时会引发错误,而不会引发其他错误?

您发布的代码对我来说很好。 这是完整的代码吗?

唯一想到的是您的“ ABC”存储过程还具有一个称为#TMP_DATES的临时表。 这样,在被调用的存储过程的范围内,ABC中的临时表也将可用。

但是,在这种情况下,当在被调用过程中调用CREATE TABLE #TMP_DATES时,应该会得到另一个错误。

临时表的作用域不仅仅是一个过程。

因此,您可以在uspProc1中创建一个临时表...如果在uspProc1中,您调用uspProc2,则uspProc2可以“看到”您创建的临时表。

确保为#temp表提供唯一的名称。

以下是说明这一点的示例。

IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc001'  
    )
BEGIN
    DROP PROCEDURE [dbo].[uspProc001]
END


GO

CREATE Procedure dbo.uspProc001 (
@Param1 int
)
AS

BEGIN


IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


CREATE TABLE #TableOne
( 
SurrogateKey int , 
NameOf varchar(12)
)

Insert into #TableOne ( SurrogateKey , NameOf ) select 1001, 'uspProc001'

Select * from #TableOne

EXEC dbo.uspProc002 

Select * from #TableOne

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


END


GO




IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc002'  
    )
BEGIN
    DROP PROCEDURE [dbo].[uspProc002]
END


GO

CREATE Procedure dbo.uspProc002 
AS

BEGIN

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
    Insert into #TableOne ( SurrogateKey , NameOf ) select 2001, 'uspProc002'
end



END


GO










exec dbo.uspProc001 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM