Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

C# &SQL Server - най-добрият начин за изтриване на няколко реда наведнъж с помощта на съхранена процедура

Можете да използвате параметри с таблична стойност, за да предадете това. Приложният слой би изглеждал нещо като

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

Има редица предимства на този подход пред изграждането на низове

  • Избягвате да създавате заявки в приложния слой, създавайки разделяне на проблеми
  • Можете по-лесно да тествате планове за изпълнение и да оптимизирате заявките
  • Вие сте по-малко уязвими за атаки чрез SQL инжектиране, тъй като вашият даден подход няма да може да използва параматеризирана заявка за изграждане на клаузата IN
  • Кодът е по-четлив и илюстративен
  • В крайна сметка не създавате прекалено дълги низове

Ефективност

Има някои съображения относно ефективността на TVP върху големи масиви от данни.

Тъй като TVP са променливи, те не съставят статистика. Това означава, че понякога оптимизаторът на заявките може да изкриви плана за изпълнение. Ако това се случи, има няколко опции:

  • задайте OPTION (RECOMPILE) във всички TVP изявления, където индексирането е проблем
  • запишете TVP в локален temp и настройте индексирането там

Ето страхотна статия за TVP с добър раздел за съображения за ефективност и какво да очаквате кога.

Така че, ако се притеснявате за достигане на ограниченията на параметрите на низа, параметрите със стойност на таблицата може да са правилният начин. Но в крайна сметка е трудно да се каже, без да знаете повече за набора от данни, с който работите.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разлика между sys.objects, sys.system_objects и sys.all_objects в SQL Server

  2. SQL:Намерете пътищата на липсващите папки в йерархиите за разделяне

  3. 5 начина за преброяване на броя на дефинирани от потребителя таблици в база данни на SQL Server

  4. Стойността на колоната за идентичност изведнъж скача до 1001 в sql сървъра

  5. Имитация в изгледи на SQL Server?