我插入一个表然后获取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。
对此的任何帮助都会很棒。
提前致谢。
答案 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>