在CFScript中获取新插入记录的ID

3

我有一些代码,可以将记录插入日志并附带请求信息。一旦请求被发送并返回响应,我会使用响应信息更新该记录。 是否有办法获取新插入记录的ID,以便在收到响应后引用它并进行更新? 我知道使用CF标签可以使用SET NO COUNT,但在CFScript中似乎不起作用。 似乎在INSERT语句中没有返回任何内容。

        query = new query();
        query.name = "queryResult";
        query.setDataSource('dsn');
        sql = "

        INSERT INTO paymentlogs (
            type, name, address1, address2, country, provstate, city, pocode, cclastfour, expirymonth, expiryyear, cardtype, requestxml, ipaddress, clid, subscriptionid, total, createdat, createdby, updatedat, updatedby
        )
        VALUES
        (
            :type, :name, :address1, :address2, :country, :provstate, :city, :pocode, :cclastfour, :expirymonth, :expiryyear, :cardtype, :requestxml, :ipaddress, :clid, :subscriptionid, :total, :now, :username, :now, :username
        )

        ";
        query.setSQL(sql);

        query.addParam(name="clid", cfsqltype="cf_sql_varchar", value="#formValues.clid#");
        query.addParam(name="type", cfsqltype="cf_sql_varchar", value="#arguments.type#");
        query.addParam(name="name", cfsqltype="cf_sql_varchar", value="#formValues.ccname#");
        query.addParam(name="address1", cfsqltype="cf_sql_varchar", value="#formValues.ccaddress1#");
        query.addParam(name="address2", cfsqltype="cf_sql_varchar", value="#formValues.ccaddress2#");
        query.addParam(name="country", cfsqltype="cf_sql_varchar", value="#formValues.cccountry#");
        query.addParam(name="provstate", cfsqltype="cf_sql_varchar", value="#formValues.ccprovstate#");
        query.addParam(name="city", cfsqltype="cf_sql_varchar", value="#formValues.cccity#");
        query.addParam(name="pocode", cfsqltype="cf_sql_varchar", value="#formValues.ccpocode#");
        query.addParam(name="cclastfour", cfsqltype="cf_sql_varchar", value="#Right(formValues.ccnumber, 4)#");
        query.addParam(name="expirymonth", cfsqltype="cf_sql_varchar", value="#formValues.ccexpirymonth#");
        query.addParam(name="expiryyear", cfsqltype="cf_sql_varchar", value="#formValues.ccexpiryyear#");
        query.addParam(name="cardtype", cfsqltype="cf_sql_varchar", value="#getCardType(formValues.cctype)#");
        query.addParam(name="requestxml", cfsqltype="cf_sql_varchar", value="#soapBody#");
        query.addParam(name="ipaddress", cfsqltype="cf_sql_varchar", value="#CGI.REMOTE_ADDR#");
        query.addParam(name="subscriptionid", cfsqltype="cf_sql_varchar", value="#formValues.subscriptionid#");
        query.addParam(name="total", cfsqltype="cf_sql_float", value="#formValues.grandTotalAmount#");
        query.addParam(name="username", cfsqltype="cf_sql_varchar", value="#formValues.username#");
        query.addParam(name="now", cfsqltype="cf_sql_timestamp", value="#now()#");
        result = query.execute().getResult();
        writedump(result);abort;

我在谷歌上搜索了一下,没有找到在CFScript中实现的方法。我不想查询最后一行,因为那不是很可靠。有没有办法在执行INSERT查询后获取新插入记录的ID?
我正在使用mySQL。奇怪的是,当我转储上面的“result”变量时,CF抱怨result未定义。当我检查表格时,我可以看到脚本确实执行了,并且记录已被插入。

回复:使用CF标签,你可以使用SET NO COUNT,但在CFScript中似乎不起作用。SET NOCOUNT是一个特定于SQL Server的命令。MySQL没有相应的命令。这就是为什么它对你不起作用的原因。话虽如此,通常只有在查询执行多个插入操作时才需要使用SET NOCOUNT - Leigh
3个回答

13

它应该位于 getPrefix().generatedkey 下面。

genKey = result.getPrefix().generatedkey;

我以为我可以做类似的事情,但是当我像在我的代码示例中一样转储结果变量时,我会收到一个错误,说结果未定义。因此,我无法访问结果中的任何内容。但是查询确实正确执行,我可以在表中看到插入的行。 - Guest
Matt是正确的。这些方法只是命名不当。在我看来,它们应该与cfquery标签属性对齐。但事实并非如此。getResult()相当于<cfquery name="..">,而getPrefix()相当于<cfquery result="..."> - Leigh

6
马特的回答是正确的,元数据位于前缀属性中。他的示例假定结果变量是返回的result = query.execute();而不是像您的代码中的result = query.execute().getResult();
根据查询cfc文档:“Prefix:相当于cfquery标记的结果属性。”

我的投票让你的声望超过了100。恭喜,你欠我一瓶啤酒。 - Dan Bracuk

1

或者你可以使用 Scope_Identity() MS SQL Server 函数:

sql = "

    INSERT INTO paymentlogs (
        type, name, address1, address2, country, provstate, city, pocode, cclastfour, expirymonth, expiryyear, cardtype, requestxml, ipaddress, clid, subscriptionid, total, createdat, createdby, updatedat, updatedby
    )
    VALUES
    (
        :type, :name, :address1, :address2, :country, :provstate, :city, :pocode, :cclastfour, :expirymonth, :expiryyear, :cardtype, :requestxml, :ipaddress, :clid, :subscriptionid, :total, :now, :username, :now, :username
    )

    select Scope_Identity() as [ID]

    ";

那么result.ID应该包含生成的ID。


问题中没有指定关系型数据库。 - Dan Bracuk
抱歉,我忘记提到我正在使用mySQL。但奇怪的是,我甚至无法转储结果,因为CF抱怨它未定义。 - Guest
1
抱歉,我假设是 MS SQL。关于结果不存在,可能不会被定义,因为查询没有返回值。通常,在没有返回值的情况下执行更新或插入操作时,您可以只需将 result = query.execute(); 尝试转储它。 - Jedihomer Townend
谢谢Jedihomer,它起作用了。我之前没有得到任何结果的原因是因为我将result设置为result = query.execute().getResult();而不是只有result = query.execute()。这就是为什么我不能使用getPrefix()函数的原因。请再发布一个答案,这样我就可以将其标记为答案。谢谢! - Guest
另请参见:https://dev59.com/8XI-5IYBdhLWcg3wTWf4 - James A Mohler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接