sql >> Databasteknik >  >> RDS >> Sqlserver

Vilket är det optimala sättet att hämta poster från databasen i ett scenario där du måste passera listor som var och en av dem har mer än 2000 parametrar?

Tabellvärderade parametrar är rätt väg att gå om det verkligen är så du behöver närma dig det här ämnet.

  • Byt först till en lagrad procedur eftersom du använder SQL 2008 eller nyare.
  • För det andra, läs på using uttalande för kassering av yoursql-objekt.

Psuedo-datalager:

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;
}

Skapa tvp:

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

)

Skapa den lagrade processen:

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

Om du behöver lägga till en andra uppsättning nummerparametrar kan du skicka flera parametrar av olika typer till databasen. Tidigare har vi skapat flera generiska typer för att stödja olika listor med datatyper istället för att behöva hantera många tabelltyper.

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

Viktiga saker att komma ihåg:

  • Parametertypen för en tvp måste vara SqlDbType.Structured
  • TypeName för parametern måste matcha tabellvärdesparametertypnamnet.
  • Table Value Parameter-parametern i den lagrade proceduren måste deklareras som READONLY



  1. Hur man byter ut en ny linje i Oracle

  2. SQLite MAX

  3. hur får man ett sorterat resultat i mysql-frågan?

  4. Exkludera en kolumn med SELECT * [utom kolumnA] FRÅN tabellA?