插入ColdFusion和MySQL后获取表ID

时间:2011-10-22 16:01:10

标签: mysql sql-server coldfusion

我插入一个表然后获取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

我的问题是2部分。首先,这是最好的方法吗?我读到GUID有可能在我身上发生变化,我最终在第二个表中出现了无效的GUID。我假设这个机会非常渺茫,我多年来一直在各种项目中这样做,并且从来没有遇到过问题。

我的问题的第二部分是在MySQL中做这样的工作吗?我开始使用MySQL开发一个新项目,我不确定最好的方法。我通常只在MSSQL上工作过。

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

对此的任何帮助都会很棒。

提前致谢。

5 个答案:

答案 0 :(得分:26)

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

第2部分: 与许多事情一样,ColdFusion使得为新插入的记录获取主键非常容易 - 即使您使用自动增量键,GUID或类似Oracle的ROWNUM。这适用于Adobe 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 :(得分:1)

这是MSSQL的快速解决方案。它使用SCOPE_IDENTITY()函数返回在前一个insert语句中插入的最后一行的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>

答案 2 :(得分:1)

根据@ 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>

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

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

答案 3 :(得分:0)

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>

答案 4 :(得分:-1)

对于MSSQL,以下两项都将返回新的主键

<cfset NewPrimaryKey = result.generatedkey> OR
<cfset NewPrimaryKey = result.identitycol>