6

以下は、すべてのフィールドを個別にチェックすることに基づいて、データベースに重複するエントリがあるかどうかをチェックするためのストアド プロシージャです (なぜこれを行う必要があるかは聞かないでください。このようにする必要があります)。

それは完全に簡単に聞こえますが、SP は失敗します。問題は、SP に渡される一部のパラメーターが null 値を持つ可能性があるため、SQL は「= null」ではなく「is null」と読み取る必要があることです。isnull()、case ステートメント、coalesce()、および exec() と sp_executesql を使用した動的 SQL を試しましたが、これらのいずれも実装できませんでした。これがコードです...

CREATE PROCEDURE sp_myDuplicateCheck
 @userId int,
 @noteType char(1),
 @aCode char(3),
 @bCode char(3), 
 @cCode char(3),
 @outDuplicateFound int OUT
AS
BEGIN
SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                          WHERE userId = @userId
                          AND noteType = @noteType
                          AND aCode = @aCode
                          AND bCode = @bCode
                          AND cCode = @cCode 
                          )
-- Now set the duplicate output flag to a 1 or a 0
IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
 SET @outDuplicateFound = 0
ELSE 
 SET @outDuplicateFound = 1
END
4

6 に答える 6

10

null の可能性のある各パラメーターには、次のようなものが必要だと思います。

AND (aCode = @aCode OR (aCode IS NULL AND @aCode IS NULL))
于 2008-12-19T12:59:50.200 に答える
7

あなたの質問を正しく理解できたら、次のことについて少し調べてみることをお勧めします。

SET ANSI_NULLS OFF

このコマンドをストアド プロシージャで使用すると、比較で = NULL を使用できます。次のコード例を見て、これがどのように機能するかを確認してください。

Declare @Temp Table(Data Int)

Insert Into @Temp Values(1)
Insert Into @Temp Values(NULL)

-- No rows from the following query
select * From @Temp Where Data = NULL

SET ANSI_NULLS OFF

-- This returns the rows where data is null
select * From @Temp Where Data = NULL

SET ANSI_NULLS ON

ANSI_NULLS をオフに設定した場合は、後で実行する他のクエリに影響を与える可能性があるため、できるだけ早くオンに戻すことをお勧めします。すべての SET コマンドは現在のセッションにのみ影響しますが、アプリケーションによっては複数のクエリにまたがる可能性があるため、このクエリの直後に ansi null をオンに戻すことをお勧めします。

于 2008-12-19T13:38:02.590 に答える
1

これは COALESCE 関数で動作するはずです。これを試して:

CREATE PROCEDURE sp_myDuplicateCheck
 @userId int,
 @noteType char(1),
 @aCode char(3),
 @bCode char(3), 
 @cCode char(3),
 @outDuplicateFound int OUT
AS
BEGIN

SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                          WHERE userId = @userId
                          AND noteType = @noteType
                          AND COALESCE(aCode,'NUL') = COALESCE(@aCode,'NUL')
                          AND COALESCE(bCode,'NUL') = COALESCE(@bCode,'NUL')
                          AND COALESCE(cCode,'NUL') = COALESCE(@cCode,'NUL')
                          )
-- Now set the duplicate output flag to a 1 or a 0
IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
 SET @outDuplicateFound = 0
ELSE 
 SET @outDuplicateFound = 1
END

幸運を!

ジェイソン

于 2008-12-19T13:32:07.547 に答える
0

最初に、実行時にすべてのパラメーターが null かどうかを確認するチェックを追加します。つまり、

IF(COALESCE(@userId, @noteType, @aCode, @bCode, @cCode) IS NULL)
   BEGIN
       -- do something here, log, print, return, etc.
   END

次に、ユーザーが何かを渡したことを検証した後、WHERE 句で次のようなものを使用できます

WHERE userId = COALESCE(@userId, userId)
AND noteType = COALESCE(@noteType, noteType)
AND aCode    = COALESCE(@aCode, aCode)
AND bCode    = COALESCE(@bCode, bCode)
AND cCode    = COALESCE(@cCode, cCode)

編集:パラメーターが null として渡された場合、列の null を明示的にテストする必要があるという意図を見逃した可能性があります。上記の where 句では、null パラメーターが「この列のテストをスキップする」ことを意味すると想定していました。

または、元のクエリを使用して、ストアド プロシージャの作成時に ANSI_NULLS セット オプションを追加できると思います。例えば、

SET ANSI_NULLS OFF
GO
CREATE PROC sp_myDuplicateCheck....

事実上、これにより、コードは column=null ではなく column=null を評価できるようになります。Kalen Delaney はかつて ANSI _NULLS および QUOTED_IDENTIFIERオプションを「スティッキー オプション」として造語したと思います。これは、プロシージャの作成時に設定されている場合、その時点での接続がどのように設定されているかに関係なく、実行時にプロシージャにとどまるからです。

于 2008-12-19T13:22:55.787 に答える
0

これを試して :

CREATE PROCEDURE sp_myDuplicateCheck
     @userId int = 0,
     @noteType char(1) = "",
     @aCode char(3) = "", 
     @bCode char(3) = "", 
     @cCode char(3) = "",
     @outDuplicateFound int OUT
    AS
    BEGIN
    SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                              WHERE @userId in (userId ,0)
                              AND @noteType in (noteType,"")
                              AND @aCode in (aCode , "")
                              AND @bCode in (bCode , "")
                              AND @cCode in (cCode ,"")
                              )
    -- Now set the duplicate output flag to a 1 or a 0
    IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
     SET @outDuplicateFound = 0
    ELSE 
     SET @outDuplicateFound = 1
    END

これが基本的に行うことは、null の場合に入力パラメーターにデフォルト値を提供し、値がデフォルト値と等しくないかどうかのみを where 条件でチェックすることです。

于 2008-12-19T13:31:02.947 に答える
0

SET ANSI_NULLS OFF/On

そうすればできるcolName = null

于 2010-06-18T15:34:36.543 に答える