使用asp.net插入数据时如何避免数据库中的不同记录?

Posted

技术标签:

【中文标题】使用asp.net插入数据时如何避免数据库中的不同记录?【英文标题】:How to avoid distinct records from database while inserting data using asp.net? 【发布时间】:2019-09-26 08:32:07 【问题描述】:

我正在构建一个程序,将数据从 Excel 文件导入数据库,或通过写入文本框(通过在 asp.net 中插入)或两者兼而有之,但我想在用户尝试输入时发出警告数据库中已有的相同记录(重复)。

我想通过在 SQL 中编码或设置一些东西来做到这一点,以使用户更容易......

这是我的桌子:

Mov. Date     Value Date    description of the movement     Value in EUROS
---------------------------------------------------------------------------
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 222       200,01
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 223       200,01
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 224       200,02

如果用户输入的记录等于其中任何一个,它会发出警告,用户可以再试一次

这是代码(asp.net C#):

protected void Upload_Click(object sender, EventArgs e)

    string excelPath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
    string filepath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.FileName);
    string filename = Path.GetFileName(filepath);

    FileUpload1.SaveAs(excelPath);

    string ext = Path.GetExtension(filename);

    string strConnection = @"Data Source=PEDRO-PC\SQLEXPRESS;Initial Catalog=costumizado;Persist Security Info=True;User ID=sa;Password=1234";
    string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\"";

    OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);

    OleDbCommand cmd = new OleDbCommand("Select * from [rptListaMovs_4$A15:D75]", excelConnection);

    excelConnection.Open();
    cmd.ExecuteNonQuery();

    OleDbDataReader dReader;
    dReader = cmd.ExecuteReader();

    DataTable dtFail = new DataTable();

    using (SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection))
    
        sqlBulk.ColumnMappings.Add("Mov. Date", "Mov. Date");
        sqlBulk.ColumnMappings.Add("Value Date", "Value Date");
        sqlBulk.ColumnMappings.Add("description of the movement", "description of the movement");
        sqlBulk.ColumnMappings.Add("Value in EUROS", "Value in EUROS");
        sqlBulk.DestinationTableName = "Dados";

        var temp = dtFail.AsEnumerable().Distinct();

        dtFail = temp.CopyToDataTable();

        sqlBulk.WriteToServer(dReader);
    

    excelConnection.Close();

【问题讨论】:

您可以在列上添加唯一性约束,或者选择 * 并在内存中执行验证 @Daniel 不能对列进行唯一约束,否则我不能在不同的记录中拥有两个相等的值。我只是不希望我的程序让用户错误地输入两行......你在说的第二件事是什么? 只是一种预感,但您在 DataTables 集合上调用 Linqs .Distinct。这可能使用引用相等并失败。我认为最简单的方法是将表单数据解析为值类型结构的集合,然后使用 .GroupBy(x => x) .Where(g => g.Count() > 1) 之类的东西来检查是否有任何重复。 如果你做 SQL 你可以简单地做一个合并语句,如果它匹配然后更新,它不匹配插入。您可以做的另一件事是使用 SQL 输出功能获取输入的 id 并将其从列表中删除,然后再继续。 当你得到答案时不要删除你的问题。见meta.***.com/questions/378440/…。 【参考方案1】:

SqlBulkCopy 不是用于条件插入的正确工具。您需要使用合并语句或IF NOT EXISTS (SELECT ....) INSERT ELSE UPDATE

如果您需要提交大量数据,请查看使用表类型Table-Valued Parameter 和存储过程来封装条件插入/更新逻辑。

如果需要在找到匹配项时向用户显示消息,则添加一列以包含行中所有数据的哈希值可能会有所帮助,因此您可以执行查找和消息或过滤掉匹配项。或者如前所述,使用OUTPUT SQL 子句创建要返回的匹配列表。

CREATE TYPE <MyRecord> (
    <add columns to match the table as if it was a CREATE TABLE>
)

将DataTable作为参数绑定到存储过程

...
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "<MyRecord>";
command.ExecuteNonQuery();
...

现有帖子Pass table value parameter中的示例

【讨论】:

但是我不必总是写这个?由于这是针对客户的,因此他将无法为此使用 Sql,我需要为他编程...通过网络应用程序 这就是存储过程的目的。它封装了数据库逻辑,通过代码启动。 Example

以上是关于使用asp.net插入数据时如何避免数据库中的不同记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 c#asp.net 将数据库中的数据插入到表中?

如何使用 jquery asp.net mvc 将多个数据插入到数据库中的 2 个表中

如何遍历 MultiSelectList 发布的值并将每个值插入 ASP.Net MVC 5 中的新数据库行?

如何在asp.net mvc中使用dropdownlist在数据库中插入记录?

ASP.NET 在尝试插入 MS Access DB 时出错

如何通过 ASP.net 网站将新条目插入 Access db 表?