-2

次のようなストアド プロシージャがあります。

ALTER PROCEDURE [dbo].[T_TransactionSummary]  
 @locations nvarchar
AS
    BEGIN 
..............
.............
AND (Location_tbl.Locid IN (@locations))

私のlocidフィールドは整数です。このlocidはリストボックスから取得されます.1つのアイテムを選択すると1つのlocidが来ます.2つのアイテムを選択すると2つのlocidが来ます..@locationsパラメーター(整数)を入力するListBoxがありますリストボックスの値を次のように取りました

cnt = LSTlocations.SelectedItems.Count
 Dim list As New List(Of Integer)
        Dim locid As Integer
        If cnt > 0 Then
            For i = 0 To cnt - 1
                Dim locationanme As String = LSTlocations.SelectedItems(i).ToString
                locid = RecordID("Locid", "Location_tbl", "LocName", locationanme)
                list.Add(locid)
            Next
End If
 Dim da As New SqlDataAdapter
        Dim ds As New DataSet
        Dim cmd23 As New SqlCommand("T_TransactionSummary", con.connect)
        cmd23.CommandType = CommandType.StoredProcedure
        cmd23.Parameters.Add("@locations", SqlDbType.Int).Value = String.Join(",", list)
        da.SelectCommand = cmd23
        da.Fill(ds)  

現在、リストボックスからのロケーションIDはストアドプロシージャ1,2,3のみに渡されています。ただし、ストアド プロシージャは常に最初の値を取得します (この場合は 1 を取得することを意味します)。

4

2 に答える 2

7

まず、パラメータの長さを定義する必要があります...現在持っているのは、最初の文字で切り捨てられている文字列です。

DECLARE @locations NVARCHAR;
SET @locations = '1,2,3';
SELECT @locations;

結果:

1

あなたが言う必要があります

@locations VARCHAR(MAX)

NVARCHAR整数のコンマ区切りリストを保存する必要はありません。(整数の長いリストがあると思いますが、おそらく代わりにMAXなる可能性があり8000ます。)

次に、言うことはできませんIN (@locations)-これは正しく機能しません.int'1,2,3...'への変換に関するエラーメッセージが表示されるか、値が見つからないだけです-セットではなく文字列全体と比較しています。したがって、動的SQLでこれを行うことができます。

SET @sql = @sql + ' WHERE locations IN (' + @locations + ') ...;';

しかし、それには、保守性や SQL インジェクションへの露出など、他のあらゆる種類の問題が伴います。代わりに、テーブル値パラメーターを強くお勧めします。基本的に、次のようなタイプを作成します。

CREATE TYPE dbo.Integers AS TABLE(Item INT PRIMARY KEY);

次に、このようにパラメーターを使用します。

@locations dbo.Integers READONLY

そして、あなたは言うことができます:

WHERE EXISTS (SELECT 1 FROM @locations WHERE Item = Location_tbl.Locid)

VB.Net コードでは、リストボックスの選択内容を (int または文字列ではなく) DataTable に入力し、DataTable をSqlDbType.Structured. ここにいくつかの例がありますが、それらは C# です。

http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql

MSDN には、TVP に関するドキュメントも多数あります。

于 2013-10-21T16:54:19.823 に答える
1

以下が最初の問題です。

cmd23.Parameters.Add("@locations", SqlDbType.Int).Value = String.Join(",", list)

@locations パラメータを int として追加しています。値を割り当てると、VB は文字列を int に変換します。つまり"1,2,3,4"、 になり"1"ます。

それをに変更しますSqlDbType.VarChar


2番目に関しては、これができるかどうかは完全にはわかりません:

AND (Location_tbl.Locid IN (@locations))

代わりに、テーブル値パラメーターを調べることをお勧めします。

于 2013-10-21T16:54:12.663 に答える