2016-08-17 1 views
2

私は効率的な方法でコードを書く方法を次のようにします。何のparamが ')'IN句内の複数のIF文を使用して動的クエリを回避する方法

近くに無効な構文を追加されていない場合、上記のステートメントがエラーをスローした場合

DECLARE @sql VARCHAR(MAX) = '' 
DECLARE @where VARCHAR(MAX) = '' 

IF @is_clean_label = 1 
    SET @where = @where+ N'Clean Label,' 

IF @Is_KeyInterview = 1 
    SET @where = @where+N'Key Interview,' 

IF @Is_SpecialReport = 1 
    SET @where = @where+N'Special Report,' 

SET @sql = N' SELECT * FROM TABLE WHERE Name in ('[email protected]+')' 

EXEC (@sql) 

条件が適用されない場合はすべての値を返す必要があります。

動的SQLを回避することはできますか?

+0

あなたの@whereには、 ';'が含まれています。 SQLに追加する前にその最初のコンマを削除するロジックを記述してください – techspider

+0

文字列の後ろに移動し、値の一部であってはなりません。 'を3回使用して、値を文字列で囲みます。例は、+ N '、Clean Label'のどこにあってはならない。 + '' 'クリーンラベル' '+'、 ''である必要があります。また、他の人が何かを削除すると言っている、かわいそうや終わりのどこから文字列。検索するにはCHARINDEXを使用し、文字列を切り取るにはSUBSTRINGを使用します。 –

答えて

1

あなたは、あなたが、本質的に直接where句の中に、論理をあなたのIFを移動することができますwhere句でのcase文で欲しいものは何でもほとんど行うことができます。

SELECT * 
FROM 
    TableName 
WHERE 
    (CASE 
     WHEN @is_clean_label = 1 AND Name = 'Clean Label' THEN 1 
     ELSE 0 
    END) = 1 
    OR 
    (CASE 
     WHEN @Is_KeyInterview = 1 AND Name = 'Key Interview' THEN 1 
     ELSE 0 
    END) = 1 
    OR 
    (CASE 
     WHEN @Is_SpecialReport = 1 AND Name = 'Special Report' THEN 1 
     ELSE 0 
    END) = 1 
    OR 
    (CASE 
     WHEN (COALESCE(@Is_SpecialReport,0) + COALESCE(@Is_KeyInterview,0) + COALESCE(@Is_SpecialReport,0)) = 0 THEN 1 
     ELSE 0 
    END) = 1 

私はあまりにもJohnが書いたテーブルルートを使用しますが、このテクニックを何度も役立つように表示することが重要だと思います。私はまた、他のコメントのいくつかは、本当に必要とされていないときにダイナミックSQLから離れることに同意します!

0

@where変数には、連結論理のために先にcommaが含まれています。

最初に削除するのはcommaなので、よろしくお願いします。ダイナミック、スクリプトにはいくつかの問題がありますが何も選択

Declare @InList Table (KeyVal varchar(50),Include int) 

Insert Into @InList 
values ('Clean Label', @is_clean_label), 
     ('Key Interview', @Is_KeyInterview), 
     ('Special Report', @Is_SpecialReport) 

SELECT * 
FROM TABLE 
WHERE Name IN (SELECT KeyVal 
       FROM @InList 
       WHERE Include = (SELECT MAX(sign(Include)) FROM @InList)) 
0

おそらく必要はありません。

最初に、あなたのinのリストの先頭のカンマ。

第二に、あなたがあなたのinリストに単一引用符を追加していないのいずれか、何のフラグが

と第三に設定されていないとき処理していない:

DECLARE @sql NVARCHAR(MAX) = '' 
DECLARE @where NVARCHAR(MAX) 

IF @is_clean_label = 1 
SET @where = isnull(@where + ',','')+ N'''Clean Label''' 

IF @Is_KeyInterview = 1 
SET @where = isnull(@where + ',','')+ N'''Key Interview''' 

IF @Is_SpecialReport = 1 
SET @where = isnull(@where + ',','')+ N'''Special Report''' 

SET @sql = N' SELECT * FROM TABLE' 
      + case when @where <> '' 
        then ' WHERE Name in ('[email protected]+')' 
        else '' 
        end 
EXEC (@sql) 
+0

条件が適用されていない場合は、すべての値を返す必要があります。 – Ragul

+0

@Ragul元の質問に追加の要件を追加することができます。 – iamdave

+0

@Ragul十分に公正ですが、あなたの要求には言及されていません。それが "!"の価値があるかどうかわからない –

0

のすべてを含むように更新へ行く

SET @where = STUFF(@where, 1, 1, '') 
SET @sql = N' SELECT * FROM TABLE WHERE Name in ('[email protected]+')' 
1

まず、良い仕事をしようと手を差し伸べます非動的SQLの方法を見つける。

以下の「トリック」は、ルックアップテーブルのカウントを考慮することです。

IMHO、動的SQLの回答を含むすべての "試してください"を無視してください。問題が動的SQLなしで解決できる場合は、IMHOにする必要があります。ここでいくつかの問題について読むことができます:http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sqlそれを使用しても、それを使用するためのまともな方法と馬鹿な方法があります。

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL 
    begin 
      drop table #TableOne 
    end 


    CREATE TABLE #TableOne 
    ( 
    SurrogateKeyIDENTITY int not null IDENTITY (1,1) , 
    MyLabel varchar(16) 
    ) 

    Insert into #TableOne (MyLabel) select 'Clean Label' UNION ALL select 'Clean Label' UNION ALL select 'Key Interview' UNION ALL select 'Key Interview' UNION ALL select 'Special Report' UNION ALL select 'Special Report' UNION ALL select 'NotAMatch' UNION ALL select 'NotAMatch' 


Declare @LookupMatchTable Table (KeyVal varchar(50)) 
if(1=1) /* use your bool flags here */ 
begin 
    Insert Into @LookupMatchTable (KeyVal) Select 'Clean Label' 
end 
if(1=1) /* use your bool flags here */ 
begin 
    Insert Into @LookupMatchTable (KeyVal) Select 'Key Interview' 
end 
if(1=1) /* use your bool flags here */ 
begin 
    Insert Into @LookupMatchTable (KeyVal) Select 'Special Report' 
end 

declare @LookupMatchTableCount int 
select @LookupMatchTableCount = (select count(*) from @LookupMatchTable) 


SELECT * FROM #TableOne t1 WHERE (@LookupMatchTableCount = 0 OR EXISTS (Select KeyVal from @LookupMatchTable lmt where lmt.KeyVal = t1.MyLabel)) 

/* now show if there are no entries in the look up table, everything comes back */ 
delete from @LookupMatchTable 
select @LookupMatchTableCount = (select count(*) from @LookupMatchTable) 
SELECT * FROM #TableOne t1 WHERE (@LookupMatchTableCount = 0 OR EXISTS (Select KeyVal from @LookupMatchTable lmt where lmt.KeyVal = t1.MyLabel)) 


/* now show that if there is something in the lookup table that doesn't match the "real" table......no rows returned */ 
delete from @LookupMatchTable 
    Insert Into @LookupMatchTable (KeyVal) Select 'No Match Whatsoever' 
select @LookupMatchTableCount = (select count(*) from @LookupMatchTable) 
SELECT * FROM #TableOne t1 WHERE (@LookupMatchTableCount = 0 OR EXISTS (Select KeyVal from @LookupMatchTable lmt where lmt.KeyVal = t1.MyLabel)) 




    IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL 
    begin 
      drop table #TableOne 
    end 
0

動的SQLを忘れてしまった。下記の質問にお答えし、必要な変更があれば教えてください。

select * from TABLE 
where (Name ='Clean Label' or @is_clean_label=0) 
and ((Name ='Key Interview' or @Is_KeyInterview=0)) 
and ((Name ='Special Report' or @Is_SpecialReport=0)) 
関連する問題