使用CFQUERY并使用Oracle匿名块返回记录集

时间:2014-01-14 00:08:13

标签: oracle coldfusion plsql

参考:Oracle SQL RETURN INTO Fails within CFQUERY (ORA-06550/PLS-00103)

将PL / SQL放入变量然后在CFQUERY标签中执行,但是当我转储查询变量时,我得到“变量XX未定义”。

如何让匿名阻止返回受影响记录的ID,或者更好的是整个记录?

下面是执行的代码,但会抛出错误...

    <cfset plsql = "
        DECLARE record_id scpricequeue.scpricequeueid%TYPE;

        BEGIN
        update scpricequeue
            set datelocked = sysdate
            where scpricequeueid = (
                select scpricequeueid
                from (
                    select scpricequeueid
                    from scpricequeue
                    where islocked = 0 and completed = 0
                    order by dateadded asc
                )
                where rownum <= 1
            )
        RETURNING scpricequeueid INTO record_id;

        END;
        ">

    <cfset sql = "
        select *
        from scpricequeue
        ">

    <cfquery name="q" datasource="ecomd">
        #plsql#
    </cfquery>

    <cfdump var="#q#">

错误:变量q未定义

1 个答案:

答案 0 :(得分:0)

我通过使用SELECT ... FOR UPDATE

以另一种方式解决了我的特殊需求
  

当您对数据库发出SELECT语句以查询某些记录时,不会对所选行放置锁定。通常,这是一个很棒的功能,因为在任何给定时间锁定的记录数量保持绝对最小值:只有已更改但尚未提交的记录才会被锁定。即便如此,其他人也能够在更改之前读取这些记录(数据的“前映像”)。

     

但是,有时您甚至需要在程序中更改记录之前锁定一组记录。 Oracle提供SELECT语句的FOR UPDATE子句来执行此锁定。

     

当您发出SELECT ... FOR UPDATE语句时,数据库会自动获取SELECT语句标识的所有行上的行级锁定,并在您移动时保留“仅用于您的更改”的记录由光标检索的行。就好像你已经针对行发出了UPDATE语句,但是你没有 - 你只是选择了它们。在您执行ROLLBACK或COMMIT之前,没有其他人能够更改任何这些记录,但其他会话仍然可以读取数据。

     

参考:O'Reilly的Oracle PL-SQL,第492页

然而,我还在追踪其他一些更复杂但更有前景的解决方案。我从来没有得出结论,但希望这些对别人来说是有用的指针,在这里它们是。

  1. Oracle Package / CF存储过程:请参阅标题为“Use Oracle referenced cursors to return result sets (ColdFusion 4.5+, Oracle 7.3+):”和“Oracle PL-SQL”的章节(有关包的第18章)。我只是没有弄清楚如何创建包并将其链接到CF,但这似乎肯定是一个可行的解决方案。

  2. 我打算测试CFTRANSACTION是否对记录进行锁定,这与上面的SELECT ... FOR UPDATE解决方案类似。