2016-08-12 22 views
1

動的SQLに問題があります。 私はPrint (@sql)とてmanualyコピー&ペーストを使用する場合、それは完璧に動作しますが、この例ではexec (@sql)またはexec sp_executesql @sql動的クエリを使用してSQL Serverでsqlを実行する方法

を使用して、私は、システムテーブルにsys.types

を使用しますが、私が間違ってやっている任意のアイデアを持っていますか?

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) 

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)

メッセージを持って実行するものによっては

結果:最後の組合から34行

2)

print (@sql) 
exec (@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 

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) 

結果:最後の組合から34行

3) 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

あなたはWhileループのEXEC (@sql)外、すなわち移動する必要がある - あなたの最後の3行...

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

に変更する..needを。 。

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

また、あなたの最初の@sql =文は、他の場所で持っているよう@sql = @sql +する必要があります。あなたの明細書にUNIONがあるので、@sqlは1回だけ実行する必要があります。これが機能するには、スクリプトの冒頭に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

あなたの修正でコードを実行すると、空のメッセージセクションと「成功したクエリが実行されました」だけが表示されます。同じ結果がありますか? –

+0

スクリプトをわずかに調整しました。 "@sqlsub"は "@sqlsub" = "で"初期化 "する必要がありますが、" @sql "と同じです。また、 "cnt"は0でないので、 "@cnt"は1から開始する必要があります。 –

+0

これは完全に動作します。どうもありがとうございました:) –

関連する問題