1

I'm trying to update a record at the same time I select it. In Oracle SQL Developer, the below query works. However, when I execute it from within a CFQUERY tag in ColdFusion, I get an error (see below). I found this stack overflow (ORA-06550 and PLS-00103) but wasn't any help.

Ideally, I'd also like to return the whole record, not just the ID of the affected record. So, I have two questions.

  1. Why is the below record failing from within a ColdFusion CFC's CFQUERY?
  2. How to I rewrite the query to return the affected record rather than just that record's id?

    DECLARE
      record_id scpricequeue.scpricequeueid%TYPE;
    
    BEGIN
    update scpricequeue
    set islocked = 1, 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;
    DBMS_OUTPUT.put_line('Locked Record: ' || record_id);
    
    END;
    

ERROR RECEIVED when executed as CFQUERY:

ORA-06550: line 1, column 8: PLS-00103: Encountered the symbol "" when
expecting one of the following: begin function package pragma procedure
subtype type use <an identifier> <a double-quoted delimited-identifier>
form current cursor The symbol "" was ignored.*
Community
  • 1
  • 1
Chris Geirman
  • 9,474
  • 5
  • 37
  • 70

3 Answers3

0

Do two queries, this should answer your question: https://stackoverflow.com/a/1883117/3112803 Hope that helps.

Since you are only doing one update and one select then the cftransaction tags are not needed. But if you were doing multiple add/update/deletes then you would want the cftransaction tag so if a error happens they would all roll back.

Community
  • 1
  • 1
gfrobenius
  • 3,987
  • 8
  • 34
  • 66
0

There are some db engines with which you can use a semi-colon. These include ms-sql and mySql. These do not include oracle.

This code runs without error:

<cfquery name="x" datasource="burns">
select 1 record 
from dual
</cfquery>

But, if you add a semi-colon,

<cfquery name="x" datasource="burns">
select 1 record 
from dual;
</cfquery>

You get

Error Executing Database Query.  
[Macromedia][Oracle JDBC Driver][Oracle]ORA-00911: invalid character  

The error occurred in D:\DW\dwtest\Dan\abc.cfm: line 106

104 :  --->
105 : 
106 : <cfquery name="x" datasource="burns">
107 : select 1 record 
108 : from dual;

Basically you need another approach. You move your code to a stored procedure and call that from ColdFusion, or you can follow @gfrobenius's advice and use more than one cfquery. Or you can do something else.

Dan Bracuk
  • 20,699
  • 4
  • 26
  • 43
-1

EDIT:
you can see here that, after the semicolon in declare block, CF pushed the query to the db layer, and oracle in turn replied back stating, I see a space instead of a begin keyword! Sure we have to push the block completely, and this should work.

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

BEGIN
update scpricequeue
set islocked = 1, 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;
DBMS_OUTPUT.put_line('Locked Record: ' || record_id);

END;
"
>
<cfquery name="q" datasource="yourDSN">
    #variables.plsql#
</cfquery>

Set the query string as a variable, while executing anonymous pl/sql blocks!

Courtesy: http://awads.net/wp/2005/07/25/oracle-plsql-in-cfquery/

Maheswaran Ravisankar
  • 17,652
  • 6
  • 47
  • 69
  • All you're doing is moving where the SQL string is created. Be it in a variable or between the `` tags makes no difference. The error is coming *from the DB* not from ColdFusion, so it's not going to matter how differently you write the CFML to arrive at the same SQL string to pass to the DB. – Adam Cameron Jan 01 '14 at 10:05
  • The error comes from Oracle , yes it is,but issue i guessed is,the query is not pushed to oracle correctly, and hence the error! – Maheswaran Ravisankar Jan 01 '14 at 10:28
  • 2
    @AdamCameron you can see here that, after the semicolon in declare block, CF pushed the query to the db layer, and oracle in turn replied backs tating, I see a space instead of a begin keyword! Sure we have push the block completely, and this should work! – Maheswaran Ravisankar Jan 01 '14 at 10:37
  • Whether you create the string in a variable first or directly in the `` block is neither here nor there. CF doesn't process the string at all, it just passes it to the DB. The only difference here is that when using a variable inside a `` block, any embedded single quotes will be escape, so you'll be passing `''Locked Record: ''` rather than `'Locked Record: '`. And all that will achieve is causing a syntax error once the DB gets it. – Adam Cameron Jan 01 '14 at 17:50
  • Why are you even commenting on the CFML-specific side of things here? Looking at your profile you don't actually know anything about CFML!? – Adam Cameron Jan 01 '14 at 17:53
  • @MaheswaranRavisankar, thank you! Your suggestion works. The PL/SQL now executes, BUT when I dump the query variable (q in your example) I get "Variable q is undefined" – Chris Geirman Jan 01 '14 at 17:59
  • @ChrisGeirman printing the variable is not possible I beleive, trying setting `result` attribute for cfquery. – Maheswaran Ravisankar Jan 01 '14 at 20:05
  • @AdamCameron I just go with basics of oracle, it is pretty much same , so far as the FE components I worked.(JDBC,pro*C,ODBC,ADO..) I don't mean to be offensive! Sorry if you felt so. Thanks. – Maheswaran Ravisankar Jan 01 '14 at 20:08
  • @MaheswaranRavisankar, I have checked the result struct, but the id of the affected row seems to only be returned on insert, not update. I think I may need to figure out how to return a rowset rather than just the id. It doesn't appear the PL/SQL is passing anything back to the cfquery tag when I pass just the id of the affected row. – Chris Geirman Jan 02 '14 at 18:02