2016-08-12 3 views
1

동적 SQL에 문제가 있습니다. 내가 Print (@sql) 및 수동으로 실시 사본 & 붙여 넣기를 사용하는 경우 는, 내가 시스템 테이블 sys.types동적 쿼리를 사용하여 SQL Server에서 sql을 실행하는 방법

당신은 내가 잘못 뭘하는지 어떤 아이디어가 있습니까 사용 완벽하게 작동하지만,이 예를 들어 exec (@sql) 또는 exec sp_executesql @sql

를 사용하고 계십니까?

CREATE TABLE [dbo].pomocnicza 
(okres VARCHAR(5) PRIMARY KEY 
, idWiersza INT 
, cnt INT 
) 

INSERT INTO [dbo].pomocnicza(okres, idWiersza, cnt) 
SELECT okres, idWiersza, cnt FROM(SELECT '07_03'okres, 2 idWiersza, 1 cnt 
UNION 
SELECT '07_04', 3, 2 
UNION 
SELECT '07_07', 6, 3 
UNION 
SELECT '07_10', 9, 4 
UNION 
SELECT '07_14', 13, 5) t 

및 동적 SQL :

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 

(34 row(s) affected) 
,536,913 :

DECLARE @sql VARCHAR(max) 
, @sqlSub VARCHAR(max) 
, @cnt INT = 0 
, @cntSub INT = 2 
, @cnt_total INT = 0 
, @okres VARCHAR(5) 
, @idWiersza INT; 

SELECT @cnt_total = COUNT(1) FROM [dbo].pomocnicza 

WHILE @cnt <= @cnt_total 
BEGIN 
    SELECT @okres = okres, @idWiersza = idWiersza FROM [dbo].pomocnicza WHERE cnt = @cnt 
    SET @sql = 'select distinct name, schema_id, ''' + @okres 
       + ''' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       ' 
    WHILE @cntSub <= @idWiersza 
    BEGIN 
     SET @sqlSub = @sqlSub + ' or isnull(lead(max_length,' + CAST(@cntSub AS VARCHAR) + ') over (partition by scale,precision order by precision),0)=0' 
     SET @cntSub = @cntSub + 1; 
    END 
     SET @sql = @sql + @sqlSub + ' then 0 else 1 end) all_period_available FROM sys.types' 

    if @cnt+1 <= @cnt_total 
    begin 
     SET @sql = @sql + ' 
     union all 
     '; 
    end 


    SET @cnt = @cnt + 1; 
    SET @sqlSub = '' 
    SET @cntSub = 2 

print (@sql) 
exec (@sql)  
END; 

내가 다른 오류

1)exec (@sql)

메시지를 실행할 것을 따라 63,210

결과 :

select distinct name, schema_id, '07_03' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
select distinct name, schema_id, '07_04' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
select distinct name, schema_id, '07_07' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
select distinct name, schema_id, '07_10' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,7) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,8) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,9) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near 'all'. 
select distinct name, schema_id, '07_14' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,7) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,8) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,9) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,10) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,11) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,12) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,13) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 

(34 row(s) affected) 

결과 : 만 마지막 조합

3에서 34 행) 만 마지막 조합

2)

print (@sql) 
exec (@sql) 

메시지 34 개 행 print (@sql) 내가 완벽하게 작동 SQL이 있습니다

select distinct name, schema_id, '07_03' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

select distinct name, schema_id, '07_04' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

select distinct name, schema_id, '07_07' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

select distinct name, schema_id, '07_10' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,7) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,8) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,9) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
     union all 

select distinct name, schema_id, '07_14' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       or isnull(lead(max_length,2) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,3) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,4) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,5) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,6) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,7) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,8) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,9) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,10) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,11) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,12) over (partition by scale,precision order by precision),0)=0 or isnull(lead(max_length,13) over (partition by scale,precision order by precision),0)=0 then 0 else 1 end) all_period_available FROM sys.types 
+2

오류 메시지가 무엇을? @sql을 인쇄 할 때 얻는 텍스트는 무엇입니까? –

+2

"작동하지 않는다"는 것은 무엇을 의미합니까? 오류가 발생합니까?, 잘못된 결과는 무엇입니까? – Lamak

+0

그 안쪽의'while'은 좋지 않습니다 ... –

답변

1

당신은 동안 루프의 EXEC (@sql) 외부, 즉 이동해야 - 당신의 마지막 세 행 ..

print (@sql) 
exec (@sql)  
END; 

로 변경 ..need을. .

END; 
print (@sql) 
exec (@sql) 

또한, 첫 번째 @sql = 문을 사용하면 다른 장소에서이 같은 @sql = @sql +을 할 필요가있다. 성명서에 UNION이 있으니 @sql 번만 실행하면됩니다. 이 작업을 수행하려면 스크립트 시작 부분에 set @sql = ''이 필요합니다.

이와 수정 전체 스크립트는 다음과 같은 모양 :

DECLARE @sql VARCHAR(max) = '' 
, @sqlSub VARCHAR(max) = '' 
, @cnt INT = 1 
, @cntSub INT = 2 
, @cnt_total INT = 0 
, @okres VARCHAR(5) 
, @idWiersza INT; 

SELECT @cnt_total = COUNT(1) FROM [dbo].pomocnicza 

WHILE @cnt <= @cnt_total 
BEGIN 
    SELECT @okres = okres, @idWiersza = idWiersza FROM [dbo].pomocnicza WHERE cnt = @cnt 
    SET @sql = @sql + 'select distinct name, schema_id, ''' + @okres 
       + ''' as okres, getdate() as czas 
       , (case when scale<>0 then 100 else 0 end) scale 
       , (case when precision>=4 
       ' 
    WHILE @cntSub <= @idWiersza 
    BEGIN 
     SET @sqlSub = @sqlSub + ' or isnull(lead(max_length,' + CAST(@cntSub AS VARCHAR) + ') over (partition by scale,precision order by precision),0)=0' 
     SET @cntSub = @cntSub + 1; 
    END 
     SET @sql = @sql + @sqlSub + ' then 0 else 1 end) all_period_available FROM sys.types' 

    if @cnt+1 <= @cnt_total 
    begin 
     SET @sql = @sql + ' 
     union all 
     '; 
    end 


    SET @cnt = @cnt + 1; 
    SET @sqlSub = '' 
    SET @cntSub = 2 

END; 
print (@sql) 
exec (@sql) 
+0

수정 사항을 사용하여 코드를 실행하면 빈 메시지 섹션과 "쿼리가 successfuly 실행되었습니다"만 표시됩니다. 같은 결과가 있습니까? –

+0

방금 ​​스크립트를 약간 조정했습니다. "@sqlsub"는 "@sqlsub"= "로"초기화 "해야하며"@sql "과 동일합니다. 또한 "cnt"는 0이 아니므로 "@cnt"는 1부터 시작해야합니다. –

+0

이제 완벽하게 작동합니다. 고마워요 :) –