当我使用CFINSERT
时,表单数据会插入到我的数据库中,因为字段名称与列名称匹配。
我的问题:如何使用CFINSERT获取刚刚添加的行的主键?
我知道我不能使用类似于标准cfquery
的“Result ='variable'”,那么获得主键的最佳方法是什么?
如果我在cfinsert之后直接运行以下查询,它应该返回以前的PK:
<cfquery name="getID" datasource="#mydsn#" result="#result#">
select Max(id) as NewID from myTablename;
</cfquery>
这是完成我想要做的事情的最好方法吗?
答案 0 :(得分:2)
处理此问题的最佳方法是从查询的结果结构中获取generatedKey
的主键。
<cfquery name="myQuery" result="queryResult" datasource="#myDSN#">
INSERT INTO some_table
(column_one)
VALUES
(<cfqueryparam value="#stringForColOne#" cfsqltype="CF_SQL_VARCHAR">)
</cfquery>
<cfoutput>
Generated Key from SQL Insert = #queryResult.generatedKey#
</cfoutput>
请参阅https://wikidocs.adobe.com/wiki/display/coldfusionen/cfquery#cfquery-Usage
答案 1 :(得分:1)
由于您使用的是SQL Server,因此可以使用SCOPE_IDENTITY()
函数安全地获取当前作用域中最后插入的标识值。
SCOPE_IDENTITY(Transact-SQL)
返回插入标识列的最后一个标识值 相同的范围。范围是一个模块:存储过程,触发器, 功能或批处理。因此,如果两个语句属于同一范围 它们处于相同的存储过程,功能或批处理中。
当在两个单独的ColdFusion标记(<cfinsert>
后跟<cfquery>
)中使用时,那两个批次和SCOPE_IDENTITY()
将不再有效。因此,INSERT
和SELECT
语句必须属于同一批次。不幸的是,<cfinsert>
无法实现这一点。
你说你的表格帖子中有很多字段,所以我会这样做:
<cfset fieldNames = "all,relevant,field,names,from,http,post">
<cfset fieldTypes = "INTEGER,VARCHAR,VARCHAR,DATETIME,INTEGER,VARCHAR,VARCHAR">
<cfset fieldNullable = "false,true,true,true,false,true,false">
<cfset fieldCount = ListLen(fieldNames)>
<!--- default "" for any fields missing from the HTTP POST --->
<cfloop from="1" to="#fieldCount#" index="i">
<cfparam name="FORM.#ListGetAt(fieldNames, i)#" default="">
</cfloop>
<cfquery name="insert" datasource="#yourdatasource#">
INSERT YourTable (#fieldNames#)
VALUES (
<cfloop from="1" to="#fieldCount#" index="i">
<cfif i gt 1>,</cfif>
<cfset val = FORM[ListGetAt(fieldNames, i)]>
<cfset type = "CF_SQL_#ListGetAt(fieldTypes, i)#">
<cfset null = ListGetAt(fieldNullable, i) eq "true" and val eq "">
<cfqueryparam value="#val#" cfsqltype="#type#" null="#null#">
</cfloop>
)
SELECT SCOPE_IDENTITY() as NewId
</cfquery>
<cfdump var="#insert#">