6

パラメータを省略できるストアド プロシージャを作成しようとしていますが、指定されている場合は AND します。

CREATE PROCEDURE 
    MyProcedure

    @LastName Varchar(30) = NULL,
    @FirstName Varchar(30) = NULL,
    @SSN INT = NULL
AS

SELECT LastName, FirstName, RIGHT(SSN,4) as SSN
FROM Employees
WHERE 
    (
        (LastName like '%' + ISNULL(@LastName, '') + '%')
            AND 
        (FirstName like '%' + ISNULL(@FirstName, '') + '%')
    )
AND
    (SSN = @SSN)

@SSN が提供されている場合にのみ AND を実行したい。または、これを行う他の方法はありますか?

SSN が指定されている場合、クエリの LastName/FirstName 部分によってすべてのレコードが返されます。姓/名のみが提供された場合、AND は、SSN が検証されないため、レコードが返されないようにします。

アイデア?


追加説明

基本的なレコードセットを想定します。

First          Last          SSN  
Mike           Smith         123456789  
Tom            Jones         987654321

上記の手順を変更して、このチャンクが含まれないようにする場合:

AND
    (SSN = @SSN)

FirstName または LastName が渡されれば、すべてうまくいきます。ただし、提供されている場合は、SSN を含めることができるようにしたいと考えています。

AND を OR に変更すると、クエリの FirstName/LastName 部分が次のように評価されるため、不適切な結果セットが得られます。

WHERE (LastName like '%%' and FirstName like '%%')

(もちろん、すべてのレコードが返されます)


AND を条件付きで中止できない場合は、次のようなことを望んでいます。

AND
    (SSN like ISNULL(@SSN, '%'))

:-)

4

5 に答える 5

16

変化する:

AND (SSN = @SSN) 

に:

AND (SSN = @SSN or @SSN is null)

null にならない場合SSNは、次のこともできます。

AND SSN = ISNULL(@SSN, SSN)
于 2012-10-11T17:29:56.260 に答える
0
CREATE PROCEDURE 
    MyProcedure

    @LastName Varchar(30) = NULL,
    @FirstName Varchar(30) = NULL,
    @SSN INT = -1
AS

SELECT LastName, FirstName, RIGHT(SSN,4) as SSN
FROM Employees
WHERE 
    (
        (LastName like '%' + ISNULL(@LastName, '') + '%')
            AND 
        (FirstName like '%' + ISNULL(@FirstName, '') + '%')
    )
AND
    (SSN = @SSN or @SSN = -1)

@SSN にデフォルト値を与えるだけで、常に AND を使用して心配することができます。

于 2012-10-11T19:02:55.707 に答える
0

HERE's THE BIBLE SQL Server の動的検索パラメーターについて。このように書くべきです

SELECT LastName, FirstName, RIGHT(SSN,4) as SSN
FROM Employees
WHERE (NULLIF(@LastName,'') IS NULL OR LastName LIKE '%' + @LastName + '%')
  AND (NULLIF(@FirstName,'') IS NULL OR FirstName LIKE '%' + @FirstName + '%')
  AND (@SSN is null or SSN = @SSN)
   -- or if not provided means blank, then
   -- (@SSN = '' or SSN = @SSN)
OPTION (RECOMPILE)

ところで、SQL Server には短絡ブール値のようなものはありません。はい、最初の結論で停止しますが、左側の条件が右側の条件の前に処理されるという保証はありません。たとえば、このコードは安全ではありません。私は「ABC.123」を使用していますが、それは列でも構いません。

WHERE ISNUMERIC('ABC.123') = 1 OR CAST('ABC.123' AS INT) > 10

AND (@SSN is null or SSN = @SSN)@SSN が指定されていない場合、つまり NULLの句について説明します。

   AND (@SSN is null or SSN = NULL)
=> AND (NULL IS NULL or SSN = NULL)
=> AND (TRUE or SSN = NULL)
=> AND (TRUE)

-- In other words, this filter is "dissolved" and appears as if it never existed.
-- (in the scheme of a series of AND conditions)
于 2012-10-11T17:46:21.403 に答える
0

あなたも試すことができます:

(ISNULL(SSN, @SSN) = @SSN)
于 2012-10-11T17:32:08.213 に答える
0

ステートメントの両方のバージョンを if ブロックに入れることができます。

 AS
 IF @SSN IS NULL
      /*regular statement*/
 ELSE
      /*Statement with @SSN*/

また

 AND
      SSN = ISNULL(@SSN, SSN)

2番目のオプションを使用したことはありませんが、存在することは知っています。

于 2012-10-11T17:32:34.817 に答える