1

を使用してデータをページングしObjectDataSourceており、次の方法があります。

public int GetNumberOfArticles(string employeeIds)
{
    System.Data.DataTable dataTable;
    System.Data.SqlClient.SqlDataAdapter dataAdapter;
    System.Data.SqlClient.SqlCommand command;

    int numberOfArticles = 0;

    command = new System.Data.SqlClient.SqlCommand();
    command.Connection = Classes.Database.SQLServer.SqlConnection;

    command.CommandText = @"SELECT COUNT(*)
                            FROM 
                                  [Articles]
                            WHERE 
                                  [Articles].[EmployeeID] IN (@EmployeeIds)";

    command.Parameters.AddWithValue("@EmployeeIds", employeeIds);
    numberOfArticles = (int)command.ExecuteScalar();
    return numberOfArticles;
}

EmployeeIDは整数であるため、内部に配置したものはすべてemployeeIds整数に変換されます。ただし、キーワードを使用しているため、コンマで区切られた ID のリストINに置き換えたいことは明らかです。employeeIds

1, 2, 3

しかし、行を置き換えると:

command.Parameters.AddWithValue("@EmployeeIds", employeeIds);

次のようなもので:

command.Parameters.AddWithValue("@EmployeeIds", "1, 2, 3");

EmployeeIdsが整数であるときに文字列を指定したため、例外が発生します。それで、どうすればそれを行うことができますか?

ありがとう。

編集:

返信から、これは手動で行う必要があることを理解していますが、このメソッドを含むクラスは によって自動的に作成されますObjectDataSourceemployeeIdsでは、実行時に値を提供するにはどうすればよいですか?

4

4 に答える 4

2

INこれを行う唯一の方法は、クエリで文字列を手動で解析し、値をメモリ テーブルに挿入してから、句を使用するのではなくクエリでメモリ テーブルを結合することです。

例として、CodeProject のこのページでは、次の関数を紹介しています。

IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID(’UF_CSVToTable’))
 DROP FUNCTION UF_CSVToTable
GO

CREATE FUNCTION UF_CSVToTable
(
 @psCSString VARCHAR(8000)
)
RETURNS @otTemp TABLE(sID VARCHAR(20))
AS
BEGIN
 DECLARE @sTemp VARCHAR(10)

 WHILE LEN(@psCSString) > 0
 BEGIN
  SET @sTemp = LEFT(@psCSString, ISNULL(NULLIF(CHARINDEX(',', @psCSString) - 1, -1),
                    LEN(@psCSString)))
  SET @psCSString = SUBSTRING(@psCSString,ISNULL(NULLIF(CHARINDEX(',', @psCSString), 0),
                               LEN(@psCSString)) + 1, LEN(@psCSString))
  INSERT INTO @otTemp VALUES (@sTemp)
 END

RETURN
END
Go

次に、次のように使用できます。

SELECT                          
    COUNT(*)
FROM 
    [Articles]

JOIN dbo.UF_CSVToTable(@EmployeeIds) ids on ids.sID = [Articles].[EmployeeID]

とはいえ、結局のところ、これは一般的にはあまり良い習慣ではありません。ただし、必要な場合は、このアプローチで非常に簡単な方法で提供する必要があります。

于 2009-04-12T13:47:50.327 に答える
1

この質問と同様に、実行時に各値のパラメーターを追加する必要があります。

public int GetNumberOfArticles(string employeeIds)
{
    System.Data.DataTable dataTable;
    System.Data.SqlClient.SqlDataAdapter dataAdapter;
    System.Data.SqlClient.SqlCommand command;

    int numberOfArticles = 0;

    command = new System.Data.SqlClient.SqlCommand();
    command.Connection = Classes.Database.SQLServer.SqlConnection;

    string params = string.Join(",", employeeIds.Select((e, i)=> "@employeeId" + i.ToString()).ToArray());
    command.CommandText = @"SELECT                          
                               COUNT(*)
                            FROM 
                               [Articles]
                            WHERE 
                               [Articles].[EmployeeID] IN (" + params + ")";

    for (int i = 0; i < employeeIds.Length; i++) {
       command.Parameters.AddWithValue("@employeeId" + i.ToString(), employeeIds[i]);
    }

    numberOfArticles = (int)command.ExecuteScalar();

    return numberOfArticles;
}
于 2009-04-12T14:53:53.010 に答える
0

パラメータは個別の値であり、実行しようとしているように SQL ステートメントを動的に作成するために使用することはできません。次のように単純な文字列連結を使用して SQL ステートメントを作成する必要があります。

command.CommandText = @"SELECT COUNT(*) FROM [Articles] " +
    "WHERE [Articles].[EmployeeID] IN (" + employeeIds + ")";

ただし、employeeIds 文字列がユーザー入力によるものである場合は、SQL インジェクションの脆弱性を回避するためにサニタイズする必要があります。文字列を配列に分割し、各要素を解析して int であることを確認することで、これを行うことができます。合格した場合は、連結する前に配列を文字列に再結合できます。

于 2009-04-12T14:00:03.230 に答える