【问题标题】:Creating and retrieving index at the same time?同时创建和检索索引?
【发布时间】:2018-11-14 23:22:07
【问题描述】:

我正在开发一个使用 MariaDB 运行的 C# 程序。 由于它可以由多个用户同时运行,因此在使用“INSERT”语句插入(创建)新行时,我将索引(唯一索引字段)留空并让 MariaDB 分配它们。

问题是,由于我在程序中将索引字段留空,我不知道在 DB 中分配了哪个索引号。如果我尝试在客户端创建索引,那么我不能保证它在数据库上也是唯一的。

那么,有没有办法在创建行时检索数据库分配的索引号?

PS:我正在使用sqlcommandbuilder和sqladapter的更新功能。

【问题讨论】:

  • 原来是AUTO_INCREMENT?
  • 如果您能提供minimal reproducible example,那就太好了。
  • 你想要的是类似于 SQL 输出子句的东西。 docs.microsoft.com/en-us/sql/t-sql/queries/… 不幸的是,我不知道 Maria DB 是否支持类似的东西。
  • MariaDB 是 MySQL 的变体,SQL Server 提供程序(“sqlcommandbuilder”和“sqladapter”)不应该使用它。官方 MySQL 提供程序在 NuGet 上
  • 是的,该字段已设置为 AUTO_INCREMENT。

标签: c# sql indexing mariadb


【解决方案1】:

您完全正确:您无法在 GUI 中定义主键。这样做只会让你进入竞争状态。您需要让数据库生成它(以及任何其他自动值),然后返回它。

我对Maria DB一无所知,所以只能给你SQL相关的答案:SELECT TOP和SCOPE_IDENTITY都用过。然而,那些根本不是比赛条件。然而,SQL OUTPUT clause 是。检索自动创建的数据,如 PK 就是它的用途。它甚至是围绕 DML 语句的原始 Transaction 的一部分。

我在谷歌搜索中找不到“MariaDB OUTPUT 子句”的匹配项。但是我确实找到了这个:

该语句的其他选项包括“INSERT...SET”语句, “INSERT...SELECT”语句和其他几个选项。

“插入选择”语法可能最接近 SQL 的 INSERT ... OUTPUT 组合。可以。

编辑:嗯,MariaDB 中的 INSERT SELECT 似乎并不是您要寻找的机器人:https://mariadb.com/kb/en/library/insert-select/ 它更像是从其他表/导入中批量插入/插入

所以我猜回退是制作您自己的插入/选择组合,这是手动创建的事务和锁定表的一部分。

【讨论】:

  • 非常感谢克里斯托弗。我已经阅读了你所有的链接,它启发了我。是的,我必须使用我自己的插入 .. 选择并通过 ExecuteScalar() 命令运行它。
【解决方案2】:

怎么样,使用下面的2条sql?

SELECT MAX(id) FROM mytable.

SELECT LAST_INSERT_ID()

会制造另一个比赛条件吗?

【讨论】:

  • 如果在 INSERT 和 select 之间插入了其他任何东西:当然这将是一个竞争条件。你得到错误的ID。如果您可以将其包裹在与原始插入相同的锁中,那将是节省的。然后没有其他插入可以干扰。
  • 是的 lock 可以工作,但 tablelock 似乎也阻止了读取权限。我不想阻止用户阅读,但写作......
  • 通常查询在获取锁/检测死锁时会超时。大约30秒。 DML 状态插入本身 已经需要对表进行完全读/写锁定。这本质上是插入的一部分。所以手动创建锁并在其中添加选择不会有很大的变化。
  • 任何 DQL 语句都将具有隐式读锁作为操作的一部分。任何 DML 语句都将具有隐式读/写锁和隐式事务作为操作的一部分。这是数据库的基础,NTFS 本身也具有这两个功能。我知道您可以关闭隐式事务(但是您永远不应该这样做)。我怀疑你甚至可以用锁做到这一点。但是,如果您在整个事情上都有类似的锁定/事务,则两者都可以被否决/掩盖。您手动创建它们,以获得“更多操作”。
猜你喜欢
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2022-10-15
  • 2021-01-14
  • 1970-01-01
  • 2017-08-24
相关资源
最近更新 更多