You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL存储过程IF ELSE分支用SELECT INTO临时表报已存在错误求助

问题修复:临时表重复创建报错

问题原因

你遇到的错误根源是SQL Server的预编译机制:它会对整个批处理代码做语法和对象检查,哪怕ELSE分支实际不会执行,编译器也会检测到两个分支里都用SELECT INTO创建同一个临时表,因此提前抛出“对象已存在”的错误,和运行时是否走到对应分支无关。

修复方案

推荐两种解决方式,优先选择第一种:

方式1:提前创建临时表,分支内仅执行插入操作

先定义好临时表的结构,再在不同分支里用INSERT INTO填充数据,彻底避免重复创建的冲突:

DECLARE @Lotnum varchar(30);
DECLARE @FormulationID varchar(30); 
DECLARE @QtyToProduce numeric(18, 2); 
DECLARE @JobType varchar(2); 

DECLARE @TotalToDisp numeric(18, 2);
DECLARE @ContReq INT;
DECLARE @CONTCODE varchar(30);
DECLARE @CONTMAXQUANT INT;

SET @Lotnum = 'I23-01134';
SET @FormulationID = 'NPI-401-50F';
SET @QtyToProduce = 50;
SET @JobType = 'IN';

-- 先清理已存在的临时表,确保每次执行环境干净
IF OBJECT_ID('tempdb..#TempProdQuatities') IS NOT NULL
    DROP TABLE #TempProdQuatities;

-- 提前创建临时表,结构与SELECT结果完全匹配
CREATE TABLE #TempProdQuatities (
    BillNo varchar(30),
    CurrentBillRevision varchar(30),
    UDF_TOTPARTS numeric(18,2),
    UDF_SOLDBYGALLON bit, -- 请根据实际字段类型调整,此处为示例
    UDF_WPG numeric(18,2),
    UDF_DEFAULTBATCHSIZE numeric(18,2),
    ComponentItemCode varchar(30),
    UDF_PARTS numeric(18,2),
    QTYRECPERUM numeric(18,4),
    TotalQTY numeric(18,2),
    ExtendedQTY numeric(18,4),
    UDF_PAGEGRP INT,
    UDF_TUBGROUP INT,
    CondensedFormulationID varchar(16),
    LotNum varchar(30)
);
    
BEGIN
    IF @JobType = 'IN'
        BEGIN
        PRINT 'jOB tYPE IS iNK';

        INSERT INTO #TempProdQuatities
        SELECT 
            MAS_LPI.dbo.BM_BillHeader.BillNo, 
            MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision, 
            MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS, 
            MAS_LPI.dbo.BM_BillHeader.UDF_SOLDBYGALLON, 
            MAS_LPI.dbo.BM_BillHeader.UDF_WPG, 
            MAS_LPI.dbo.BM_BillHeader.UDF_DEFAULTBATCHSIZE, 
            MAS_LPI.dbo.BM_BillDetail.ComponentItemCode, 
            MAS_LPI.dbo.BM_BillDetail.UDF_PARTS,
            MAS_LPI.dbo.BM_BillDetail.UDF_PARTS / MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS AS QTYRECPERUM,
            @QtyToProduce as TotalQTY,
            ROUND((MAS_LPI.dbo.BM_BillDetail.UDF_PARTS / MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS) * MAS_LPI.dbo.BM_BillHeader.UDF_WPG * @QtyToProduce, 4) AS ExtendedQTY,
            MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP, 
            MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP,
            LEFT(MAS_LPI.dbo.BM_BillHeader.BillNo, 16) AS CondensedFormulationID,
            @Lotnum AS LotNum 
        FROM            
            MAS_LPI.dbo.BM_BillDetail  
        INNER JOIN
            MAS_LPI.dbo.BM_BillHeader ON MAS_LPI.dbo.BM_BillDetail.BillNo = MAS_LPI.dbo.BM_BillHeader.BillNo 
                                      AND MAS_LPI.dbo.BM_BillDetail.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision
        WHERE
            MAS_LPI.dbo.BM_BillHeader.BillNo = @FormulationID 
            AND MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP = 3 
            AND MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP = 500 
            AND MAS_LPI.dbo.BM_BillHeader.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision ;
    END
    ELSE 
    BEGIN
        PRINT 'jOB tYPE IS sOMETHING eLSE';
    
        INSERT INTO #TempProdQuatities
        SELECT 
            MAS_LPI.dbo.BM_BillHeader.BillNo, 
            MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision, 
            MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS, 
            MAS_LPI.dbo.BM_BillHeader.UDF_SOLDBYGALLON, 
            MAS_LPI.dbo.BM_BillHeader.UDF_WPG, MAS_LPI.dbo.BM_BillHeader.UDF_DEFAULTBATCHSIZE, 
            MAS_LPI.dbo.BM_BillDetail.ComponentItemCode, MAS_LPI.dbo.BM_BillDetail.UDF_PARTS,
            MAS_LPI.dbo.BM_BillDetail.UDF_PARTS/MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS as QTYRECPERUM,
            @QtyToProduce as TotalQTY,
            Round((MAS_LPI.dbo.BM_BillDetail.UDF_PARTS/MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS) * MAS_LPI.dbo.BM_BillHeader.UDF_WPG * @QtyToProduce,4) as ExtendedQTY,
            MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP, MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP,
            Left(MAS_LPI.dbo.BM_BillHeader.BillNo,16) as CondensedFormulationID,
            @Lotnum as LotNum 
        FROM            
            MAS_LPI.dbo.BM_BillDetail INNER JOIN
            MAS_LPI.dbo.BM_BillHeader ON MAS_LPI.dbo.BM_BillDetail.BillNo = MAS_LPI.dbo.BM_BillHeader.BillNo 
            AND MAS_LPI.dbo.BM_BillDetail.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision
            Where MAS_LPI.dbo.BM_BillHeader.BillNo = @FormulationID and MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP = 3 and MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP = 500 
            and MAS_LPI.dbo.BM_BillHeader.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision ;
        END
END

方式2:用动态SQL避开编译检查(不推荐,仅作备选)

如果不想提前定义表结构,可以把分支内的逻辑改成动态SQL,这样编译器不会预检查动态代码里的对象:

DECLARE @Lotnum varchar(30);
DECLARE @FormulationID varchar(30); 
DECLARE @QtyToProduce numeric(18, 2); 
DECLARE @JobType varchar(2); 

DECLARE @TotalToDisp numeric(18, 2);
DECLARE @ContReq INT;
DECLARE @CONTCODE varchar(30);
DECLARE @CONTMAXQUANT INT;

SET @Lotnum = 'I23-01134';
SET @FormulationID = 'NPI-401-50F';
SET @QtyToProduce = 50;
SET @JobType = 'IN';

-- 先清理临时表
IF OBJECT_ID('tempdb..#TempProdQuatities') IS NOT NULL
    DROP TABLE #TempProdQuatities;
    
BEGIN
    IF @JobType = 'IN'
        BEGIN
        PRINT 'jOB tYPE IS iNK';
        EXEC('
            SELECT 
                MAS_LPI.dbo.BM_BillHeader.BillNo, 
                MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision, 
                MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS, 
                MAS_LPI.dbo.BM_BillHeader.UDF_SOLDBYGALLON, 
                MAS_LPI.dbo.BM_BillHeader.UDF_WPG, 
                MAS_LPI.dbo.BM_BillHeader.UDF_DEFAULTBATCHSIZE, 
                MAS_LPI.dbo.BM_BillDetail.ComponentItemCode, 
                MAS_LPI.dbo.BM_BillDetail.UDF_PARTS,
                MAS_LPI.dbo.BM_BillDetail.UDF_PARTS / MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS AS QTYRECPERUM,
                '+@QtyToProduce+' as TotalQTY,
                ROUND((MAS_LPI.dbo.BM_BillDetail.UDF_PARTS / MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS) * MAS_LPI.dbo.BM_BillHeader.UDF_WPG * '+@QtyToProduce+', 4) AS ExtendedQTY,
                MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP, 
                MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP,
                LEFT(MAS_LPI.dbo.BM_BillHeader.BillNo, 16) AS CondensedFormulationID,
                '''+@Lotnum+''' AS LotNum 
            INTO
                #TempProdQuatities
            FROM            
                MAS_LPI.dbo.BM_BillDetail  
            INNER JOIN
                MAS_LPI.dbo.BM_BillHeader ON MAS_LPI.dbo.BM_BillDetail.BillNo = MAS_LPI.dbo.BM_BillHeader.BillNo 
                                          AND MAS_LPI.dbo.BM_BillDetail.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision
            WHERE
                MAS_LPI.dbo.BM_BillHeader.BillNo = '''+@FormulationID+''' 
                AND MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP = 3 
                AND MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP = 500 
                AND MAS_LPI.dbo.BM_BillHeader.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision ;
        ')
    END
    ELSE 
    BEGIN
        PRINT 'jOB tYPE IS sOMETHING eLSE';
        EXEC('
            SELECT 
                MAS_LPI.dbo.BM_BillHeader.BillNo, 
                MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision, 
                MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS, 
                MAS_LPI.dbo.BM_BillHeader.UDF_SOLDBYGALLON, 
                MAS_LPI.dbo.BM_BillHeader.UDF_WPG, MAS_LPI.dbo.BM_BillHeader.UDF_DEFAULTBATCHSIZE, 
                MAS_LPI.dbo.BM_BillDetail.ComponentItemCode, MAS_LPI.dbo.BM_BillDetail.UDF_PARTS,
                MAS_LPI.dbo.BM_BillDetail.UDF_PARTS/MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS as QTYRECPERUM,
                '+@QtyToProduce+' as TotalQTY,
                Round((MAS_LPI.dbo.BM_BillDetail.UDF_PARTS/MAS_LPI.dbo.BM_BillHeader.UDF_TOTPARTS) * MAS_LPI.dbo.BM_BillHeader.UDF_WPG * '+@QtyToProduce+',4) as ExtendedQTY,
                MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP, MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP,
                Left(MAS_LPI.dbo.BM_BillHeader.BillNo,16) as CondensedFormulationID,
                '''+@Lotnum+''' as LotNum 
                into #TempProdQuatities
            FROM            
                MAS_LPI.dbo.BM_BillDetail INNER JOIN
                MAS_LPI.dbo.BM_BillHeader ON MAS_LPI.dbo.BM_BillDetail.BillNo = MAS_LPI.dbo.BM_BillHeader.BillNo 
                AND MAS_LPI.dbo.BM_BillDetail.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision
                Where MAS_LPI.dbo.BM_BillHeader.BillNo = '''+@FormulationID+''' and MAS_LPI.dbo.BM_BillDetail.UDF_PAGEGRP = 3 and MAS_LPI.dbo.BM_BillDetail.UDF_TUBGROUP = 500 
                and MAS_LPI.dbo.BM_BillHeader.Revision = MAS_LPI.dbo.BM_BillHeader.CurrentBillRevision ;
        ')
        END
END

注意:动态SQL存在SQL注入风险,调试难度也更高,仅在特殊场景下使用。

关键说明

  • 你之前添加的“删除临时表”操作如果放在分支内部,完全起不到作用——因为编译阶段就已经报错,根本到不了执行删除的步骤。必须把删除操作放在所有分支代码之前。
  • 方式1的核心是让临时表只被创建一次,后续分支仅执行插入操作,彻底规避编译时的对象冲突问题。

内容的提问来源于stack exchange,提问作者Ryan Potratz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:48:09