Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

C# e SQL Server:il modo migliore per eliminare più righe in una volta sola utilizzando una stored procedure

Potresti usare parametri con valori di tabella per consegnare questo. Il livello dell'applicazione sarebbe simile a

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

Ci sono una serie di vantaggi in questo approccio rispetto alla creazione di stringhe

  • Eviti di creare query nel livello dell'applicazione, creando una separazione di preoccupazioni
  • Puoi testare più facilmente i piani di esecuzione e ottimizzare le query
  • Sei meno vulnerabile agli attacchi SQL injection, poiché il tuo approccio non sarebbe in grado di utilizzare una query parametrizzata per creare la clausola IN
  • Il codice è più leggibile e illustrativo
  • Non finisci per costruire stringhe eccessivamente lunghe

Prestazioni

Ci sono alcune considerazioni sulle prestazioni dei TVP su grandi set di dati.

Poiché i TVP sono variabili, non compilano statistiche. Ciò significa che a volte Query Optimizer può alterare il piano di esecuzione. Se ciò accade, ci sono un paio di opzioni:

  • imposta OPTION (RECOMPILE) su qualsiasi dichiarazione TVP in cui l'indicizzazione è un problema
  • Scrivi il TVP in una temperatura locale e imposta lì l'indicizzazione

Ecco un ottimo articolo sui TVP con una buona sezione sulle considerazioni sulle prestazioni e su cosa aspettarsi quando.

Quindi, se sei preoccupato di raggiungere i limiti sui parametri di stringa, i parametri con valori di tabella potrebbero essere la strada da percorrere. Ma alla fine, è difficile dirlo senza sapere di più sul set di dati con cui stai lavorando.