2

저장 프로 시저가 있으며 함께 재생되지 않습니다. 나는 약간의 연구를 시도하고 성공하지 못했습니다. 내가 SP에 ## 탭에 삽입을 언급하면 ​​SP가 작동하고 CT의 결과를 볼 수 있습니다. 그것은 단지 전역 임시 테이블 ## 탭에 삽입 할 때입니다.저장 프로 시저가 임시 테이블에 삽입하지 않고 작동하지 않습니다.

이러한 오류가 발생합니다. 메시지 102, 수준 15, 상태 1, 줄 39

'ALL'근처의 구문이 잘못되었습니다.

메시지 102, 수준 15, 상태 1, 줄 39

근처의 구문이 잘못되었습니다 'ALL'.

메시지 102, 수준 15, 상태 1, 줄 39

근처의 구문이 잘못되었습니다 'ALL'.

메시지 102, 수준 15, 상태 1, 줄 39

근처의 구문이 잘못되었습니다 'ALL'.

메시지 102, 수준 15, 상태 1, 줄 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 
[email protected] 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 [email protected] 

SET @sql = ' 
    SELECT 
''UCBI_DCE_'[email protected]+''' AS [Table], 
CAST('''[email protected]+'/'[email protected]+'/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_'[email protected]+'] 
     UNION ALL 
' 
IF @i = @count SET @sql = LEFT(@sql,LEN(@sql) - 15) 
--PRINT @sql 
EXEC (@sql) 

SET @[email protected]+1 
END 
IF(OBJECT_ID('tempdb..##tab') IS NOT NULL) 
BEGIN 
    DROP TABLE ##tab 
END 
END 

GO 
+0

이 때문에 글로벌 임시 테이블의 여기 동시성 문제가 있음을 인식하시기 바랍니다. 기본 쿼리에는 비 -SARGable 술어가 있기 때문에 성능 문제가 발생합니다. 마지막으로 중요한 것은 while 루프를 사용하여 동적 SQL 문자열을 이와 같이 만들지 않는 것이 좋습니다. 이 모든 과정을 훨씬 간단하게 처리 할 수 ​​있습니다. –

답변

1

나는 이것이 문제라고 생각합니다. 나는 당신이 동적 인 SQL과 UNION ALL을 만들려고한다는 것을 알게되었다. 문제는 명령문이 계속 작성되는 동안 루프에서 @sql을 실행한다는 것입니다. 따라서 기본적으로 모든 반복을 @sql 빌드하고 실행합니다. 루프 밖에서 최종 실행을 이동하십시오. 문제점을 어디에 있는지 보여주기 위해 코드를 단축했습니다.

오우 (temp) 테이블에 insert을 주석 처리 할 때 작동하는 이유는 그 테이블에 행이 없기 때문에 결코 루프에 들어 가지 않기 때문입니다.

BEGIN 
SELECT @SQLname=SQLname, @myMonth=myMonth, @myYear=myYear FROM ##tab WHERE [email protected] 

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 @[email protected]+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 [email protected] 

/* 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 @[email protected]+1 
END 

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

그건 문제가되지 않습니다. PRINT가 좋아 보이고 있습니다. – dbahiker

+0

@ dbahiker 그 이유는 각 반복을 인쇄하여 결과가 하나의 커다란 인쇄본처럼 보이기 때문입니다. 실제로는 6입니다. 인쇄본 아래에'PRINT 'STATEMENT EXECUTED''라는 또 다른 행을 추가하면 의미하는 것을 볼 수 있습니다. – SQLChao

+0

Gotcha, ok Im 솔루션을 찾고 있습니다. 어떤 아이디어? – dbahiker

0

왜 동적 SQL 쿼리 하단에 합집합이 있습니까? 오류가에서 ... 노동 조합 오는 곳이 모두 같은 필드

두 개의 별도의 선택 문을 결합이다

간단한 예 :

select 1 
union all 
select 2 

이 2 행 ... 1, 여기에 2

를 반환합니다 당신은 그것을 따르지 않고 여기에 가지고 있습니다. 다른 명령문을 사용하지 않는 한 공용체를 모두 제거하십시오.이 경우 코드에 다른 명령문을 포함하십시오.

+0

쿼리는 while 루프에서 빌드되도록 설정되어 있으므로 모두가 함께 조인 할 수 있습니다. IF i = Count에 제거 단계가있어서 단 하나의 쿼리 만 필요한 경우이를 제거합니다. 나는 그것이 만들어지고있는 방식에 문제가 있다고 가정한다.PRINT @sql 출력을 가져 와서 오류를 찾는 쿼리 창에 넣으십시오. –

+0

두 개 이상의 SELECT 문을 선택 중이므로 UNION ALL과 함께 사용합니다. 기본 쿼리는 9 개의 결과를 가질 수 있으며 9 개의 SELECT 문 모두에 UNION ALL이 모두 포함됩니다. 그런 다음 마지막 루프에서 길이가 15 자까지 제거됩니다. – dbahiker

+0

백작 예 인쇄 할 때 제대로 실행됩니다. 또한 쿼리가 아닌 쿼리로 모든 것을 실행하면 잘 작동합니다. – dbahiker