使用 SqlDataAdapter 防止仅更新某些列

Posted

技术标签:

【中文标题】使用 SqlDataAdapter 防止仅更新某些列【英文标题】:Prevent update of only some columns using SqlDataAdapter 【发布时间】:2018-05-23 07:55:01 【问题描述】:

我需要的是防止某些列的更新。我需要这些字段,但我必须确保即使出现错误也不会更新这些字段。 那么是否有一个属性被设置为使这些字段仅处于一种只读状态? 为了更清楚一点,我的查询结果由四个字段组成:

跟踪号码, 跟踪状态, 运输代码, 发货日期

前两个将被更新,但后两个不会被修改,我想确保即使出现错误也无法更改它们。

有办法吗?

public static Dictionary<string, object> GetTrackingShippingInfo(string carrierCode, DateTime date) 

SqlCommand cmd = new SqlCommand(String.Format(@"
            (   SELECT  salesShipment.[Shipping Agent Ref_]             as trackingNumber,
                        salesShipment.[Tracking Status]                 as trackingStatus,
                        salesShipment.[No_]                             as shippingCode,
                        salesShipment.[Posting Date]                    as shippingDate

                FROM    0.[1$Sales Shipment Header] as salesShipment

                WHERE   salesShipment.[Shipping Agent Code] = @carrierCode AND
                        salesShipment.[Posting Date] = @date AND
                        salesShipment.[Export to Carrier] > 0 AND
                        salesShipment.[Location Code] = @departureWarehouse
            )

            UNION ALL

            (   SELECT  transferShipment.[Shipping Agent Ref_]          as trackingNumber,
                        transferShipment.[Tracking Status]              as trackingStatus,
                        transferShipment.[No_]                          as shippingCode,
                        transferShipment.[Posting Date]                 as shippingDate

                FROM    0.[1$Transfer Shipment Header] as transferShipment

                WHERE   transferShipment.[Shipping Agent Code] = @carrierCode AND 
                        transferShipment.[Tipo Soggetto 1] = 1 AND 
                        transferShipment.[Posting Date] = @date AND 
                        transferShipment.[Export to Carrier] > 0 AND 
                        transferShipment.[Transfer-from Code] = @departureWarehouse
            )", navDbPrefix, navCompany));

        cmd.CommandType = CommandType.Text;
        cmd.Parameters.AddWithValue("@carrierCode", carrierCode);
        cmd.Parameters.AddWithValue("@date", String.Format("0:yyyy-MM-dd", date));
        cmd.Parameters.AddWithValue("@departureWarehouse", "MP");

        Dictionary<string, object> selectResult = DbHelper.ExecuteSelectForUpdateQuery(cmd);
        return selectResult;
    


    public static void UpdateTrackingShippingInfo(DataTable dataTable, SqlDataAdapter adapter) 
        try
        
            DbHelper.BeginTransaction();
            DbHelper.ExecuteUpdate(dataTable, adapter);
            DbHelper.CommmitTransaction();
        
        catch (Exception e)
        
            DbHelper.RollbackTransaction();
            log.Error("Failed update query. Rollback executed");
            log.Error(e.ToString());
        
    

public static void ExecuteUpdate(DataTable data, SqlDataAdapter adapter)
    
        SqlCommandBuilder cmdBuilder;
        cmdBuilder = new SqlCommandBuilder(adapter);
        log.Debug(cmdBuilder.GetUpdateCommand().CommandText);
        adapter.Update(data);
    

【问题讨论】:

你能给我们看看你的代码,以便我们看看你是怎么做的 如何创建命令文本?只是不要将它们添加到命令文本中 在 SqlDataAdapter 你会发现 SqlDataAdapter.UpdateCommand 包含更新语句.. 只包括你需要更新的内容 @SimonPrice 抱歉,我刚刚更新了帖子。 @HesamFaridmehr 我没有修改更新命令,我只是使用了具有新值的相同数据表和来自选择查询的相同适配器 【参考方案1】:

这里是 Microsoft 示例,用于在 SQLDataAdapter 中为所有 CRUD 操作设置更新参数:

public static SqlDataAdapter CreateCustomerAdapter(
    SqlConnection connection)

    SqlDataAdapter adapter = new SqlDataAdapter();

    // Create the SelectCommand.
    SqlCommand command = new SqlCommand("SELECT * FROM Customers " +
        "WHERE Country = @Country AND City = @City", connection);

    // Add the parameters for the SelectCommand.
    command.Parameters.Add("@Country", SqlDbType.NVarChar, 15);
    command.Parameters.Add("@City", SqlDbType.NVarChar, 15);

    adapter.SelectCommand = command;

    // Create the InsertCommand.
    command = new SqlCommand(
        "INSERT INTO Customers (CustomerID, CompanyName) " +
        "VALUES (@CustomerID, @CompanyName)", connection);

    // Add the parameters for the InsertCommand.
    command.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    command.Parameters.Add("@CompanyName", SqlDbType.NVarChar, 40, "CompanyName");

    adapter.InsertCommand = command;

    // Create the UpdateCommand.
    command = new SqlCommand(
        "UPDATE Customers SET CustomerID = @CustomerID, CompanyName = @CompanyName " +
        "WHERE CustomerID = @oldCustomerID", connection);

    // Add the parameters for the UpdateCommand.
    command.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    command.Parameters.Add("@CompanyName", SqlDbType.NVarChar, 40, "CompanyName");
    SqlParameter parameter = command.Parameters.Add(
        "@oldCustomerID", SqlDbType.NChar, 5, "CustomerID");
    parameter.SourceVersion = DataRowVersion.Original;

    adapter.UpdateCommand = command;

    // Create the DeleteCommand.
    command = new SqlCommand(
        "DELETE FROM Customers WHERE CustomerID = @CustomerID", connection);

    // Add the parameters for the DeleteCommand.
    parameter = command.Parameters.Add(
        "@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    parameter.SourceVersion = DataRowVersion.Original;

    adapter.DeleteCommand = command;

    return adapter;

因此,对于更新,您只需要使用所需参数应用您需要的列。

【讨论】:

以上是关于使用 SqlDataAdapter 防止仅更新某些列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQLDataAdapter 中使用更新语句

使用 SqlDataAdapter 更新 SQL Server 数据库

使用 SQL 数据适配器更新和插入行不会更新(仅插入)

在 C# 中使用 SqlDataAdapter 更新数据库

DataGridView 和 SqlDataAdapter 未正确更新

使用 ADO.NET SqlDataAdapter 更新单个记录