【问题标题】:Get table ID after insert with ColdFusion and MySQL使用 ColdFusion 和 MySQL 插入后获取表 ID
【发布时间】:2020-08-26 04:55:50
【问题描述】:

我插入一个表然后取回 ID 以便我可以插入另一个表的正常过程在 MSSQL 中是这样的:

DECLARE @transactionKey uniqueidentifier
SET @transactionKey = NEWID()

INSERT INTO transactions(transactionKey, transactionDate, transactionAmount)
    VALUES(@transactionKey, '#transactionDate#', '#transactionAmount#')

DECLARE @transactionID int
SELECT @transactionID = transactionID
    FROM transactions
    WHERE transactionKey = @transactionKey


INSERT INTO transactionItems(transactionID, itemID, itemAmount)
    VALUES(@transactionID, '#itemID#', '#itemAmount#')


SELECT @transactionID as transactionID

我的问题分为两部分。首先,这是最好的方法吗?我读到 GUID 有可能在我身上发生变化,最终我在第二个表中得到了无效的 GUID。我假设这种情况的可能性非常小,而且我多年来一直在各种项目中这样做并且从未遇到过问题。

我的问题的第二部分是这样的事情在 MySQL 中是否有效?我开始使用 MySQL 开展一个新项目,但我不确定最好的方法。我过去通常只在 MSSQL 上工作过。

我在这个新项目中使用 CF9 和 MySQL。

在这方面的任何帮助都会很棒。

提前致谢。

【问题讨论】:

  • 回复:我读到我的 GUID 有可能发生变化你从哪里读到的?

标签: mysql sql-server coldfusion


【解决方案1】:

第 1 部分: 我个人不会在单个查询中批处理多个语句以降低 SQL 注入的风险。这是 ColdFusion 管理员数据源中的设置。执行存储过程,这可能是您正在做的事情(?),是另一回事,但是,如果这是您的意图,您应该将您的问题改写为“使用 mySQL 存储过程插入后获取主键”。

第 2 部分: ColdFusion 和很多东西一样,使得获取新插入记录的主键变得非常容易——即使您使用的是自动递增键、GUID 或 Oracle 的 ROWNUM 之类的东西。这将适用于 Adob​​e ColdFusion 支持的几乎所有数据库,包括 MSSQL 或 MySQL。唯一的例外是数据库的版本——例如,MySQL 3 不支持这个;但是,MySQL 4+ 会。

<cfquery result="result">
  INSERT INTO myTable (
      title
  ) VALUES (
    <cfqueryparam value="Nice feature!" cfsqltype="cf_sql_varchar">
  )
</cfquery>

<--- get the primary key of the inserted record --->
<cfset NewPrimaryKey = result.generatedkey>

从 CF9+ 开始,您可以使用通用键名访问新 ID(适用于任何数据库):

result.GENERATEDKEY    // All databases

对于 CF8,不同的数据库在结果值中会有不同的键。这是一个简单的表格,可以帮助我从cfquery documentation 复制。

result.identitycol    // MSSQL
result.rowid          // Oracle
result.sys_identity   // Sybase
result.serial_col     // Informix
result.generated_key  // MySQL

如果您有任何问题,您可以看到如下漂亮的转储:

<cfdump var="#result#" />

【讨论】:

  • +1 用于“结果”属性,使用 cfqueryparam,并将查询拆分为更精细的调用。
  • @aaron 谢谢!我不知道为什么我这么长时间一直在做相反的事情。这要容易得多。
  • 我不知道为什么,但我一直无法让 result.generatedKey 为我工作。使用 result.generated_key 效果很好。
  • 根据您使用的数据库,主键被命名为差异。猜猜驱动程序作者“几乎”采用相同的约定。
  • 对于 MSSQL,它不是 identifycol... 它是 identitycol
【解决方案2】:

这里是 MSSQL 的快速解决方案。它使用 SCOPE_IDENTITY() 函数返回在前一个插入语句中插入的最后一行的 ID。

http://msdn.microsoft.com/en-us/library/ms190315.aspx

<cfquery>
    DECLARE @iNewGeneratedID INT

    INSERT INTO transactions
        (
            transactionDate,
            transactionAmount
        )
    VALUES
       (
            <cfqueryparam value="#transactionDate#" type="cf_sql_date">,
            <cfqueryparam value="#transactionAmount#" type="cf_sql_integer">
       )

    SET @iNewGeneratedID = SCOPE_IDENTITY()

    INSERT INTO transactionItems
        (
            transactionID,
            itemID,
            itemAmount
        )
    VALUES
        (
            @iNewGeneratedID,
           <cfqueryparam value="#itemID#" type="cf_sql_integer">,
           <cfqueryparam value="#itemAmount#" type="cf_sql_integer">
        )

    SELECT @iNewGeneratedID AS iNewGeneratedID
</cfquery>

【讨论】:

  • 谢谢!我喜欢这种方式也比我做的其他方式更好。这将有利于存储过程。
【解决方案3】:

根据@aaron-greenlee 的回答,INSERT 查询的结果变量包含一个键值对,即插入行的自动生成的ID; this is available only for databases that support this feature.

以下是返回所有数据库的插入记录的可能方法。

<cfquery result="result">
   INSERT INTO myTable (
      title
   )
   OUTPUT INSERTED.*
   VALUES (
   <cfqueryparam value="Nice feature!" cfsqltype="cf_sql_varchar">
   )
</cfquery>

您将在结果中获得插入记录的详细信息。

希望这会有所帮助。谢谢。

【讨论】:

    【解决方案4】:

    getGeneratedKey function at cflib.org 可用于大多数数据库:

    示例:

    <cfquery name="insertArtist" datasource="cfartgallery" result="r">
        insert into artists (firstName, lastName)
        values('todd','sharp')
    </cfquery>
    <cfquery name="getArtists" datasource="cfartgallery">
        select *
        from   artists
    </cfquery>
    <cfdump var="#getArtists#">
    <cfoutput>#getGeneratedKey(r)#</cfoutput>
    
    <cffunction name="getGeneratedKey" 
        hint="I normalize the key returned from cfquery" output="false">
    
          <cfargument name="resultStruct" hint="the result struct returned from cfquery" />
          <cfif structKeyExists(arguments.resultStruct, "IDENTITYCOL")>
              <cfreturn arguments.resultStruct.IDENTITYCOL />
          <cfelseif structKeyExists(arguments.resultStruct, "ROWID")>
              <cfreturn arguments.resultStruct.ROWID />
          <cfelseif structKeyExists(arguments.resultStruct, "SYB_IDENTITY")>
              <cfreturn arguments.resultStruct.SYB_IDENTITY />
          <cfelseif structKeyExists(arguments.resultStruct, "SERIAL_COL")>
              <cfreturn arguments.resultStruct.SERIAL_COL />  
          <cfelseif structKeyExists(arguments.resultStruct, "GENERATED_KEY")>
              <cfreturn arguments.resultStruct.GENERATED_KEY />
          <cfelse>
              <cfreturn />
          </cfif>
    </cffunction>
    

    【讨论】:

      猜你喜欢
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 2010-10-28
      • 1970-01-01
      • 2014-02-18
      • 2017-10-14
      相关资源
      最近更新 更多