从另一个删除时更新一个SQL表

时间:2014-07-07 20:37:49

标签: c# sql sql-server

我有两个SQL表(SalesCategory和ProductLine),每个表有两列。产品类别不能同时与销售类别和产品系列相关联。但是,用户可以更改,例如,产品类别ABC与销售类别123而不是产品线456相关联。当发生类似这样的情况时,我想从ProductLine SQL表中删除产品类别ABC的记录并更新SalesCategory,其ID为产品类别ABC。但我不知道如何在不创建另一个单独的DELETE函数的情况下执行此操作,并在相关SQL表的save函数内调用它们。我觉得我投入了太多与这两个SQL表相关的函数....

作为重要的附注,产品类别不能与多个产品系列或多个销售类别相关联。

有没有更好的方法来设置代码,所以我没有一堆与两个SQL数据库表相关联的函数?或者这是最好的方式吗?

这是我现在的代码:

    //Get current Product Line and Sales Cateogry data for the current Category.
    //These two functions are called in the Page_Load    
    protected string getProductLine()
    {
        string retVal = "";
        try
        {
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand("SELECT ProductLine FROM ProductLine WHERE uidCategory = @CategoryID", cn);
                cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                cmd.CommandType = CommandType.Text;
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        if (reader["ProductLine"].ToString() != "")
                        {
                            productLineTxt.Text = reader["ProductLine"].ToString();
                            retVal = productLineTxt.Text;
                        }
                        else
                        {
                            retVal = "";
                        }
                    }
                }
                cn.Close();
            }
        }
        catch (Exception ex)
        {
            //
        }
        return retVal;
    }

    protected string getSalesCategory()
    {
            string retVal = "";
            try
            {
                using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
                {
                    cn.Open();
                    SqlCommand cmd = new SqlCommand("SELECT SalesCat FROM SalesCategory WHERE uidCat = @CategoryID", cn);
                    cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                    cmd.CommandType = CommandType.Text;
                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            if (reader["SalesCat"].ToString() != "")
                            {
                                salesCatTxt.Text = reader["SalesCat"].ToString();
                                retVal = salesCatTxt.Text;
                            }
                            else
                            {
                                retVal = "";
                            }
                        }
                    }
                    cn.Close();
                }
            }
            catch (Exception x)
            {
                //
            }
        return retVal;
    }

    //These two functions are called in the saveSalesCategory() and saveProductLine() functions respectively. They determine if those save functions should perform an UPDATE or INSERT. This is meant to prevent a Product Category from having association with more than one Product Line or Sales Category
    protected bool salesCatExists()
    {
        bool retVal = true;

        try
        {
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = cn;
                cmd.CommandText = "SELECT COUNT(*) AS 'Exists' FROM SalesCategory WHERE uidCat = @CategoryID";
                cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                cmd.Parameters.Add(new SqlParameter("@SalesCategory", salesCatTxt.Text));
                cmd.CommandType = CommandType.Text;
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        if (Convert.ToInt32(reader["Exists"]) == 0)
                        {

                            retVal = false;
                        }
                        else
                        {
                            retVal = true;
                        }
                    }
                }
                cn.Close();
            }
        }
        catch (Exception x)
        {
            //
        }

        return retVal;
    }

    protected bool productLineExists()
    {
        bool retVal = true;

        try
        {
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = cn;
                cmd.CommandText = "SELECT COUNT(*) AS 'Exists' FROM ProductLine WHERE uidCategory = @CategoryID";
                cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                cmd.Parameters.Add(new SqlParameter("@ProductLine", productLineTxt.Text));
                cmd.CommandType = CommandType.Text;
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        if (Convert.ToInt32(reader["Exists"]) == 0)
                        {

                            retVal = false;
                        }
                        else
                        {
                            retVal = true;
                        }
                    }
                }
                cn.Close();
            }
        }
        catch (Exception x)
        {
           //
        }

        return retVal;
    }

    //Save new or update old Product Line and Sales Category data for the current Category
    protected void saveProductLine()
    {
        try
        {
            string update1 = "UPDATE ProductLine SET ProductLine = @ProductLine WHERE uidCategory = @CategoryID";
            string update2 = "UPDATE ProductLine SET ProductLine = '' AND uidCategory = '' WHERE uidCategory = @CategoryID";
            string insert = "INSERT INTO ProductLine (uidCategory, ProductLine) VALUES(@CategoryID, @ProductLine)";
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = cn;
                cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                cmd.Parameters.Add(new SqlParameter("@ProductLine", productLineTxt.Text));
                cmd.CommandType = CommandType.Text;

                if (getProductLine() == "")
                {
                    cmd.CommandText = insert;
                }
                else
                {
                    productLineTxt.Text = getProductLine();
                    cmd.CommandText = update;
                }
                cmd.ExecuteNonQuery();
                cn.Close();
            }
        }
        catch (Exception ex)
        {
            //
        }
    }

    protected void saveSalesCategory()
    {
        string update = "UPDATE SalesCategory SET SalesCat = @SalesCategory WHERE uidCat = @CategoryID";
        string insert = "INSERT INTO SalesCategory (uidCat, SalesCat) VALUES(@CategoryID, @SalesCategory)";
        try
        {
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@CategoryID", _CategoryId));
                cmd.Parameters.Add(new SqlParameter("@SalesCategory", salesCatTxt.Text));
                cmd.Connection = cn;
                cmd.CommandType = CommandType.Text;

                if (salesCatExists() == false)
                {
                    cmd.CommandText = insert;
                }
                else
                {

                    cmd.CommandText = update;
                }

                cmd.ExecuteNonQuery();
                cn.Close();
            }
        }
        catch (Exception x)
        {
            //
        }
    }

5 个答案:

答案 0 :(得分:1)

您可以查看SQL MERGE语句。我不确定我是否完全理解您希望做的事情足以提供一个代码示例,说明它可能对您有何帮助,但听起来它可能会像您的目标一样。

例如,它允许您在给定一个键或一组键的情况下检查一个表(无论是实际表还是表值变量),然后在记录匹配时或在它们发生时执行操作不配。

我想我可以举一个简单的例子:

此查询可以处理saveSalesCategory方法中的大部分逻辑:

MERGE SalesCategory AS T
USING (VALUES ((@CategoryID, @SalesCategory)) AS S (uidCat, SalesCat)
ON (T.uidCat = S.uidCat)
WHEN MATCHED THEN
    UPDATE SET SalesCat = S.SalesCat
WHEN NOT MATCHED THEN
    INSERT (uidCat, SalesCat) VALUES (S.uidCat, S.SalesCat)

正如您所注意到的,它会检查是否存在任何记录,然后相应地插入或更新。这样就无需运行salesCatExists()并使用多个TSQL查询。

我认识到这并没有回答你的问题(我认为?)但是我希望它至少可以引导你朝着正确的方向前进,因为我仍然不太确定你到底在想什么对

答案 1 :(得分:0)

您无法在一个命令中更新一个表并删除另一个表。似乎数据结构是你在这里最激烈的。如果您的ProductCategory表有一个ReferenceType列,这将非常简单。您可以在一次传递中更新ReferenceType和外键值。通过它们将这些组合在一起,您也将面临参考完整性的挑战,因为ProductCategory中的值对于一个或另一个表来说是异类,具体取决于它的类型。

答案 2 :(得分:0)

您的代码示例看起来似乎没有尝试执行您描述的所有内容。也许你还没有进入删除部分。我认为一些存储过程可能会有所帮助。我将你的几个方法压缩成一个存储过程,你可以为产品线做同样的事情。我只是不确定在哪里放DELETE语句。这是正确的方向吗?如果是这样,我们可以找出删除的位置;)

CREATE PROCEDURE SaveSalesCategory
    @CategoryID INT ,
    @SalesCategory INT
AS 
    BEGIN
        DECLARE @SalesCatCount INT = ( SELECT   COUNT(*) AS 'Exists'
                                       FROM     SalesCategory
                                       WHERE    uidCat = @CategoryID
                                     )

        IF @SalesCatCount = 0 
            BEGIN
                INSERT  INTO SalesCategory
                        ( uidCat, SalesCat )
                VALUES  ( @CategoryID, @SalesCategory )
            END
        ELSE 
            BEGIN
                UPDATE  SalesCategory
                SET     SalesCat = @SalesCategory
                WHERE   uidCat = @CategoryID
            END
    END
GO

答案 3 :(得分:0)

使用OUTPUT子句(MSDN

DELETE ProductLine
WHERE uidCategory = @CategoryID
OUTPUT column1,column2,etc INTO SalesCategory

DELETE SalesCategory
WHERE uidCategory = @CategoryID
OUTPUT column1,column2,etc INTO ProductLine

答案 4 :(得分:0)

您可以在这两个表上设置一个触发器,这样当您插入新记录或更新现有记录时,数据库会查找该类别的其他表并删除该记录。

并非所有参数都在您的示例代码中使用,而且它有点长,所以我不认为这些代码完全符合您的需要,但我认为应该有效。

CREATE TRIGGER dbo.TRG_SalesCategory_RECORD
   ON  SalesCategory 
   AFTER INSERT, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    Delete from ProductLine
    Where CategoryID = (select CategoryID from INSERTED)

END
GO

CREATE TRIGGER dbo.TRG_ProductLine_RECORD
   ON  ProductLine 
   AFTER INSERT, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    Delete from SalesCategory
    Where CategoryID = (select CategoryID from INSERTED)

END
GO