【问题标题】:SQL - Inserting a row and returning primary keySQL - 插入一行并返回主键
【发布时间】:2012-01-18 17:48:34
【问题描述】:

我在存在主键的表中插入了包含一些数据的行。如何“选择”刚插入的第一行的主键?

我应该更具体一些,并提到我目前 使用 SQLite。

【问题讨论】:

  • 您使用的是哪种 RBDMS?

标签: sql sqlite insert row primary-key


【解决方案1】:

对于 MS SQL Server:

SCOPE_IDENTITY() 将返回您当前范围内最后生成的身份值:

SELECT SCOPE_IDENTITY() AS NewID

【讨论】:

  • 适用于 SQL Server - 但仅如果您有INT IDENTITY(或BIGINT IDENTITY)类型的主键 - 任何其他类型的 PK(如 GUID 或SCOPE_IDENTITY()不支持
  • 没错,好点...我会 +1 你的答案,因为你已经解决了这种情况。
  • @marc_s: or numeric(x,0) too: 猜测 SCOPE_IDENTITY() 的类型...msdn.microsoft.com/en-us/library/ms190315.aspx
  • 非常感谢。虽然我应该更具体一点,并提到我目前正在使用 SQLite。无论如何,我搜索了“SQLite 中的SCOPE_IDENTITY”并找到了答案。干杯。将此标记为答案。
【解决方案2】:

对于 SQL Server 2005 及更高版本,无论您的主键是什么类型,您始终可以使用 OUTPUT clause 返回插入的值:

INSERT INTO dbo.YourTable(col1, col2, ...., colN)
OUTPUT Inserted.PrimaryKey
VALUES(val1, val2, ....., valN)

【讨论】:

  • 这是要走的路,因为它适用于任何主键。它需要作为标量查询执行而不是非查询执行,但这很简单。
  • 好方法,但是如果你的表有触发器,你必须使用 OUTPUT ... INTO ... 输出到中间表。
  • 这行得通(谢谢!)但请注意 PrimaryKey 不是关键字(如果您尝试使用它,将导致 Invalid column name 'PrimaryKey'.。它应该替换为您的实际列名。
  • @Taran:当然-我只是写了PrimaryKey来说明这里,任何定义为主键的列都需要使用(因为OP没有提到他的主键是什么列)
  • @marc_s 是的,只是为以后像我这样的复制和粘贴笨蛋留下评论:)
【解决方案3】:

对于 MySQL,使用 LAST_INSERT_ID()

http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html

您还应该能够启动事务、插入行并使用具有您刚刚插入的唯一值的某个字段(例如时间戳或 guid)选择行。这应该适用于几乎任何支持事务的 RDBMS,只要您有一个很好的唯一字段来选择行。

【讨论】:

  • 只有当你有一个自动增量字段时才有效。如果我有自定义 id 字段怎么办?我会运行另一个查询来获取该值。有什么办法吗?
【解决方案4】:

SQL 服务器:

您可以使用@@IDENTITY。在插入语句之后,您可以运行:

select @@identity

这将为您提供刚刚插入的记录的主键。如果您打算以后使用它,我建议保存它:

set @MyIdentity = @@identity

如果您在存储过程中使用它并希望在您的应用程序中重新访问它,请确保取消计数。

【讨论】:

【解决方案5】:

对于 Postgresql:

SELECT CURRVAL(pg_get_serial_sequence('schema.table','id'))

来源:https://stackoverflow.com/questions/2944297/postgresql-function-for-last-inserted-id

【讨论】:

  • PGSQL 可以做得更好,请查看 RETURNING。
  • 根据 BastetFurry 的评论,请参见 INSERT 命令的 RETURNING 子句。引用文档:The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number.
【解决方案6】:

如果您需要在表上有触发器时检索 MS SQL 中的新索引,那么您必须使用一些变通方法。一个简单的 OUTPUT 将不起作用。你必须这样做(在 VB.NET 中):

DECLARE @newKeyTbl TABLE (newKey INT);
INSERT INTO myDbName(myFieldName) OUTPUT INSERTED.myKeyName INTO @newKeyTbl VALUES('myValue'); " & _
SELECT newKey FROM @newKeyTbl;"

如果使用 .NET,则此查询的返回值可以直接转换为整数(您必须在 .NET SqlCommand 上调用“ExecuteScalar”才能获得返回)。

【讨论】:

    【解决方案7】:
    select MAX(id_column) from table
    

    理论上,这应该返回你最后插入的 id。如果它是一个繁忙的数据库,有许多插入操作,它可能不会得到你刚刚做的那个,而是另一个。

    无论如何,其他方法的替代方法。

    【讨论】:

      【解决方案8】:

      对于 SQLite:

      SELECT [Column_1],  [Column_2],...  [Column_n]
      FROM [YourTable]
      WHERE rowid = (SELECT last_insert_rowid())
      

      而:

      • Column_1、Column_2、... Column_n:是YourTable的主键。

      如果您创建的 YourTable 用主键替换了 rowid(即一列 pk 定义为 INTEGER PRIMARY KEY),您只需使用:

      SELECT last_insert_rowid()
      

      这是常见的情况。
      最后,这不适用于 WITHOUT_ROWID 表。

      请检查:

      https://www.sqlite.org/lang_corefunc.html#last_insert_rowid

      【讨论】:

      【解决方案9】:

      对于 PostgreSQL,

      INSERT INTO tablename (col1, col2, ...)
      VALUES (val1, val2, ...)
      RETURNING idcol;
      

      可选的 RETURNING 子句使 INSERT 根据实际插入的每一行计算并返回值(或更新,如果使用了 ON CONFLICT DO UPDATE 子句)。这主要用于获取默认提供的值,例如序列号。但是,任何使用表格列的表达式都是允许的。

      https://www.postgresql.org/docs/current/sql-insert.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-23
        • 1970-01-01
        • 2013-08-24
        相关资源
        最近更新 更多