获取刚刚插入的记录的主键

时间:2011-04-26 22:29:09

标签: sql-server coldfusion sql-server-2000 coldfusion-8

这变得有点棘手。我想输出刚刚插入的记录的主键。我正在插入多个记录:

我的插入语句如下所示:

<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
    <cfoutput query="myFileList">
        INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
    </cfoutput>
</cfquery>

<cfset newID = result.IdentityCol>
<cfoutput>#newID#</cfoutput>

这引发了CF错误:

  

“RESULT中未定义元素IDENTITYCOL。”

所以我认为有希望以另一种方式获得我刚插入的记录的PK。有什么想法吗?

以下是我根据示例使用的代码:

<cftransaction>
    <cfquery name="importFiles" datasource="#dsn#" result="result">
        <cfoutput query="myFileList">
        INSERT INTO tbl_logfiles (originalFile, originalFileSize) VALUES ('#name#', '#length#');
        </cfoutput>
    </cfquery>

    <cfquery name="getID" datasource="#dsn#">
         select Max(fileID) as NewID from tbl_logfiles;
    </cfquery>
</cftransaction>

<cfset newID = getID.NewID>
<cfoutput> #newID# </cfoutput>

我从#newID#获得的输出是280,这是我此时数据库表中最高的fileID。怪异。

我想要获得的是我导入的最后N条记录。我希望有一种方法可以基于cfoutputcfquery.result标签以某种方式输出它。

4 个答案:

答案 0 :(得分:4)

我知道这是一个旧线程,但是......从不使用SELECT MAX(Column)来获取插入的最后一个ID。 It is not thread safe,即使在交易中(设置为默认级别)。

由于result属性仅返回单个标识值,因此您必须使用单独的查询(无论如何,对于SQL Server 2000)。然后,您可以在每个insert之后获取并存储新ID。

另外,请务必在所有参数上使用cfqueryparam。除了防止sql注入,它还会通过鼓励数据库reuse the same query plan来提高insert查询的性能。

<cfset newIDArray = []>
<cftransaction>
    <cfloop query="myFileList">
        <cfquery result="result" ...>
           INSERT INTO myTablename (...) VALUES (...);
        </cfquery>
        <!--- For CF9+ use generic result.generatedKey instead --->
        <cfset arrayAppend(newIDArray, result.identityCol)>
    </cfloop>
</cftransaction>

注意:正如Nicholas在评论中提到的,CF9 +引入了一个新的数据库不可知密钥名result.generatedKey。因此,如果您使用的是更高版本,则该密钥名称优先于result.identityCol,以获得更大的灵活性。

显然有better options like OUTPUT for SQL Server 2005

答案 1 :(得分:1)

它将是MSSQL 2000或2005.如果您使用的是2005,则可以在INSERT查询中使用OUTPUT子句来跟踪插入创建的PK值。

有关OUTPUT的更多信息,请参阅此BOL文章。

要将此设置为您的解决方案,您可能必须将其设置为存储过程并从CF调用SP。

答案 2 :(得分:0)

在coldfusion中有多种方法可以做到 - 请在此处查看:http://tutorial480.easycfm.com/

编辑:

尝试这种方法,它肯定会起作用:


<cftransaction>
<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
<cfoutput query="myFileList">
INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
</cfoutput>
</cfquery>
<cfquery name="getID" datasource="#mydsn#" result="#result#">
select Max(id) as NewID from myTablename;
</cfquery>
</cftransaction>
<cfset newID = getID.NewID>
<cfoutput>
#newID#
</cfoutput>

根据评论编辑:

是的,当然。您在cfquery标记中有一个cfoutput查询,因此您要逐行插入,并且每次都要创建一个新ID。如果您需要每个ID,那么您需要将整个内容包装在cfoutput中:


<cftransaction>
<cfoutput query="myFileList">
<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
</cfquery>
<cfquery name="getID" datasource="#mydsn#" result="#result#">
select Max(id) as NewID from myTablename;
</cfquery>
<cfset newID = getID.NewID>
#newID#
</cfoutput>
</cftransaction>

答案 3 :(得分:0)

我认为在这种情况下,您需要在自己的cfquery标记中执行每个插入操作。如果你一次只进行一次插入,这不会有问题,但是因为你正在进行多次插入(并且你使用的是旧版本的SQL Server),所以没有办法用一个{ {1}}。如果你是在2005年或2008年,你可能会使用另一个回复中提到的cfquery方法。