2012-02-17 3 views
1

私は、アドレスを選択するストアド・プロシージャを作成しています。多くの選択パラメータがありますが、問題の原因は状態の選択です。 国は必須で、1つ以上の国名を使用できます。 国がUSAの場合、状態はNULLまたは1対多の状態コードになります。 は、私はテーブル値関数(ParmTable_String)を持っているので、私は、パラメータリストに参加することができますし、状態コードがある場合、これは動作します:SQLのパラメータ・リストまたはnullへの結合

DECLARE @Country AS varchar(MAX); 
DECLARE @State AS varchar(256); 
SET @Country = 'USA'; 
SET @State = 'ME, VT'; 
SELECT * 
FROM Customer 
JOIN ParmTable_String(@Country, ',') AS CT 
ON Country = CT.str 
JOIN ParmTable_String(@State, ',') AS ST 
ON State = ST.str 

しかし@State = null場合、私はNULLの結果セットを取得します。これを左結合してwhere句を追加すると、単一の状態コードまたはnullでは動作しますが、リストでは機能しません。

WHERE State = @State OR @State IS NULL 

誰でもこれに対応していますか?

OK、私は解決策を持っているが、私は、これは私には少し原油だとして、より良い方法があることを考えている:

DECLARE @Country AS varchar(MAX); 
DECLARE @State AS varchar(256); 
SET @Country = 'USA'; 
SET @State = 'ME, VT'; 
SELECT * 
FROM Customer 
JOIN ParmTable_String(@Country, ',') AS CT 
ON Country = CT.str 
WHERE (State IN 
(SELECT str from lntw.ParmTable_String(@State, ',')) OR @State IS NULL) 
+0

ansi_nullsをオフに設定しましたか? –

+0

はい、テーブル値関数から返された文字列にNULLIFを試しましたが、結果は返されませんでした。 – GBrookman

+0

ParmTable_Stringのコードと期待される結果の例を掲載してください。私は良い解決策を持っていると思うが、それを知るのは難しい... –

答えて

0

私は、SQL Serverに慣れていないいないですが、このような何かあれば疑問に思って**私はNULLIFを想定しています

State = NULLIF(@State,State) 

を働くかもしれないことはST.strが空の文字列の場合はnullを返します神託のNVLと等価なもの()関数

+0

ありがとう、しかし、問題は@ステートが 'ME、VT、MA、NH、CT'なので複数の値を扱えないようになる – GBrookman

0

NULLIF(ST.str、 '')です。次にState = NULLを実行しようとすると、レコードは返されません。

IF @State is null 
BEGIN 
    SELECT * FROM Customer 
    JOIN ParmTable_String(@Country, ',') AS CT 
    ON Country = CT.str 
END 
ELSE 
BEGIN 
    SELECT * FROM Customer 
    JOIN ParmTable_String(@Country, ',') AS CT 
    ON Country = CT.str 
    JOIN ParmTable_String(@State, ',') AS ST 
    ON State = ST.str 
END 
+0

ありがとうございますが、左側のジョインオプションの問題はwhere節です。 。私はまだ試していないが、私はwhere節でテーブル値付きの関数からselectを追加することができると思うが、私はちょっと単純なものを見逃していると思っている。 – GBrookman

+0

左の結合を使ってwhere句の複数の状態をフィルタリングする方法は次のとおりです: '' ca '、' ny '、' ak ')のisnull(状態、' ') ' –

+0

isnull( ) 関数。それは、列をフィルタリングしたいだけでなく、その列がnullの行を保持したい場合に役立ちます。 –

0
あなたが持っている

OR:

一致する状態があるかどうか、それは顧客レコードを返す必要があり、これを試してみてください約

DECLARE @Country AS varchar(MAX);
DECLARE @State AS varchar(256);
SET @Country = 'USA';
SET @State = 'ME、VT';カスタマー
FROM
SELECT *
はAS( 'ISNULL(@state、 ' ')、')CT
国= CT.str
LEFT JOINのON ParmTable_String AS ParmTable_String(@Countryを、'、')に参加しますST
オン状態= ST.str

+0

質問へのコメントで言及したように、私はこのアプローチがシンプルであることをお勧めします。 – blntechie

+0

私はSQLにうまくいかないので? :)実際のクエリはかなり複雑です。 where句には多くの条件があり、a *にはselectにはさらに多くの条件に関する12のパラメータがあります。私がIFルートに行くと、@Stateロジック以外のすべてをdupする必要がありますか?それはORなしでもっと速いですか?私は複数の手順を考えましたが、それはもっと複雑に思えました。 – GBrookman

+0

12人(階乗)のクエリを書く人はいません。ここでは、クエリ実行*中にパラメータが評価される単一のクエリを作成するときに、クエリオプティマイザが適切なクエリプランを作成する機能を削除します。それは神の質問のための単一の計画を作成し、その単一の計画はすべてのパラメータの組み合わせに適していないかもしれません。これらの問題の両方を回避するためには、ほとんどの人が何らかの動的SQL /またはマシンのクエリ構築を使用します。オプティマイザに到達する前に各クエリを作成します。 –

0

方法:なぜいない代わりに、2つのクエリしてみてください...

DECLARE @Country AS varchar(MAX); 
DECLARE @State AS varchar(256); 
SET @Country = 'USA'; 
SET @State = 'ME, VT'; 

SELECT * 
FROM Customer 
    JOIN ParmTable_String(@Country, ',') AS CT 
     ON Country = CT.str 
    JOIN ParmTable_String(isnull(@State,''), ',') AS ST 
     ON (State = ST.str or State is null) 
+0

ありがとうございますが、左の結合ではwhere節が必要ですが、それは状態をフィルタリングしないで、複数の状態の問題にぶつかります。 – GBrookman

+0

ああ、申し訳ありませんが、必要なのはwhere句を変更することです。基本的には、@stateがnullでないときには一致する状態だけが必要だが、すべての状態が必要なときは正しいと言っているだろうか? – Mordechai

+0

はコメントインターフェースを理解できないようです。いずれの場合でも、WHERE ST.strがNULLでないか、または "@state"がnullです。これにより、意図したとおりに条件付きの左/右結合を行うことができます – Mordechai

関連する問題