【问题标题】:Stored Procedure to Cascade Delete Customer?级联删除客户的存储过程?
【发布时间】:2012-12-31 16:23:03
【问题描述】:

我有一个项目来实现从Northwind -> Customers 插入、更新和删除Customers 的表单。我设法在每次操作后进行插入、更新和刷新,但删除不起作用并引发 FK 异常。我需要级联删除,但我不知道如何..

我的表单如下所示:

和我的删除程序(到目前为止,没有级联):

CREATE Procedure [dbo].[DeleteCustomer]
(
    @Original_CustomerID nchar(5)
)
AS
  SET NOCOUNT OFF; 

  DELETE FROM [dbo].[Customers]
  WHERE 
  (
    (
        [CustomerID] = @Original_CustomerID
    )
)

在某些情况下有效,但在其他情况下我收到错误:

DELETE 语句与 REFERENCE 约束“FK_Orders_Customers”冲突。冲突发生在数据库“Northwind”中, 表“dbo.Orders”,列“客户 ID”。该声明已 终止。

任何人都可以通过在删除时添加级联来帮助我完成这个项目吗?

这是 Northwind Traders 数据库,Customer 表。

【问题讨论】:

  • 先从dbo.Orders删除CustomerId再从dbo.Customers删除
  • 我做了:` 从 [dbo] 删除。[订单] WHERE ( ( [CustomerID] = @Original_CustomerID ) ) 从 [dbo].[Customers] 删除 ( ( [CustomerID] = @Original_CustomerID ) ) ` 但仍然是同样的错误。如何添加级联?您能否编写此程序的代码..?

标签: c# sql wpf cascade


【解决方案1】:

处理此问题的一种简单方法是在 SQL 企业管理器(或您选择的 ISQLW 解释器)中删除并读取约束作为级联删除约束:

USE Northwind
GO
ALTER TABLE Orders
  DROP CONSTRAINT
    FK_Orders_Customers
GO
ALTER TABLE Orders
  ADD 
    CONSTRAINT FK_Orders_Customers FOREIGN KEY
    (
        CustomerID
     ) REFERENCES Customers
        CustomerID
     ) ON CASCADE DELETE
GO

如果你想有一个严格的存储过程解决方案,你可以使用你原来的存储过程的这个版本:

CREATE Procedure [dbo].[DeleteCustomer] (
    @Original_CustomerID nchar(5)
)
AS

SET NOCOUNT OFF; 

  DELETE 
    FROM [dbo].[Orders]
   WHERE [CustomerID] = @Original_CustomerID

  DELETE 
    FROM [dbo].[Customers]
   WHERE [CustomerID] = @Original_CustomerID

【讨论】:

  • 我在哪里运行这段代码?我将其保存为存储过程还是?
  • 您将使用与创建存储过程相同的工具。
  • 太好了,最后一件事。在准备最终项目时如何以及在哪里保存您发布的代码?在我的 StoredProcedures 文件夹中将其保存为查询或存储过程?
  • 它怎么知道我运行了这段代码?难道我不必以某种方式将它附加到我在 WPF 中的项目中,所以每次按删除时它都会运行..?
  • 此 SQL 所做的是改变 Orders 表与 Customers 表的关系性质,这样每当删除 Customer 时,数据库会自动删除该 Customer 的所有 Orders。没有额外的工作要做。由于这是一次性操作,因此可能会包含在您为数据库创建的原始模式中。
【解决方案2】:

我将您的代码放在哪里?我是否保存/运行为存储过程? 它仍然抛出异常..:/ 我的删除:

private void buttonDelete_Click(object sender, RoutedEventArgs e)
{            
    SqlConnection cn = new SqlConnection(@"Integrated Security=SSPI;Initial Catalog=Northwind;Data Source=(local)");
    SqlCommand cmd = new SqlCommand("DeleteCustomer", cn);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue("@Original_CustomerID", textBox_CompanyID.Text);

    cn.Open();
    cmd.ExecuteNonQuery();
    cn.Close();

    lbxCustomers.Items.Clear();
    this.init();
}

我的DeleteCustomer 程序:

CREATE Procedure [dbo].[DeleteCustomer]
(
    @Original_CustomerID nchar(5)
)
AS

SET NOCOUNT OFF; 

DELETE FROM [dbo].[Customers]
WHERE 
(
    (
        [CustomerID] = @Original_CustomerID
    )
)

我有你的代码,但不知道如何将它添加到我的项目中以使其工作。因此,当我重新启动应用程序或切换计算机时,它仍然可以工作。请帮忙..我认为这是新错误。似乎连接了 3 个表:

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.

【讨论】:

  • 您需要将您的 DeleteCustomer 存储过程更改为提供的主管技术(或适用于您的情况的类似程序)。这样做的方法是发出 DROP PROCEDURE 命令,例如 DROP PROCEDURE dbo.DeleteCustomer,然后运行 ​​CREATE PROCEDURE 命令。您可以通过在 SQL Management Studio 中突出显示文本并按 F5 来实现。只有您突出显示的文本才会运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
相关资源
最近更新 更多