存储过程无法使用插入临时表

时间:2014-07-16 17:41:34

标签: sql sql-server global-variables common-table-expression insert-into

我有一个存储过程并且没有在一起玩得很好。我尝试过做一些研究并且没有成功。当我注释掉插入到cte上的##选项卡时SP工作,我看到了cte的结果。就在我插入全局临时表## tab时。

我收到这些错误。 Msg 102,Level 15,State 1,Line 39

'ALL'附近的语法不正确。

Msg 102,Level 15,State 1,Line 39

'ALL'附近的语法不正确。

Msg 102,Level 15,State 1,Line 39

'ALL'附近的语法不正确。

Msg 102,Level 15,State 1,Line 39

'ALL'附近的语法不正确。

Msg 102,Level 15,State 1,Line 39

'ALL'附近的语法不正确。

    SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO




ALTER PROCEDURE [dbo].[csp_CALL_UCBI_DCN_DATES]
    @FMDATE DATETIME ='2014-01-20 00:00:00.000', 
    @TODATE DATETIME ='2014-06-30 00:00:00.000'
AS
BEGIN
SET NOCOUNT ON;

DECLARE 
--@FMDATE DATETIME
--,@TODATE DATETIME
@FM_DATEPART_MONTH VARCHAR(2)
,@FM_DATEPART_YEAR VARCHAR(4)
,@TO_DATEPART_MONTH VARCHAR(2)
,@TO_DATEPART_YEAR VARCHAR(4)

--SET @FMDATE = '2014-01-20 00:00:00.000'
--SET @TODATE = '2014-06-30 00:00:00.000'
SET @FM_DATEPART_MONTH = CAST(DATEPART(M,@FMDATE) AS VARCHAR(2))
SET @FM_DATEPART_YEAR = CAST(DATEPART(YYYY,@FMDATE) AS VARCHAR(4))
SET @TO_DATEPART_MONTH = CAST(DATEPART(M,@TODATE) AS VARCHAR(2))
SET @TO_DATEPART_YEAR = CAST(DATEPART(YYYY,@TODATE) AS VARCHAR(4))

  CREATE TABLE ##tab (id INT IDENTITY(1,1) PRIMARY KEY,myDate VARCHAR(50), SQLname VARCHAR(50),myMonth VARCHAR(50),myYear VARCHAR(50))
;WITH cte(myDate,myMonth,myYear,SQLname) AS (

    SELECT @FMDATE  AS myDate
    ,CAST(DATEPART(M,@FMDATE) AS VARCHAR(2)) AS myMonth
    ,CAST(DATEPART(YYYY,@FMDATE) AS VARCHAR(4)) AS myYear
    ,CAST(DATEPART(M,@FMDATE) AS VARCHAR(2))+'_'+CAST(DATEPART(YYYY,@FMDATE) AS VARCHAR(4)) AS SQLname
    UNION ALL
    SELECT DATEADD(MONTH,1,myDate) AS myDate
    ,CAST(DATEPART(M,DATEADD(MONTH,1,myDate)) AS VARCHAR(2)) AS myMonth
    ,CAST(DATEPART(YYYY,DATEADD(MONTH,1,myDate)) AS VARCHAR(4)) AS myYear
    ,CAST(DATEPART(M,DATEADD(MONTH,1,myDate)) AS VARCHAR(2))+'_'+CAST(DATEPART(YYYY,DATEADD(MONTH,1,myDate)) AS VARCHAR(4)) AS SQLname
    FROM cte
    WHERE DATEADD(MONTH,1,myDate) <=  @TODATE
)
INSERT INTO [##tab]
(myDate,myMonth,myYear,SQLname)
SELECT *
FROM cte
--output INSERTED.myDate,INSERTED.myMonth,INSERTED.myYear,INSERTED.SQLname into [##tab]
--(myMonth,myYear,SQLname)
--OPTION (MAXRECURSION 0)

------------------------------------

DECLARE @sql VARCHAR(8000)
, @i INT
,@count INT
, @sqlname VARCHAR(15)
, @myMonth VARCHAR(50) 
, @myYear VARCHAR(50)

SET @i=1
SELECT @count= COUNT(*) FROM ##tab
WHILE @i <= @count

BEGIN
SELECT @SQLname=SQLname, @myMonth=myMonth, @myYear=myYear FROM ##tab WHERE id=@i 

SET @sql = '
  SELECT  
''UCBI_DCE_'+@SQLname+''' AS [Table],
CAST('''+@myMonth+'/'+@myYear+'/01'' AS DATETIME) AS Date,
        lEntity ,
        lValue ,
        lAccount ,
        lICP ,
        lCustom1 ,
        lCustom2 ,
        lCustom3 ,
        lCustom4 ,
        dP0_Input ,
        dP0_InputTransType ,
        dP1_Input ,
        dP1_InputTransType ,
        dP2_Input ,
        dP2_InputTransType ,
        dP3_Input ,
        dP3_InputTransType ,
        dP4_Input ,
        dP4_InputTransType ,
        dP5_Input ,
        dP5_InputTransType ,
        dP6_Input ,
        dP6_InputTransType ,
        dP7_Input ,
        dP7_InputTransType ,
        dP8_Input ,
        dP8_InputTransType ,
        dP9_Input ,
        dP9_InputTransType ,
        dP10_Input ,
        dP10_InputTransType ,
        dP11_Input ,
        dP11_InputTransType ,
        dTimestamp 
        FROM [DB100].[DB].[dbo].[DCN_'+@SQLname+']
        UNION ALL
'
IF @i = @count SET @sql = LEFT(@sql,LEN(@sql) - 15)
--PRINT @sql
EXEC (@sql)

SET @i=@i+1
END
IF(OBJECT_ID('tempdb..##tab') IS NOT NULL)
BEGIN
    DROP TABLE ##tab
END
END

GO

2 个答案:

答案 0 :(得分:1)

我相信这是问题所在。我知道你正在尝试构建一些动态sql和UNION ALL。问题是您在语句仍在构建时在循环中执行@sql。所以基本上你每次迭代都会构建并执行@sql。将最终执行移动到循环外部。我缩短了您的代码以显示问题所在。

哦,当你将insert注释到临时表时,它的工作原因是因为该表中没有行,你永远不会进入循环。

BEGIN
SELECT @SQLname=SQLname, @myMonth=myMonth, @myYear=myYear FROM ##tab WHERE id=@i 

SET @sql = '
  YOUR CODE 
  UNION ALL'
IF @i = @count SET @sql = LEFT(@sql,LEN(@sql) - 15)
--PRINT @sql

/*HERE YOU EXECUTE WHILE IN LOOP SO THE LAST LINE IS UNION ALL*/
EXEC (@sql)
SET @i=@i+1
END

这是修复

SET @i=1
/* Set @sql outside of loop */
SET @sql = ''
SELECT @count= COUNT(*) FROM ##tab
WHILE @i <= @count

BEGIN
SELECT @SQLname=SQLname, @myMonth=myMonth, @myYear=myYear FROM ##tab WHERE id=@i 

/* Modified this to add to @sql each interation to build your select statement.*/
SET @sql = @sql + '
  select 1 
  UNION ALL'

IF @i = @count SET @sql = LEFT(@sql,LEN(@sql) - 15)

SET @i=@i+1
END

/* Moved exec out of loop*/
EXEC (@sql)

答案 1 :(得分:0)

为什么union ALL位于动态SQL查询的底部?它的错误来自...... union all将两个单独的select语句与相似的字段组合在一起

简单的例子:

 select 1 
 union all
 select 2

这将返回2行... 1和2。

在这里你没有任何关注它。删除union all,除非你在其下运行另一个语句,在这种情况下......在你的代码中包含另一个语句。