0

次のデータを渡す C# アプリがあります。

データセット ID = 10; ユーザー ID = 1; varnames = "'ACT97','ACTCHNG','ACTQTR2','ACTSCOR2'";

ストアド プロシージャは次のとおりです。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[s_LockCheck]
-- Add the parameters for the stored procedure here
@varNames VARCHAR(max),
@datasetID INT,
@userID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

SELECT COUNT(*) as locked FROM VarLocks WHERE var_name IN (@varNames) AND dataset_id = @datasetID AND user_id != @userID AND is_locked = 1

END

しかし、そのように呼び出すと、それよりも高くなければならないときに 0 のカウントが返されます。

exec s_LockCheck "'ACT97','ACTCHNG','ACTQTR2','ACTSCOR2'", 88, 14

上記の各 ACTXXX は、列 var_name の変数名です。

IN句を正しく実行していないのはなぜですか?

4

1 に答える 1

1

これを実現するには、いくつかの方法があります。

  1. この記事で指摘されている動的SQL:http: //asheej.blogspot.com/2012/04/how-to-use-ms-sql-in-clause-with.html

  2. 変数で各項目を指定します(これは、'emがたくさんある場合はかなり醜くなる可能性があります):

    @ var1 varchar(20)、@ var2 varchar(20)、@ var3 varchar(20)

  3. 文字列をテーブル変数に変換する分割関数を記述します。それらの多くはそこにあります。これは私の個人的なお気に入りです:http: //dataeducation.com/faster-more-scalable-sqlclr-string-splitting/

  4. テーブル値パラメーターを使用する(2008):http ://www.techrepublic.com/blog/datacenter/passing-table-valued-parameters-in-sql-server-2008/168

  5. CHARINDEXを使用したちょっとしたコツを次に示します(このアプローチは非引数であることに注意してください)。

あなたの文字列は次のようになります:'abc、def'

を使用しCHARINDEXて、検索文字列と検索文字列内で検索する値の両方をデリメータで埋めます。したがって、私の小さな例を使用すると、文字列は'、abc、def'になります。最初と最後に余分なコンマがあることに注意してください。次に、フィールドデータに対して同じことを行います。データにコンマが含まれている場合は、区切り文字をchar(2)やセミコロンなどの他の文字に交換する必要があります。

次に、検索を実行します。

WHERE CHARINDEX ( ',' + expressionToFind + ',' , ',' + expressionToSearch ',') > 0

デリメータのパディングは、検索で「abcabc」が見つからないようにしますが、完全に一致する「abc」は見つかります。

2005を使用している場合は、動的SQLの使用を回避できるように、非常に高速な分割関数を使用します。

于 2012-07-06T00:35:33.580 に答える