使用ColdFusion和MySQL插入后获取表ID

使用ColdFusion和MySQL插入后获取表ID,mysql,sql-server,coldfusion,Mysql,Sql Server,Coldfusion,在MSSQL中,插入到一个表中,然后获取ID以便插入到另一个表中的正常过程如下所示: DECLARE @transactionKey uniqueidentifier SET @transactionKey = NEWID() INSERT INTO transactions(transactionKey, transactionDate, transactionAmount) VALUES(@transactionKey, '#transactionDate#', '#transac

在MSSQL中,插入到一个表中,然后获取ID以便插入到另一个表中的正常过程如下所示:

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

这方面的任何帮助都会很好

提前感谢。

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

第二部分: 与许多事情一样,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>
对于CF8,不同的数据库在结果值中具有不同的键。下面是一个简单的表格,帮助我从中复制

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

<cfdump var="#result#" />

以下是MSSQL的快速解决方案。它使用SCOPE_IDENTITY()函数返回上一个insert语句中插入的最后一行的ID


声明@iNewGeneratedID INT
插入到事务中
(
交易日期,
交易量
)
价值观
(
,
)
设置@iNewGeneratedID=SCOPE\u IDENTITY()
插入到transactionItems中
(
事务ID,
itemID,
项目金额
)
价值观
(
@不可再生能源,
,
)
选择@iNewGeneratedID作为iNewGeneratedID
可用于大多数数据库:

示例:

<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>

插入艺术家(名字、姓氏)
值('todd','sharp')
挑选*
来自艺术家
#getGeneratedKey(r)#

根据@aaron greenlee的回答,INSERT查询的结果变量包含一个键值对,该键值对是插入行的自动生成ID

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

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

插入到myTable中(
标题
)
插入输出*
价值观(
)
您将在结果中获得插入的记录详细信息


希望这有帮助。谢谢。

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

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

Re:我读到有可能GUID在我身上发生了变化,您在哪里读到的?+1表示“结果”属性,使用cfqueryparam,并将查询拆分为更细粒度的调用。@aaron谢谢!我不知道为什么这么长时间以来我一直在用另一种方式做这件事。这要容易得多。我不知道为什么,但我一直无法得到结果。generatedKey为我工作。使用result.generated_键可以正常工作。根据您使用的数据库,主键名为differences。猜测驱动程序作者“几乎”在同一个约定上。对于MSSQL来说,它不是identificCol。。。这是识别密码!我更喜欢这种方式,而不是我当时的另一种方式。这对存储过程很有好处。看起来您的答案没有添加任何新内容,因为您提供的信息已经存在于接受的答案中。我投了反对票,因为我认为不应该提供这个答案。如果你愿意,你可以删除答案,这将从你的SO声誉中删除否决票。当这么多问题和答案已经发布时,很难积累声誉,但请记住,你的声誉在现实世界中并不重要:)
<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>
<cfquery result="result">
   INSERT INTO myTable (
      title
   )
   OUTPUT INSERTED.*
   VALUES (
   <cfqueryparam value="Nice feature!" cfsqltype="cf_sql_varchar">
   )
</cfquery>
<cfset NewPrimaryKey = result.generatedkey> OR
<cfset NewPrimaryKey = result.identitycol>