sql >> データベース >  >> RDS >> Sqlserver

それぞれが2000を超えるパラメータを持つリストを渡す必要があるシナリオで、データベースからレコードを取得する最適な方法は何ですか?

    これが実際にこのトピックにアプローチする必要がある場合は、テーブル値パラメーターを使用することをお勧めします。

    • まず、SQL 2008 以降を使用しているため、ストアド プロシージャに切り替えます。
    • 次に、using を読んでください。 yoursql アイテムを破棄するためのステートメント。

    疑似データ層:

    public List<SalesList> ExecuteSales(List<string> items, int storeID, int W1, int W2, int vendorID, int retailerID)
    {
        var sales = new List<SalesList>();
        var table = new DataTable();
        table.Columns.Add("ItemNumber");
        foreach (var item in items)
        {
            table.Rows.Add(item);
        }
        using (var connection = new SqlConnection("ConnectionString"))
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandType = CommandType.StoredProcedure;
                command.CommandText = "cp_ExecuteSales";
                command.Parameters.AddWithValue("@RetailerID", retailerID);
                command.Parameters.AddWithValue("@VendorID", vendorID);
                command.Parameters.AddWithValue("@StoreID", storeID);
                var tvp = new SqlParameter("@ItemIds", SqlDbType.Structured)
                {
                     TypeName = "tvpItems",
                     Value = table
                };
                command.Parameters.Add(tvp);
                using (var reader = command.ExecuteReader())
                {
                    //DoWork
                }
            }
        }
        return sales;
    }
    

    tvp を作成します:

    CREATE TYPE [dbo].[tvpItems] AS TABLE(
    [ItemNumber] [int] NULL
    

    )

    ストアド プロシージャを作成します。

    CREATE PROCEDURE cp_ExecuteSales
         @RetailerID VARCHAR(50),
         @VendorID VARCHAR(50),
         @StoreID VARCHAR(50),
         @ItemIds tvpItems READONLY
    AS
      SELECT  I.ITEM_NBR
              ,I.ITEM_DESC1
              ,I.ITEM_DESC2
              ,I.VENDOR_STK_NBR
              ,SUM(SA.POS_QTY) AS POS_QTY
              ,SUM(SA.POS_SALES) AS POS_SALES
      FROM  SALES_FTBL SA
            INNER JOIN ITEM_TBL I ON SA.RETAILER_ID = I.RETAILER_ID 
                AND SA.ITEM_NBR = I.ITEM_NBR
            INNER JOIN @ItemIds ID ON SA.ITEM_NBR = ID.ItemNumber
      WHERE SA.RETAILER_ID=I.RETAILER_ID
            AND SA.RETAILER_ID = @RetailerID
            AND SA.VENDOR_NBR  = @VendorID
            AND SA.STORE_NBR  = @StoreID
            AND SA.ITEM_NBR=I.ITEM_NBR
    

    数値パラメーターの 2 番目のセットを追加する必要がある場合は、異なる型の複数のパラメーターをデータベースに渡すことができます。過去に、多数のテーブル タイプを管理するのではなく、データ タイプのさまざまなリストをサポートするために、いくつかのジェネリック タイプを作成しました。

    CREATE TYPE [dbo].[IntList] AS TABLE(
        [Value] [Int] NULL
    )
    

    覚えておくべき重要事項:

    • tvp のパラメータ タイプは SqlDbType.Structured でなければなりません
    • TypeName パラメータは、テーブル値のパラメータ タイプ名と一致する必要があります。
    • ストアド プロシージャのテーブル値パラメータ パラメータは、READONLY として宣言する必要があります



    1. すべての列の最も一般的な値を取得します

    2. Oracle PL/SQLプロシージャの実行速度がSQLより遅い

    3. MySQL:トリガーでSIGNALを使用できません

    4. SQL Serverで主キーを作成する方法(T-SQLの例)