Как удалить запись в бд sql
Перейти к содержимому

Как удалить запись в бд sql

  • автор:

Как удалить запись в бд sql

Команда DELETE удаляет данные из БД. Она имеет следующий формальный синтаксис:

DELETE FROM имя_таблицы [WHERE условие_удаления]

Например, удалим строки, у которых производитель — Huawei:

DELETE FROM Products WHERE Manufacturer='Huawei';

Команда DELETE в MySQL

Или удалим все товары, производителем которых является Apple и которые имеют цену меньше 60000:

DELETE FROM Products WHERE Manufacturer='Apple' AND Price < 60000;

Если необходимо вовсе удалить все строки вне зависимости от условия, то условие можно не указывать:

DELETE FROM Products;

Практическое руководство. Как удалить строки из базы данных

Вы можете удалить строки в базе данных, удалив соответствующие объекты LINQ to SQL из коллекции, связанной с таблицами. LINQ to SQL преобразует изменения в соответствующие команды SQL DELETE .

LINQ to SQL не поддерживает и не распознает операции каскадного удаления. Если требуется удалить строку в таблице, имеющей ограничения, необходимо выполнить любую из следующих задач.

  • Установите правило ON DELETE CASCADE в ограничении внешнего ключа в базе данных.
  • Используйте собственный код, чтобы сначала удалить дочерние объекты, не допускающие удаление родительского объекта.

В противном случае создается исключение. См. второй пример кода далее в этом разделе.

Вы можете переопределить LINQ to SQL методы по умолчанию для Insert операций с базой данных , Update и Delete . Дополнительные сведения см. в разделе Настройка операций вставки, обновления и удаления.

Разработчики, использующие Visual Studio, могут использовать реляционный конструктор объектов для разработки хранимых процедур с той же целью.

В следующих шагах предполагается, что подключение к базе данных Northwind выполняется с помощью допустимого объекта DataContext. Дополнительные сведения см. в разделе Практическое руководство. Подключение к базе данных.

Удаление строки в базе данных

  1. Отправьте в базу данных запрос на удаляемую строку.
  2. Вызовите метод DeleteOnSubmit.
  3. Отправьте изменение в базу данных.

Пример 1

В первом примере кода в базу данных отправляется запрос на сведения о заказе "Order #11000", помечаются сведения для удаления, а изменения отправляются в базу данных.

// Query the database for the rows to be deleted. var deleteOrderDetails = from details in db.OrderDetails where details.OrderID == 11000 select details; foreach (var detail in deleteOrderDetails) < db.OrderDetails.DeleteOnSubmit(detail); >try < db.SubmitChanges(); >catch (Exception e) < Console.WriteLine(e); // Provide for exceptions. >
' Query the database for the rows to be deleted. Dim deleteOrderDetails = _ From details In db.OrderDetails() _ Where details.OrderID = 11000 _ Select details For Each detail As OrderDetail In deleteOrderDetails db.OrderDetails.DeleteOnSubmit(detail) Next Try db.SubmitChanges() Catch ex As Exception Console.WriteLine(ex) ' Provide for exceptions End Try 

Пример 2

Целью второго примера является удаление заказа (с номером 10250). Код сначала проверяет таблицу OrderDetails на наличие в ней дочерних элементов удаляемого заказа. Если в таблице есть дочерние элементы заказа, сначала они, а затем сам заказ помечаются для удаления. DataContext располагает фактические действия по удалению в надлежащей последовательности, чтобы команды удаления, отправляемые в базу данных, подчинялись ее ограничениям.

Northwnd db = new Northwnd(@"c:\northwnd.mdf"); db.Log = Console.Out; // Specify order to be removed from database int reqOrder = 10250; // Fetch OrderDetails for requested order. var ordDetailQuery = from odq in db.OrderDetails where odq.OrderID == reqOrder select odq; foreach (var selectedDetail in ordDetailQuery) < Console.WriteLine(selectedDetail.Product.ProductID); db.OrderDetails.DeleteOnSubmit(selectedDetail); >// Display progress. Console.WriteLine("detail section finished."); Console.ReadLine(); // Determine from Detail collection whether parent exists. if (ordDetailQuery.Any()) < Console.WriteLine("The parent is present in the Orders collection."); // Fetch Order. try < var ordFetch = (from ofetch in db.Orders where ofetch.OrderID == reqOrder select ofetch).First(); db.Orders.DeleteOnSubmit(ordFetch); Console.WriteLine("OrderID is marked for deletion.", ordFetch.OrderID); > catch (Exception e) < Console.WriteLine(e.Message); Console.ReadLine(); >> else < Console.WriteLine("There was no parent in the Orders collection."); >// Display progress. Console.WriteLine("Order section finished."); Console.ReadLine(); try < db.SubmitChanges(); >catch (Exception e) < Console.WriteLine(e.Message); Console.ReadLine(); >// Display progress. Console.WriteLine("Submit finished."); Console.ReadLine(); 
Dim db As New Northwnd("c:\northwnd.mdf") db.Log = Console.Out ' Specify order to be removed from database. Dim reqOrder As Integer = 10252 ' Fetch OrderDetails for requested order. Dim ordDetailQuery = _ From odq In db.OrderDetails _ Where odq.OrderID = reqOrder _ Select odq For Each selectedDetail As OrderDetail In ordDetailQuery Console.WriteLine(selectedDetail.Product.ProductID) db.OrderDetails.DeleteOnSubmit(selectedDetail) Next ' Display progress. Console.WriteLine("Detail section finished.") Console.ReadLine() ' Determine from Detail collection whether parent exists. If ordDetailQuery.Any Then Console.WriteLine("The parent is present in the Orders collection.") ' Fetch order. Try Dim ordFetch = _ (From ofetch In db.Orders _ Where ofetch.OrderID = reqOrder _ Select ofetch).First() db.Orders.DeleteOnSubmit(ordFetch) Console.WriteLine(" OrderID is marked for deletion.,", ordFetch.OrderID) Catch ex As Exception Console.WriteLine(ex.Message) Console.ReadLine() End Try Else Console.WriteLine("There was no parent in the Orders collection.") End If ' Display progress. Console.WriteLine("Order section finished.") Console.ReadLine() Try db.SubmitChanges() Catch ex As Exception Console.WriteLine(ex.Message) Console.ReadLine() End Try ' Display progress. Console.WriteLine("Submit finished.") Console.ReadLine() 

См. также раздел

  • Практическое руководство. Как управлять конфликтами изменений
  • Практическое руководство. Назначение хранимых процедур для выполнения обновления, вставки и удаления (реляционный конструктор объектов)
  • Внесение и отправка изменений данных

Удаление записей из базы данных

Чтобы удалить запись из базы данных с помощью LINQ to SQL, понадобится удалить сущностный объект из Таb1е, членом которой он является, вызвав метод DeleteOnSubmit объекта Таb1е. После этого, конечно, необходимо вызвать метод SubmitChanges. Пример приведен ниже.

В отличие от прочих примеров, в этом примере база данных в исходное состояние не восстанавливается. Причина в том, что одна из участвующих таблиц содержит столбец идентичности, и не так просто программно восстановить данные в состояние, предшествовавшее запуску примера. Поэтому перед запуском примера удостоверьтесь в наличии резервной копии базы данных.

Если вы загрузили упакованную расширенную версию базы данных Northwind, то после запуска этого примера можете просто отсоединить базу данных Northwind, заново извлечь файлы базы данных и снова подключить ее к серверу базы.

// Используйте свою строку подключения Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS; AttachDbFilename=C:\Northwind.mdf; Integrated Security=True"); Customer cust = (from c in db.Customers where c.CustomerID == "ALFKI" select c).Single(); db.OrderDetails.DeleteAllOnSubmit( cust.Orders.SelectMany(o => o.OrderDetails)); db.Orders.DeleteAllOnSubmit(cust.Orders); db.Customers.DeleteOnSubmit(cust); db.SubmitChanges(); Customer cust2 = (from c in db.Customers where c.CustomerID == "ALFKI" select c).SingleOrDefault(); MessageBox.Show(String.Format("Заказчик найден", cust2 != null ? "успешно" : "не"));

Этот пример достаточно прямолинеен, но не лишен интересных аспектов. Во-первых, поскольку таблица Orders содержит внешний ключ, ссылающийся на таблицу Customers, нельзя удалить заказчика без предварительного удаления всех его заказов. И поскольку таблица OrderDetails содержит внешний ключ, ссылающийся на таблицу Orders, нельзя удалить заказ, не удалив его деталей. Таким образом, чтобы удалить заказчика, сначала понадобится удалить детали всех его заказов, затем сами его заказы, и только потом — собственно заказчика.

Удаление всех заказов не представляет труда, благодаря операции DeleteAllOnSubmit, которая может удалить последовательность заказов. Однако удаление деталей каждого заказа несколько сложнее. Конечно, можно было бы выполнить перечисление последовательности заказов, вызывая операцию DeleteAllOnSubmit на каждой последовательности деталей заказов, но это утомительно. Вместо этого вызывается операция SelectMany для получения последовательности последовательностей деталей заказов и затем создается единая совокупная последовательность деталей заказов, которая передается операции DeleteAllOnSubmit.

После удаления деталей заказов, самих заказов и их заказчика вызывается метод SubmitChanges. Чтобы доказать, что заказчика больше нет, он запрашивается снова с выводом на экран сообщения.

Удаление присоединенных сущностных объектов

В отличие от автоматической вставки в базу данных присоединенных ассоциированных зависимых сущностных объектов с помощью DataContext, как было показано в примере выше, когда вставлялся их родительский объект, в случае удаления родительского объекта зависимые объекты автоматически не удаляются. Под зависимыми понимаются сущностные объекты, имеющие внешний ключ. Заметьте, сначало пришлось удалять записи OrderDetails перед записями Orders, а записи Orders — перед записью Customers.

Поэтому, например, если вы попытаетесь удалить заказ в базе данных Northwind, то его детали не будут удалены автоматически. Попытка удаления заказа приведет к нарушению ограничения внешнего ключа. Перед тем, как удалить сущностный объект, потребуется удалить все присоединенные к нему ассоциированные дочерние объекты.

Удаление отношений

Чтобы удалить отношение между двумя сущностными объектами в LINQ to SQL, ссылке сущностного объекта, указывающей на связанный объект, присваивается значение null. Тем самым удаляется отношение данного сущностного объекта с сущностью этого типа. Однако удаление отношения присваиванием null на самом деле не удаляет самой записи. Помните, что для действительного удаления записи соответствующий ей сущностный объект должен быть удален из соответствующей Таble. Ниже приведен пример удаления отношения:

Удаление отношения между двумя сущностными объектами

// Используйте свою строку подключения Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS; AttachDbFilename=C:\Northwind.mdf; Integrated Security=True"); // Получить заказ для удаления отношения. Order order = (from o in db.Orders where o.OrderID == 11043 select o) .Single(); // Сохранить исходного заказчика, чтобы можно было восстановить обратно. Customer с = order.Customer; string s = ("Заказы перед удалением отношения:"); foreach (Order ord in с.Orders) s += "\nOrderID = " + ord.OrderID; // Удалить отношение с заказчиком order.Customer = null; db.SubmitChanges(); s += "\n\nЗаказы после удаления отношения: \n"; foreach (Order ord in с.Orders) s += "\nOrderID imgcontent">

Как видите, после удаления отношения между заказчиком и заказом с OrderID, равным 11043, он исчез из коллекции заказов данного заказчика.

Удаление записей из базы данных

Чтобы удалить запись из базы данных, необходимо просто передать сущностный объект, представляющий эту запись, в качестве аргумента методу DeleteObject. Пример использования этого метода приведен в примере ниже:

// Создание ObjectContext NorthwindEntities context = new NorthwindEntities(); // Получить детали заказа 10248 IQueryable ods = from o in context.Order_Details where o.OrderID == 10248 select o; // Вывести результаты Console.WriteLine("Перед удалением: "); foreach (Order_Detail od in ods) < Console.WriteLine("Детали заказа , , ", od.ProductID, od.UnitPrice, od.Quantity); > // Удалить детали первого заказа context.DeleteObject(ods.First()); // Сохранить изменения context.SaveChanges(); // Вывести результаты запроса Console.WriteLine("\nПосле удаления: "); foreach (Order_Detail od in ods) Console.WriteLine("Детали заказа , , ", od.ProductID, od.UnitPrice, od.Quantity);

В этом коде запрашиваются все сущностные объекты Order_Detail со значением OrderID, равным 10248. Затем с помощью метода First первый из них выбирается и передается в качестве аргумента методу ObjectContext.DeleteObject. Для сохранения изменений вызывается метод ObjectContext.SaveChanges, который отправляет команду удаления в базу данных.

Класс EntitySet также имеет метод DeleteObject, а это значит, что можно получить тот же эффект, что и в предыдущем примере, с использованием сущностного объекта, представляющего таблицу, из которой нужно удалить запись:

. // Удалить детали первого заказа context.Order_Details.DeleteObject(ods.First()); . 

В этом коде выполняется тот же запрос, что и в предыдущем примере, но здесь используется метод EntitySet.DeleteObject. Компиляция и запуск кода этих примеров даст одинаковый результат:

Удаление записи с использованием сущностного класса

Удаление связанных объектов

Удаление сущностного объекта в Entity Framework приводит к удалению автоматически связанных с ним объектом. При удалении сущностного объекта, имеющего связанные с ним объекты, следует проявлять осторожность: в зависимости от схемы базы данных, могут либо появиться "висячие" данные (данные, внешний ключ которых ссылается на более несуществующий первичный ключ), либо произойти исключение о нарушении ограничения схемы.

Ниже демонстрируется то, что случится, когда объект удаляется без обработки связанных с ним объектов. В данном случае предпринимается попытка удалить сущностный объект Order:

// Создание ObjectContext NorthwindEntities context = new NorthwindEntities(); // Запросить первый заказ для LAZYK Order firstOrder = context.Orders .Where(o => o.CustomerID == "LAZYK") .Select(o => o) .First(); // Удалить заказ context.DeleteObject(firstOrder); // Сохранить изменения context.SaveChanges();

Компиляция и запуск этого кода приведет к генерации следующего исключения:

Unhandled Exception: System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK Order Details_Orders". The conflict occurred in database "Northwind", table "dbo.Order Details", column 'OrderID'. The statement has been terminated. Необработанное Исключение: System.Data.UpdateException: Во время обновления записей возникла ошибка. Для получения сведений см. внутреннее исключение. ---> System.Data.SqlClient.SqlException: Оператор DELETE конфликтует со ССЫЛОЧНЫМ ограничением "FK_Order Details_Orders". Конфликт произошел в базе данных "Northwind", таблица "dbo.Order Details", столбец 'OrderID'. Оператор принудительно завершен. 

Что же произошло? Было нарушено ограничение схемы базы данных. Исключение сообщает о том, что в таблице Order Details имеется ограничение по имени FK Order Details_Orders. Опция Enforce Foreign Key Constraint (Навязывать ограничение внешнего ключа) установлена в Yes (Да), а это означает, что удалить Order не получится, пока есть связанные с ним записи в таблице Order Details.

Существуют два подхода к безопасному удалению связанных объектов. Это можно сделать вручную или воспользоваться каскадным удалением в базе данных, и тогда сущностная модель данных обработает их автоматически. Мы предпочитаем автоматический подход, но поскольку бывают случаи, когда невозможно модифицировать схему базы данных, приходится применять ручной подход. Ниже продемонстрированы оба метода.

Ручное удаление связанных объектов

Возможно, простейший способ удаления связанных объектов состоит в простой передаче каждого из них методу ObjectContext.DeleteObject. При этом необходимо соблюдать осторожность. Во-первых, следует убедиться, что порядок их удаления не нарушает ограничений схемы. Например, если требуется удалить Order, то сначала следует удалить связанные объекты Order_Detail, а только потом удалять Order. Если сделать наоборот, получится исключение вроде того, что видели ранее.

Во-вторых, нужно убедиться, что они удалены все — что-то оставлять нельзя, иначе будет получено исключение или появится несколько строк "висячих" данных.

Наконец, необходимо убедиться, что связанные объекты не имеют других зависимых объектов. Сложные базы данных могут иметь множество отношений внешнего ключа, и придется разобрать их все досконально, чтобы получить возможность корректно удалить граф объектов.

Таким образом, чтобы вручную удалить Order, сначала понадобится удалить все связанные с ним объекты Order_Detail. Ниже показано, как это делается:

// Создание ObjectContext NorthwindEntities context = new NorthwindEntities(); // Запросить первый заказ для LAZYK Order firstOrder = context.Orders .Where(o => o.OrderID== 10248) .Select(o => o) .First(); // Удалить объекты Order_Detail этого объекта foreach (Order_Detail od in firstOrder.Order_Details.ToArray()) < Console.WriteLine("Deleting order detail , , , ", od.OrderID, od.ProductID, od.UnitPrice, od.Quantity); context.DeleteObject(od); > // Удалить заказ context.DeleteObject(firstOrder); // Сохранить изменения context.SaveChanges();

В этом примере запрашивается объект Order со значением свойства OrderID, равным 10248. Он выбран именно потому, что в базе данных с ним связано более одного Order_Detail. Перед удалением собственно Order объекты Order Detail перечисляются и удаляются один за другим.

Обратите внимание на вызов метода ToArray на Order_Details EntityCollection и перечисление результата. Если этого не сделать, пришлось бы удалять объекты из обрабатываемого перечисления и тогда после удаления первого объекта Order_Details возникло бы исключение.

Каскадное удаление связанных объектов

Другой способ обработки связанных объектов предусматривает применение каскадного удаления. Каскадное удаление означает, что в случае удаления из базы данных записи, такой как Order, связанные записи, имеющие с ней отношение внешнего ключа, вроде записей из таблицы Order Details, также будут удалены автоматически.

Для каждого отношения внешнего ключа, которое необходимо изменить, должно быть включено каскадное удаление в базе данных и в сущностной модели данных.

Подробности использования каскадного удаления ищите на форуме MSDN.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *