【问题标题】:Commit is not working while saving a record in database在数据库中保存记录时提交不起作用
【发布时间】:2023-03-10 08:39:01
【问题描述】:

我在向数据库中插入简单记录时遇到了困难。保存时我没有收到任何错误。此外,如果我在程序运行时尝试检索它,我可以验证它是否已插入。但是一旦我关闭程序并刷新数据库,它就不会出现在数据库中。我知道这是一个提交问题,但不确定我到底错过了什么。

private void saveEmpBtn_Click(object sender, EventArgs e)
{
    string aSQL = "INSERT INTO Employee(Id, Name, Type, Email, UTAId, Dept) VALUES (@Id, @Name, @Type, @Email, @UTAId, @Dept) ";

    using (conn = new SqlConnection(connectionString))
    {
        conn.Open();

        using (var tx = conn.BeginTransaction())
        using (SqlCommand command = new SqlCommand(aSQL, conn))
        {
            command.Connection = conn;
            command.Transaction = tx;

            command.Parameters.AddWithValue("@Id",  3);
            command.Parameters.AddWithValue("@Type", empTypCmbBx.SelectedItem.ToString());
            command.Parameters.AddWithValue("@Name", nmTxtBx.Text);
            command.Parameters.AddWithValue("@UTAId", utaIdTxtBx.Text);
            command.Parameters.AddWithValue("@Email", emailTxtBx.Text);
            command.Parameters.AddWithValue("@Dept", deptTxtBx.Text);

            try
            {
                command.ExecuteNonQuery();
                tx.Commit();
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        MessageBox.Show("Employee Saved Successfully");
    }
}

包括几张表的数据库脚本图像。架构定义和 ID 属性也是如此。一些问题:我遵循的示例有employee.mdf,并且只有一张桌子。在我的例子中,数据库名是RoomAllocationSystemDatabase,表名是Employee。我是否必须将模式包含为点符号才能访问插入语句中的表?我试过这个。当我这样做时,它说无效对象。不确定我是否需要在其他地方包含数据库名称。

CREATE TABLE [dbo].[Employee] 
(
    [Id]       INT          NOT NULL,
    [Name]     VARCHAR (50) NULL,
    [Type]     VARCHAR (50) NULL,
    [Email]    VARCHAR (50) NOT NULL,
    [UTAId]    VARCHAR (50) NULL,
    [Dept]     VARCHAR (50) NULL,
    [Password] VARCHAR (50) NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

加载表单时的连接字符串逻辑

connectionString = ConfigurationManager.ConnectionStrings["RoomAllocationSystem.Properties.Settings.RoomAllocationSystemDatabaseConnectionString"].ConnectionString;

app.config中的连接字符串:

<connectionStrings>
    <add name="RoomAllocationSystem.Properties.Settings.RoomAllocationSystemDatabaseConnectionString"
         connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\RoomAllocationSystemDatabase.mdf;Integrated Security=True"
         providerName="System.Data.SqlClient" />
</connectionStrings>

【问题讨论】:

  • 不知道为什么它没有提交,但你为什么要插入一个 ID?您应该使用主键。也许这就是表有一个主键列 (Id) 并且您尝试插入一条没有 IDENTITY_INSERT ON/Off 的记录的问题
  • @JeremyThompson 感谢您的建议。尝试了几件事,但到目前为止没有成功。如果我删除 Id 字段并将其他字段指定为插入的一部分,我会得到“Id 不能为 Null”。如果我在值之前和值之后删除除 Id 之外的所有字段的特定字段,我会得到“列名或提供的值的数量与表定义不匹配”。不确定如何在不指定 ID 的情况下插入。另外,不确定我的表定义是否正确。 MS Access 数据库中的 Id 会自动插入带序列的主键吗?
  • 如果要使用事务,应该是SqlCommand command = new SqlCommand(aSQL, conn, tx)。见msdn.microsoft.com/en-au/library/352y4sff(v=vs.110).aspx
  • @potatopeelings 添加了这个,但仍然没有运气。 :(
  • 主键属性是在您通过 DDL 创建主键时建立的。数据库结构也是如此。如果您右键单击 SSMS 中的表格并选择为其创建脚本,则所有内容都会写出 作为文本,可以在此处复制和粘贴,并且 我们可以复制/粘贴以创建相同的表。您甚至可以在比创建和上传您已发布的一个图像所花费的时间更短的时间内完成此操作。仅当没有其他选项可用于证明问题时才应使用图像。

标签: c# sql-server


【解决方案1】:

这就是答案。它发布在here。 这是一个常见的场景。您有一个使用替换字符串|DataDirectory| 的连接字符串。在桌面应用程序中,此目录通常与您的程序运行所在的目录相同。在 Visual Studio 中,您的程序在 BIN\DEBUG(或 x86 变体)目录中运行。因此,Visual Studio 将您的 MDF 文件从项目目录复制到 BIN\DEBUG 文件夹。您将记录添加到此副本,而不是项目文件夹中的副本。但是,服务器资源管理器窗口有一个特定于项目文件夹数据库的连接,当然它仍然是空的。

您可以向服务器资源管理器添加另一个指向文件夹 BIN\DEBUG 的连接,并检查您的数据库是否已更新。

更复杂的是,有一个属性复制到与 MDF 文件关联的输出目录。如果此属性设置为每次使用 Visual Studio 启动新的调试会话时始终复制,则文件会再次从项目文件夹复制到输出目录 (BIN\DEBUG),并用新的空文件覆盖已经存在的副本。所以第一次运行成功,第二次失败。而您观察到的症状就是这种情况的明显迹象。

只需将属性复制到输出目录更改为复制,如果更新,代码运行良好。 (现在还为时过早,但请记住将您的查询更改为参数化查询。按原样,您可以像 O'Malley 一样在 txtName 文本框中插入单引号来破坏您的代码,更不用说 Sql Injection hack)

【讨论】:

    【解决方案2】:

    尝试在花括号内使用事务语句

                using (var tx = conn.BeginTransaction())
                {
                    using (SqlCommand command = new SqlCommand(aSQL, conn))
                    {
                        command.Connection = conn;
                        command.Transaction = tx;
                        command.Parameters.AddWithValue("@Id", 3);
    
                        try
                        {
                            command.ExecuteNonQuery();
                            tx.Commit();
                            conn.Close();
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
    

    【讨论】:

      猜你喜欢
      • 2015-11-30
      • 2021-07-31
      • 1970-01-01
      • 2016-12-14
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      相关资源
      最近更新 更多