Why do I get "ORA-00932: inconsistent datatypes: expected - got -" when using COLLECT() in a prepared statement?

10,042

Finally got a solution to this issue, thanks to some digging by a user. The problem was not with the placeholder; why it worked without the placeholder on the VirtualBox image I have no idea. No, the issue was with the COLLECT(). Seems that both the values being collected need to be cast to a specific type, and the resulting array also needs to be cast to a pre-defined array data type. Just so happens that my code has a custom array type:

CREATE TYPE sqitch_array AS varray(1024) OF VARCHAR2(512);

So I'm able to get the query to work by casting the COLLECT() like so:

CAST(COLLECT(CAST(t.tags as VARCHAR2(512))) AS sqitch_array)
Share:
10,042
theory
Author by

theory

Intersectional humanist. He/him.

Updated on June 04, 2022

Comments

  • theory
    theory almost 2 years

    I am using this query with the Perl DBI:

    SELECT c.change_id
         , COLLECT(t.tag) AS the_tags
      FROM changes   c
      LEFT JOIN tags t ON c.change_id = t.change_id
     WHERE c.project = ?
     GROUP BY c.change_id
    

    The DBI uses OCI to prepare this statement, bind the value I pass, and get the results. But Oracle, for some reason, does not like it. The error output is:

         ORA-00932: inconsistent datatypes: expected - got - (DBD ERROR: error possibly near <*> indicator at char 41 in '
                SELECT c.change_id
                     , <*>COLLECT(t.tag) AS the_tags
                  FROM changes   c
                  LEFT JOIN tags t ON c.change_id = t.change_id
                 WHERE c.project = :p1
                 GROUP BY c.change_id
            '
    

    Not very informative. However, I can make this error go away not only by changing the call to COLLECT() also by replacing the placeholder with the actual value:

         SELECT c.change_id
              , COLLECT(t.tag) AS the_tags
           FROM changes   c
           LEFT JOIN tags t ON c.change_id = t.change_id
          WHERE c.project = 'tryoracle'
          GROUP BY c.change_id
    

    That version works perfectly. Why doesn't Oracle like the prepared statement with the COLLECT()?

    In case it's any help, here is a trace of the OCI-related calls extracted via ora_verbose = 6 (h/t @bohica).

  • Kurt Mueller
    Kurt Mueller about 9 years
    Is there a way to do this in one line? Something along the lines of CAST(COLLECT(CAST(t.tags as VARCHAR2(512))) AS (varray(1024) OF VARCHAR2(512)))?
  • Kjetil S.
    Kjetil S. about 6 years
    I mysteriously got ORA-00932 with select distinct myid, myblobcolumn from mytable. Removing distinct helped.