sql >> Databasteknik >  >> RDS >> Sqlserver

C# &SQL Server - bästa sättet att ta bort flera rader på en gång med hjälp av en lagrad procedur

Du kan använda tabellvärderade parametrar för att ge detta. Applikationsskiktet skulle se ut ungefär som

C#

var tvp = new DataTable();
tvp.Columns.Add("Id", typeof(int));

foreach(var id in RecIdsToDelete)
    tvp.Rows.Add(new {id});

var connection = new SqlConnection("your connection string");

var delete = new SqlCommand("your stored procedure name", connection)
{
  CommandType = CommandType.StoredProcedure
};

delete
  .Parameters
  .AddWithValue("@ids", tvp)
  .SqlDbType = SqlDbType.Structured;

delete.ExecuteNonQuery();

SQL

IF NOT EXISTS(SELECT * FROM sys.table_types WHERE name = 'IDList')
BEGIN
    CREATE TYPE IDList AS TABLE(ID INTEGER)
END


CREATE PROCEDURE School.GroupStudentDelete
(                                         
        @IDS IDLIST READONLY      
)                                         
AS

SET NOCOUNT ON;

BEGIN TRY
        BEGIN TRANSACTION

        DECLARE @Results TABLE(id INTEGER)

        DELETE 
        FROM TblName 
        WHERE Id IN (SELECT ID FROM @IDS)        

        COMMIT TRANSACTION
END TRY
BEGIN CATCH
        PRINT ERROR_MESSAGE();

        ROLLBACK TRANSACTION
        THROW; -- Rethrow exception
END CATCH
GO

Det finns ett antal fördelar med detta tillvägagångssätt jämfört med att bygga strängar

  • Du undviker att skapa frågor i applikationslagret, vilket skapar en separation av bekymmer
  • Du kan enklare testa exekveringsplaner och optimera frågor
  • Du är mindre sårbar för SQL-injektionsattacker, eftersom ditt givna tillvägagångssätt inte skulle kunna använda en paramatiserad fråga för att bygga IN-satsen
  • Koden är mer läsbar och illustrativ
  • Det slutar inte med att du bygger för långa strängar

Prestanda

Det finns några överväganden om TVP:ers prestanda på stora datamängder.

Eftersom TVP är variabler, sammanställer de inte statistik. Detta innebär att frågeoptimeraren ibland kan förvränga exekveringsplanen. Om detta händer finns det ett par alternativ:

  • ställ in OPTION (RECOMPILE) på alla TVP-uttalanden där indexering är ett problem
  • skriv in TVP till en lokal temp och ställ in indexeringen där

Här är en bra artikel om TVP:s med ett bra avsnitt om prestandaöverväganden och vad du kan förvänta dig när.

Så om du är orolig för att nå gränser för strängparametrar kan de tabellvärderade parametrarna vara rätt väg att gå. Men i slutändan är det svårt att säga utan att veta mer om den datamängd du arbetar med.



  1. Korrekt sätt att kommentera ett rangfält för en frågeuppsättning

  2. Är mysql_insert_id säkert att använda?

  3. Referensfel på node.js vid inkluderingsfil

  4. MySQL Välj alla kolumner från en tabell och några från en annan tabell