【问题标题】:sqladaptor insert into different tablessqladaptor 插入不同的表
【发布时间】:2016-04-01 22:38:22
【问题描述】:

我想创建一个函数,它可以同时更新我的​​旧表并记录更改之前的数据。 (就像一个日志表。)我创建了一个表来检索我搜索的表和另一个存储更改之前的表。这两个表在列上有一些差异。 DS 是检索数据集,ADS 是只插入的日志数据集

private void Update_Button_Click(object sender, EventArgs e)
    {
        try
        {
            //Update table1
            SqlCmb = new SqlCommandBuilder(SqlAd);
            SqlAd.Update(DS, "dataset1");

                //INSERT table1_log
                DataSet ds = new DataSet();
                ds = ADS;
                ds.Tables[0].Columns.Add("USER_NAME", typeof(string));
                ds.Tables[0].Columns.Add("UNIQ", typeof(String));
            foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    dr["USER_NAME"] = Form1.USER_NAME.Text;
                    dr["ALTER_TIME"] = DateTime.Now;
                }
                SqlDataAdapter SqlAdI = new SqlDataAdapter("SELECT * FROM table1_log where 0 = 1", SqlCon);
                SqlCommandBuilder SqlCmbI = new SqlCommandBuilder(SqlAdI);

                SqlCom= new SqlCommand("INSERT INTO table1_log FROM" + ds.Tables[0], SqlCon) ;
                SqlAdI.InsertCommand = SqlCom;
                SqlAdI.Update(ADS, "table1");


            MessageBox.Show("Info updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

我的问题是它无法插入日志表,但更新到 table1 工作正常。 Uniq 是 PK 并由 sql server 自动生成。错误消息是“并发冲突:更新命令影响了预期的 1 条记录中的 0 条。”

谢谢!

【问题讨论】:

  • 你有使用库的能力吗?如果可以的话,看看 dapper 会让你的生活更轻松
  • 嗨 Konkked,你是什么意思?我可以成功更新到表1但不能插入table_log,所以我认为我有能力使用库。
  • @ericka08:您应该查找触发器。这是在更新另一个表时更新一个表的好方法。您可以将触发器添加到表中,以便它会自动更新您的日志表,而无需使用 SQLCommand 并跟踪代码中所做的更改。我们在工作中一直使用这些来以您正在寻找的相同方式更新日志表。我会尝试找到一个链接
  • @JSON 我正在使用 datagridview,我希望我能坚持下去。它使我的代码非常简单。我会看一下,但这将是我的最后一次尝试。谢谢!

标签: c# datagridview sqldataadapter


【解决方案1】:

如 cmets 中所述,您应该创建一个触发器。触发器不会使您的代码复杂化或使您远离使用 DataGridView,它实际上会使您的代码更简单(IMO,您的代码有几个问题,但我会尝试解决这个问题)。触发器是在数据库级别实现的,而不是在您的 C# 代码中。它将消除在代码中显式编写插入语句的需要,如果您曾经编写多个需要记录的语句(例如插入、更新、删除),这将特别有用。您只需编写一次 insert to log 语句,它就会一直运行。

我想知道您的插入问题是否是因为您的日志表的主键与 table1 的主键匹配。在这种情况下,一条记录可能会被多次更新并尝试使用同一个键,该键已经存在于日志中。最简单的解决方法是向日志表添加一个新的主键,该主键只是一个在每次插入时递增的顺序 ID。我建议还添加另一列以指示执行的操作类型(即插入、更新、删除)。这是一个很好的答案,它解释了如何检测操作:Trigger in SQL Server - Get the type of Transaction done for Audit Table

更重要的一点是,您正在通过连接字符串来构建插入语句。我不完全确定 ds.Tables[0] 的值来自哪里,但是你将它直接连接到一个插入语句中,如果这是用户输入,这会使你面临 SQL 注入攻击的风险。攻击者可以相当容易地窃取或删除数据。即使在其他地方进行了检查,我仍然建议使用 SqlParameter,这样任何看到您的代码的人都可以清楚地知道您正在防范这些危险。

在sql中创建触发器的伪代码:

CREATE TRIGGER TR_TABLE1_AUDIT
ON table1
FOR INSERT, UPDATE, DELETE
AS
  -- your insert statement here
  INSERT INTO table1_log ...

编辑:添加有关防止 SQL 注入攻击的信息。 无论您允许用户输入多少字段,这都与 SQL 注入攻击无关。为了防止这种情况,您不能将用户输入直接连接到 SQL 语句中。你需要做这样的事情:

// Set the command text (you could pass this in the constructor)
sqlcom.CommandText = "select * from table1 where loc = @loc ";
// Create SqlParameter
// Note that I don't know your actual SqlDbType, replace it with whatever it should be
SqlParameter param = new SqlParameter("@loc", SqlDbType.Varchar) { Value = loc };
// Add to SqlCommand parameter collection
sqlcom.Parameters.Add(param);
// Add the command to your SqlDataAdapter if you are using one

这称为参数化。参数化用户输入的任何内容将保护您免受 SQL 注入。您可以在 Add 语句中内联 SqlParameter 以缩短内容。

【讨论】:

  • 嗨,布兰登,我现在正在创建一个触发器。对于主键问题,我创建了一个变量“UNIQ”来处理,这与原来的不同。对于sql注入问题,我只允许用户在sql中输入一个变量。看起来像这样:select * from table1 where loc="+loc+" 不确定这是否可以防止 sql 注入,因为我对此很陌生。
  • 我对您对主键的声明感到有些困惑。主键是唯一标识符,与表中的每一行始终具有 1 比 1 的比率。如果您声称表的主键不是 1 比 1,那么根据定义它不是主键。
  • @erickao08 我刚刚编辑了我的回复,以提供有关防止 SQL 注入的更多信息
  • @JSON 这正是我的观点,据我了解,发帖人希望使用相同的 UID 作为主键,这不起作用,因为在日志/存档表中,同一个对象可以有多个编辑记录。所以应该添加一个额外的列,称为 log_id,它充当主键。然后将 table1 的 uid 作为外键添加到日志表中,以便您查看记录的更改历史记录。
  • @JSON 和 Brandon UNIQ 是我的 log_id,它是 1 比 1。我创建了 2 个数据集来存储我的表;但是它们是不同的。 ADS 是以 UNIQ 作为 PK 的日志表。 DS有它的原始PK,所以我不会插入任何东西。日志表外键将是表 1 的 PK。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多