Subselect in PL/SQL

I am using ORACLE 8.17 and am trying to use a subselect in a sql proc. I am getting an error. Are these not allowed in PL/SQL?
Example
CREATE OR REPLACE PROCEDURE SUBSELECT_TEST
IS
V_DATE DATE;
BEGIN
SELECT (SELECT SYSDATE FROM DUAL) FROM DUAL;
END;

In 8i you could try something like :
CREATE OR REPLACE PROCEDURE SUBSELECT_TEST
IS
cursor my_cursor is
SELECT MY_DATE from (SELECT SYSDATE MY_DATE FROM DUAL);
BEGIN
for c in my_cursor
loop
dbms_output.put_line(c.my_date);
end loop;
END;

Similar Messages

  • SQL Optimization with join and in subselect

    Hello,
    I am having problems finding a way to optimize a query that has a join from a fact table to several dimension tables (star schema) and a constraint defined as an in (select ....). I am hoping that this constraint will filter the fact table then perform the joins but I am seeing just the opposite with the optimizer joining first and then filtering at the very end. I am using the cost optimizer and saw that it does in subselects last in the predicate order. I tried the push_subq hint with no success.
    Does anyone have any other suggestions?
    Thanks in advance,
    David
    example sql:
    select ....
    from fact, dim1, dim2, .... dim <n>
    where
    fact.dim1_fk in ( select pf from dim1 where code = '10' )
    and fact.dim1_fk = dim1.pk
    and fact.dim2_fk = dim2.pk
    and fact.dim<n>_fk = dim<n>.pk

    The original query probably shouldn't use the IN clause because in this example it is not necessary. There is no limit on the values returned if a sub-select is used, the limit is only an issue with hard coded literals like
    .. in (1, 2, 3, 4 ...)Something like this is okay even in 8.1.7
    SQL> select count(*) from all_objects
      2  where object_id in
      3    (select object_id from all_objects);
      COUNT(*)
         32378The IN clause has its uses and performs better than EXISTS in some conditions. Blanket statements to avoid IN and use EXISTS instead are just nonsense.
    Martin

  • SQL HEXTORAW with SUBSELECT and INLIST

    Hello guys,
    i have the following table definition
    TAB_A
    ===========
    COL1 RAW(16)
    COL2 RAW(16)
    TAB_B
    ===========
    COL1 RAW(16)
    COL2 RAW(16)
    Now the SELECT looks like the following:
    SELECT * FROM TAB_A WHERE COL1 IN ( SELECT COL2 FROM TAB_B where COL1 = HEXTORAW('12234CX'));Now i have the problem that the COL1 of TAB_A is indexed, but the index can not be used, because of oracle doesn't do an implicit conversion for COL1 of TAB_A.
    How can i use the function HEXTORAW() in that case, that the values that are returned from the SUBSELECT are translated into RAW.
    Thanks and Regards

    user11981296 wrote:
    Hello John,
    the index is also not be used when using a HINT ... so therefore it is not an optimizer problem .. it is a "data type" problem.
    RegardsNo, Oracle is fully capable of using an index on a raw column, assuming that one exists.
    SQL> desc raw_test
    Name                                      Null?    Type
    ID                                                 NUMBER
    ADDRESS                                            RAW(8)
    SQL> set autot trace explain
    SQL> SELECT * FROM raw_test
      2  WHERE address = HEXTORAW('5358B2E88');
    Execution Plan
    Plan hash value: 1291953311
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT            |               |   897 | 17043 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| RAW_TEST      |   897 | 17043 |     3   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | RAW_TEST_ADDR |   359 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("ADDRESS"=HEXTORAW('05358B2E88') )So, something else is going on. If the hint does not drive it to using the index, then you have hinted incorrectly.
    John

  • SQL subselect rounds unintentional in SAP B1

    Hey everyone,
    if I am executing a select-statement with a subselect in sap b1, the result of the subselect is rounded - why? If I run a query without other tables, I get the exact value.
    SELECT T0.[TransId], T0.[RefDate],
    (SELECT T2.Rate FROM ORTT T2 WHERE T0.RefDate = T2.RateDate AND T2.Currency = 'USD')
    FROM OJDT T0  INNER JOIN JDT1 T1 ON T0.TransId = T1.TransId WHERE T1.[ShortName] = 'T0001'
    T2.Rate is rounded unintentional to two decimals and so further arithmetic operations are senseless because not exact. If I run the same query with Managment Studio, I get the exact value with four decimals. Several tries with CONVERT and CAST did not solve the problem.
    Any suggestions? Thank you!
    Best Regards
    Sebastian

    Hi,
    thanks for your reply. I have tried it out and you were right.. but the problem is, that I want to export the results into excel, but there the rounded values are exported.
    I have solved the problem by extending the where-clause and putting the T2.Rate into the normal select-clause.. then the values keep their format.
    Best Regards
    Sebastian

  • Global Temp Table vs. PL/SQL Table

    Hi,
    I'm trying to find out which better (efficient) to use in coding, a Global Temporary Table or PL/SQL table. The process requires evaluation to what data stored in the tbale.
    Thanks in advance.

    Ok, let me restate this.
    not carteasian product, carteasian LIKE ... where there is a many to many join between 2 fields (a resolution table).
    Anyway, on Sybase/SQL Server if you need 3 fields from a table, 3 tables away,
    you are allow to do a bulk / set update
    UPDATE tempTable
    field1 = t3X
    field2 = t3Y
    field3 = t3Z
    FROM tempTable, t1, t2, t3
    Where (joins)
    In Oracle, the only way to do this is with 3 subselects
    UPDATE tempTable
    field1 = ( select t3X FROM tempTable, t1, t2, t3
    Where (joins) ) ,
    field2 = (select t3Y FROM tempTable, t1, t2, t3
    Where (joins) ),
    field3 = (select t3Z FROM tempTable, t1, t2, t3
    Where (joins) ),
    while this works, it does not seem effcient or elegant compared to the Sybase Solution.
    By the way I am dealing with a design that preceeds me and I joined the team from a DIFFERERENT TEAM with a DIFFERENT background. I am neither stupid nor a poor designer, however I am ignorant of the Oracle ways and figured this would be the best place to look for the answer. Hans seems to have the best grasp of the request, does he have a CONSTRUCTIVE comment?
    Thank you in advance.
    Gary

  • Kind of loop in sql? Any alternative?

    Hi,
    We have the following table
    create table orders
    order_id NUMBER(10),
    vehicle_id NUMEBR(10),
    customer_id NUMBER(10),
    data VARCHAR(10)
    order_id, customer_id and vehicle_id are indexed.
    In this table are stored multiple orders for multiple vehicles.
    I need an sql-statements which returns me the last 5 orders for each truck.
    For only one vehicle its no problem:
    select * from orders
    where vehicle_id = <ID>
    and rownum <=5
    order by order_id desc;
    But I need something like a loop to perform this statement for each vehicle_id.
    Or is there any way to put it into a subselect?
    Any ideas are welcome ;-)
    Thanks in advance,
    Andreas

    Hello
    Effectively by having the bind variable in there you are partitioning by customer and vehicle id, so by adding customer_id into the partition statement, the optimiser should be able to push the bind variable right down to the inner most view...
    XXX> CREATE TABLE dt_orders
      2  (      order_id NUMBER NOT NULL,
      3         customer_id     NUMBER NOT NULL,
      4         vehicle_id      NUMBER NOT NULL,
      5         some_padding    VARCHAR2(100) NOT NULL
      6  )
      7  /
    Table created.
    Elapsed: 00:00:00.23
    XXX> INSERT INTO dt_orders SELECT ROWNUM ID, MOD(ROWNUM,100),MOD(ROWNUM,100), lpad(
      2  /
    10000 rows created.
    Elapsed: 00:00:00.43
    XXX> CREATE INDEX dt_orders_i1 ON dt_orders(customer_id)
      2  /
    Index created.
    Elapsed: 00:00:00.17
    XXX> select *
      2  from (
      3  select o.*, rank() over(partition by vehicle_id order by order_id desc) rk
      4  from dt_orders o
      5  where customer_id = :var_cust_id
      6  )
      7  where rk <= 5;
    5 rows selected.
    Elapsed: 00:00:00.11
    Execution Plan
    Plan hash value: 3174093828
    | Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT              |              |   107 | 11128 |    22   (5)| 00:00:01 |
    |*  1 |  VIEW                         |              |   107 | 11128 |    22   (5)| 00:00:01 |
    |*  2 |   WINDOW SORT PUSHED RANK     |              |   107 |  9737 |    22   (5)| 00:00:01 |
    |   3 |    TABLE ACCESS BY INDEX ROWID| DT_ORDERS    |   107 |  9737 |    21   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | DT_ORDERS_I1 |    43 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("RK"<=5)
       2 - filter(RANK() OVER ( PARTITION BY "VEHICLE_ID" ORDER BY
                  INTERNAL_FUNCTION("ORDER_ID") DESC )<=5)
       4 - access("CUSTOMER_ID"=TO_NUMBER(:VAR_CUST_ID))  <----
    Note
       - dynamic sampling used for this statement
    Statistics
             36  recursive calls
              0  db block gets
            247  consistent gets
              2  physical reads
              0  redo size
            518  bytes sent via SQL*Net to client
            239  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              5  rows processedyour original statement showing that the bind variable has been applied to access the dt_orders table via the index (predicate 4)
    If I change the statement to put the bind variable outside the inline view, we now do a full scan and you can see from predicate 1 that the customer id is being filtered at the highest level.
    XXX> select *
      2  from (
      3  select o.*, rank() over(partition by vehicle_id order by order_id desc) rk
      4  from dt_orders o
      5  )
      6  where rk <= 5
      7  AND customer_id = :var_cust_id ;
    5 rows selected.
    Elapsed: 00:00:00.32
    Execution Plan
    Plan hash value: 3560032888
    | Id  | Operation                | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT         |           | 10696 |  1086K|       |   268   (2)| 00:00:04 |
    |*  1 |  VIEW                    |           | 10696 |  1086K|       |   268   (2)| 00:00:04 |
    |*  2 |   WINDOW SORT PUSHED RANK|           | 10696 |   950K|  2216K|   268   (2)| 00:00:04 |
    |   3 |    TABLE ACCESS FULL     | DT_ORDERS | 10696 |   950K|       |    39   (3)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("RK"<=5 AND "CUSTOMER_ID"=TO_NUMBER(:VAR_CUST_ID))  <---
       2 - filter(RANK() OVER ( PARTITION BY "VEHICLE_ID" ORDER BY
                  INTERNAL_FUNCTION("ORDER_ID") DESC )<=5)
    Note
       - dynamic sampling used for this statement
    Statistics
              4  recursive calls
              0  db block gets
            240  consistent gets
              0  physical reads
              0  redo size
            519  bytes sent via SQL*Net to client
            239  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              5  rows processedBut those two statements are really the same. By applying the filter inside the view as in your original, it means it's only going to calculate the rank for those customers. So we can add the customer id to the partition by statement which means the optimiser can safely push the predicate back down to the access of the orders table..
    XXX> select *
      2  from (
      3  select o.*, rank() over(partition by customer_id,vehicle_id order by order_id desc) rk
      4  from dt_orders o
      5  )
      6  where rk <= 5
      7  AND customer_id = :var_cust_id ;
    5 rows selected.
    Elapsed: 00:00:00.04
    Execution Plan
    Plan hash value: 3174093828
    | Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT              |              |   107 | 11128 |    22   (5)| 00:00:01 |
    |*  1 |  VIEW                         |              |   107 | 11128 |    22   (5)| 00:00:01 |
    |*  2 |   WINDOW SORT PUSHED RANK     |              |   107 |  9737 |    22   (5)| 00:00:01 |
    |   3 |    TABLE ACCESS BY INDEX ROWID| DT_ORDERS    |   107 |  9737 |    21   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | DT_ORDERS_I1 |    43 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("RK"<=5)
       2 - filter(RANK() OVER ( PARTITION BY "CUSTOMER_ID","VEHICLE_ID" ORDER BY
                  INTERNAL_FUNCTION("ORDER_ID") DESC )<=5)
       4 - access("O"."CUSTOMER_ID"=TO_NUMBER(:VAR_CUST_ID))  <----
    Note
       - dynamic sampling used for this statement
    Statistics
              9  recursive calls
              0  db block gets
            244  consistent gets
              0  physical reads
              0  redo size
            519  bytes sent via SQL*Net to client
            239  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              5  rows processedHTH
    David

  • SQL Performance issue: Using user defined function with group by

    Hi Everyone,
    im new here and I really could need some help on a weird performance issue. I hope this is the right topic for SQL performance issues.
    Well ok, i create a function for converting a date from timezone GMT to a specified timzeone.
    CREATE OR REPLACE FUNCTION I3S_REP_1.fnc_user_rep_date_to_local (date_in IN date, tz_name_in IN VARCHAR2) RETURN date
    IS
    tz_name VARCHAR2(100);
    date_out date;
    BEGIN
    SELECT
    to_date(to_char(cast(from_tz(cast( date_in AS TIMESTAMP),'GMT')AT
    TIME ZONE (tz_name_in) AS DATE),'dd-mm-yyyy hh24:mi:ss'),'dd-mm-yyyy hh24:mi:ss')
    INTO date_out
    FROM dual;
    RETURN date_out;
    END fnc_user_rep_date_to_local;The following statement is just an example, the real statement is much more complex. So I select some date values from a table and aggregate a little.
    select
    stp_end_stamp,
    count(*) noi
    from step
    where
    stp_end_stamp
    BETWEEN
    to_date('23-05-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')      
    AND
    to_date('23-07-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')
    group by
    stp_end_stampThis statement selects ~70000 rows and needs ~ 70ms
    If i use the function it selects the same number of rows ;-) and takes ~ 4 sec ...
    select
    fnc_user_rep_date_to_local(stp_end_stamp,'Europe/Berlin'),
    count(*) noi
    from step
    where
    stp_end_stamp
    BETWEEN
    to_date('23-05-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')      
    AND
    to_date('23-07-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')
    group by
    fnc_user_rep_date_to_local(stp_end_stamp,'Europe/Berlin')I understand that the DB has to execute the function for each row.
    But if I execute the following statement, it takes only ~90ms ...
    select
    fnc_user_rep_date_to_gmt(stp_end_stamp,'Europe/Berlin','ny21654'),
    noi
    from
    select
    stp_end_stamp,
    count(*) noi
    from step
    where
    stp_end_stamp
    BETWEEN
    to_date('23-05-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')      
    AND
    to_date('23-07-2009 00:00:00','dd-mm-yyyy hh24:mi:ss')
    group by
    stp_end_stamp
    )The execution plan for all three statements is EXACTLY the same!!!
    Usually i would say, that I use the third statement and the world is in order. BUT I'm working on a BI project with a tool called Business Objects and it generates SQL, so my hands are bound and I can't make this tool to generate the SQL as a subselect.
    My questions are:
    Why is the second statement sooo much slower than the third?
    and
    Howcan I force the optimizer to do whatever he is doing to make the third statement so fast?
    I would really appreciate some help on this really weird issue.
    Thanks in advance,
    Andi

    Hi,
    The execution plan for all three statements is EXACTLY the same!!!Not exactly. Plans are the same - true. They uses slightly different approach to call function. See:
    drop table t cascade constraints purge;
    create table t as select mod(rownum,10) id, cast('x' as char(500)) pad from dual connect by level <= 10000;
    exec dbms_stats.gather_table_stats(user, 't');
    create or replace function test_fnc(p_int number) return number is
    begin
        return trunc(p_int);
    end;
    explain plan for select id from t group by id;
    select * from table(dbms_xplan.display(null,null,'advanced'));
    explain plan for select test_fnc(id) from t group by test_fnc(id);
    select * from table(dbms_xplan.display(null,null,'advanced'));
    explain plan for select test_fnc(id) from (select id from t group by id);
    select * from table(dbms_xplan.display(null,null,'advanced'));Output:
    PLAN_TABLE_OUTPUT
    Plan hash value: 47235625
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   1 |  HASH GROUP BY     |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   2 |   TABLE ACCESS FULL| T    | 10000 | 30000 |   159   (1)| 00:00:02 |
    Query Block Name / Object Alias (identified by operation id):
       1 - SEL$1
       2 - SEL$1 / T@SEL$1
    Outline Data
      /*+
          BEGIN_OUTLINE_DATA
          FULL(@"SEL$1" "T"@"SEL$1")
          OUTLINE_LEAF(@"SEL$1")
          ALL_ROWS
          OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
          IGNORE_OPTIM_EMBEDDED_HINTS
          END_OUTLINE_DATA
    Column Projection Information (identified by operation id):
       1 - (#keys=1) "ID"[NUMBER,22]
       2 - "ID"[NUMBER,22]
    34 rows selected.
    SQL>
    Explained.
    SQL>
    PLAN_TABLE_OUTPUT
    Plan hash value: 47235625
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   1 |  HASH GROUP BY     |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   2 |   TABLE ACCESS FULL| T    | 10000 | 30000 |   159   (1)| 00:00:02 |
    Query Block Name / Object Alias (identified by operation id):
       1 - SEL$1
       2 - SEL$1 / T@SEL$1
    Outline Data
      /*+
          BEGIN_OUTLINE_DATA
          FULL(@"SEL$1" "T"@"SEL$1")
          OUTLINE_LEAF(@"SEL$1")
          ALL_ROWS
          OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
          IGNORE_OPTIM_EMBEDDED_HINTS
          END_OUTLINE_DATA
    Column Projection Information (identified by operation id):
       1 - (#keys=1) "TEST_FNC"("ID")[22]
       2 - "ID"[NUMBER,22]
    34 rows selected.
    SQL>
    Explained.
    SQL> select * from table(dbms_xplan.display(null,null,'advanced'));
    PLAN_TABLE_OUTPUT
    Plan hash value: 47235625
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   1 |  HASH GROUP BY     |      |    10 |    30 |   162   (3)| 00:00:02 |
    |   2 |   TABLE ACCESS FULL| T    | 10000 | 30000 |   159   (1)| 00:00:02 |
    Query Block Name / Object Alias (identified by operation id):
       1 - SEL$F5BB74E1
       2 - SEL$F5BB74E1 / T@SEL$2
    Outline Data
      /*+
          BEGIN_OUTLINE_DATA
          FULL(@"SEL$F5BB74E1" "T"@"SEL$2")
          OUTLINE(@"SEL$2")
          OUTLINE(@"SEL$1")
          MERGE(@"SEL$2")
          OUTLINE_LEAF(@"SEL$F5BB74E1")
          ALL_ROWS
          OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
          IGNORE_OPTIM_EMBEDDED_HINTS
          END_OUTLINE_DATA
    Column Projection Information (identified by operation id):
       1 - (#keys=1) "ID"[NUMBER,22]
       2 - "ID"[NUMBER,22]
    37 rows selected.

  • Adding custom SQL in ReadAllQuery on hierarchy fails (11.1.1.0.1)

    Hello,
    We are encountering a problem with Toplink 11.1.1.0.1 when adding a custom sql statement within a ReadAllQuery on a parent class. The same code with the same descriptor works fine with 10.1.3.3 and 9.0.4.7.
         ReadAllQuery query = new ReadAllQuery(Person.class);
         ExpressionBuilder b = query.getExpressionBuilder();
         query.addArgument("instId", Integer.class);
         ReportQuery subQuery = new ReportQuery();
         subQuery.setReferenceClass(Person.class); // dummy mapped class...
         SQLCall selectIdsCall = new SQLCall();
         String subSelect = "select inst.ID from PERSON inst where inst.ID = #instId"; // <= re-use bind variable in child query
         selectIdsCall.setSQLString(subSelect);
         subQuery.setCall(selectIdsCall);
         Expression expr = b.get("id").in(subQuery);
         query.setSelectionCriteria(expr);
         Vector params = new Vector(1);
         params.add(new Integer(1));
         List res = (List) session.executeQuery(query, params);
    SQL statements generated by Toplink 11.1.1.0.1_
    SELECT DISTINCT t0.OBJECTTYPE_ID FROM PERSON t0
    WHERE t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t0.TITI_ID, t1.ID, t1.BONUS_ID
    FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = NULL))
    SQL statements generated by Toplink 10.1.3.3 and 9.0.4.7_
    SELECT DISTINCT t0.OBJECTTYPE_ID FROM PERSON t0
    WHERE t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t0.TITI_ID, t1.ID, t1.BONUS_ID
    FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = 'EM'))It looks like the arguments are shifted. You can see it when using bind variables in 11.1.1.0.1
    Exception [TOPLINK-4002] (Oracle TopLink - 11g (11.1.1.0.1) (Build 081030)): oracle.toplink.exceptio
    ns.DatabaseException
    Internal Exception: java.sql.SQLException: Invalid column index
    Error Code: 17003
    Call: SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t
    0.TITI_ID, t1.ID, t1.BONUS_ID FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERS
    ON inst where inst.ID = ?) AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = ?))
            bind => [1, null, EM]Has anyone already encountered this problem ?

    Hello,
    We are encountering a problem with Toplink 11.1.1.0.1 when adding a custom sql statement within a ReadAllQuery on a parent class. The same code with the same descriptor works fine with 10.1.3.3 and 9.0.4.7.
         ReadAllQuery query = new ReadAllQuery(Person.class);
         ExpressionBuilder b = query.getExpressionBuilder();
         query.addArgument("instId", Integer.class);
         ReportQuery subQuery = new ReportQuery();
         subQuery.setReferenceClass(Person.class); // dummy mapped class...
         SQLCall selectIdsCall = new SQLCall();
         String subSelect = "select inst.ID from PERSON inst where inst.ID = #instId"; // <= re-use bind variable in child query
         selectIdsCall.setSQLString(subSelect);
         subQuery.setCall(selectIdsCall);
         Expression expr = b.get("id").in(subQuery);
         query.setSelectionCriteria(expr);
         Vector params = new Vector(1);
         params.add(new Integer(1));
         List res = (List) session.executeQuery(query, params);
    SQL statements generated by Toplink 11.1.1.0.1_
    SELECT DISTINCT t0.OBJECTTYPE_ID FROM PERSON t0
    WHERE t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t0.TITI_ID, t1.ID, t1.BONUS_ID
    FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = NULL))
    SQL statements generated by Toplink 10.1.3.3 and 9.0.4.7_
    SELECT DISTINCT t0.OBJECTTYPE_ID FROM PERSON t0
    WHERE t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t0.TITI_ID, t1.ID, t1.BONUS_ID
    FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERSON inst where inst.ID = 1)
    AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = 'EM'))It looks like the arguments are shifted. You can see it when using bind variables in 11.1.1.0.1
    Exception [TOPLINK-4002] (Oracle TopLink - 11g (11.1.1.0.1) (Build 081030)): oracle.toplink.exceptio
    ns.DatabaseException
    Internal Exception: java.sql.SQLException: Invalid column index
    Error Code: 17003
    Call: SELECT t0.ID, t0.OBJECTTYPE_ID, t0.GENDER, t0.AGE, t0.FIRSTNAME, t0.LASTNAME, t0.ADDRESS_ID, t
    0.TITI_ID, t1.ID, t1.BONUS_ID FROM PERSON t0, EMPLOYEE t1 WHERE ((t0.ID IN (select inst.ID from PERS
    ON inst where inst.ID = ?) AND (t1.ID = t0.ID)) AND (t0.OBJECTTYPE_ID = ?))
            bind => [1, null, EM]Has anyone already encountered this problem ?

  • PL/SQL CLOB and comma seperated list

    Hi,
    i´am beginner!
    I have a table with a clob field with a comma separeted list. The content can be '', '44' or '44,55...' as an example.
    So how can i get the values in clob and search another table?
    Something like...
    select clob from table1
    each clob
    select * from table2
    where table2.id = (clob value)
    ... do somtheing further
    Thank you,
    Jochen

    Ok... it depends...
    If you know your CLOB is going to hold a list of values that are less than 4000 characters, you can simply treat the CLOB as a VARCHAR2 and perform one of the many techniques for splitting that string to give a varying IN list...
    e.g.
    SQL> ed
    Wrote file afiedt.buf
      1  select *
      2  from emp
      3  where ename in (
      4    with t as (select '&input_string' as txt from dual)
      5    select REGEXP_SUBSTR (txt, '[^,]+', 1, level)
      6    from t
      7    connect by level <= length(regexp_replace(txt,'[^,]*'))+1
      8*   )
    SQL> /
    Enter value for input_string: SCOTT,JAMES
    old   4:   with t as (select '&input_string' as txt from dual)
    new   4:   with t as (select 'SCOTT,JAMES' as txt from dual)
         EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
          7788 SCOTT      ANALYST         7566 19-04-1987 00:00:00       3000                    20
          7900 JAMES      CLERK           7698 03-12-1981 00:00:00        950                    30
    SQL>(or alternatively read here: http://tkyte.blogspot.com/2006/06/varying-in-lists.html)
    If it's going to exceed the SQL VARCHAR2 limit of 4000 characters then you would most likely need to create a Pipelined function to split your CLOB into it's component values and return each one, thus allowing you to treat the results as a table of their own... e.g.
    Note: this example is for a pipelined function that splits a varchar2 string, but you could adapt it to use the DBMS_LOB package to split a CLOB in the same manner...
    SQL> CREATE OR REPLACE TYPE split_tbl IS TABLE OF VARCHAR2(4000);
      2  /
    Type created.
    SQL> CREATE OR REPLACE FUNCTION split (p_list VARCHAR2, p_delim VARCHAR2:=' ') RETURN SPLIT_TBL PIPELINED IS
      2      l_idx    PLS_INTEGER;
      3      l_list   VARCHAR2(4000) := p_list;
      4      l_value  VARCHAR2(4000);
      5    BEGIN
      6      LOOP
      7        l_idx := INSTR(l_list, p_delim);
      8        IF l_idx > 0 THEN
      9          PIPE ROW(SUBSTR(l_list, 1, l_idx-1));
    10          l_list := SUBSTR(l_list, l_idx+LENGTH(p_delim));
    11        ELSE
    12          PIPE ROW(l_list);
    13          EXIT;
    14        END IF;
    15      END LOOP;
    16      RETURN;
    17    END SPLIT;
    18  /
    Function created.
    SQL> SELECT column_value
      2  FROM TABLE(split('FRED,JIM,BOB,TED,MARK',','));
    COLUMN_VALUE
    FRED
    JIM
    BOB
    TED
    MARK
    SQL> create table mytable (val VARCHAR2(20));
    Table created.
    SQL> insert into mytable
      2  select column_value
      3  from TABLE(split('FRED,JIM,BOB,TED,MARK',','));
    5 rows created.
    SQL> select * from mytable;
    VAL
    FRED
    JIM
    BOB
    TED
    MARK
    SQL>... and once you can treat the values like a table it's just a case of using it like you would any table of values i.e. join on it or use it in an IN statment with a subselect etc.

  • Group by with a subselect?

    I have a problem when trying to group by the results of a subselect. I keep getting the error ORA-00979: not a GROUP BY expression, though I can't see the problem with the SQL.
    I want to count the number of rows in a table having / not having at least one row in another table.
    The query is equivalent to:
    select c1, count(*) from
    (select case when exists
    (select * from dual t2
    where t1.dummy=t2.dummy)
    then 'Y' else 'N' end c1
    from dual t1) t
    group by c1
    This fails on every version of Oracle I've tried, and I get the same error with:
    select c1, count(*) from
    (select case when t1.dummy in
    (select t2.dummy from dual t2)
    then 'Y' else 'N' end c1
    from dual t1) t
    group by c1
    Is this a fault with the SQL, or with Oracle?
    Thanks in advance,
    Rex

    On 9.2.0.5:
    ora9205>select c1, count(*)
      2    from (select case
      3                 when exists
      4                        (select * from dual t2
      5                          where t1.dummy = t2.dummy)
      6                   then 'Y' else 'N'
      7                 end c1
      8           from dual t1) t
      9   group by c1;
    C  COUNT(*)
    Y         1
    1 row selected.
    -- Two approaches with the DEPT and EMP tables
    ora9205>select c1, count(*)
      2    from (select case
      3                 when exists
      4                        (select null
      5                           from emp e
      6                          where e.deptno = d.deptno)
      7                   then 'Y' else 'N'
      8                 end c1
      9            from dept d)
    10   group by c1;
    C  COUNT(*)
    N         2
    Y         3
    2 rows selected.
    ora9205>select 'Y', count(*)
      2    from dept d
      3   where exists (select null
      4                   from emp e
      5                  where e.deptno = d.deptno)
      6  union all
      7  select 'N', count(*)
      8    from dept d
      9   where not exists (select null
    10                       from emp e
    11                      where e.deptno = d.deptno);
    '  COUNT(*)
    Y         3
    N         2
    2 rows selected.

  • Compilation problems using NVL function in Pro*C subselect

    I have come across a weird oracle problem. When I execute the following query in SQLPlus it works but when
    I include it in Pro*C code in a EXEC SQL statement it gives syntax errors and fails to compile. Any idea what I am doing wrong.
    SELECT DISTINCT
         A.ID_PERSON,
         C.ID_STAGE_PERSON_LINK ,
         A.NM_PERSON_FULL,
         A.NBR_PERSON_AGE,
         A.ADDR_PERSON_ST_LN_1,
         A.ADDR_PERSON_CITY,
         A.ADDR_PERSON_ZIP,
         A.CD_PERSON_STATE,
         A.CD_PERSON_COUNTY,
         A.NBR_PERSON_PHONE,
         C.CD_STAGE_PERS_REL_INT
         FROM
              PERSON A,
              STAGE_PERSON_LINK C
         WHERE
         C.ID_CASE = 88776721
         AND          A.IND_INVALID_PERS IS NULL
         AND          C.CD_STAGE_PERS_TYPE = 'PRN'
         AND          C.ID_PERSON = A.ID_PERSON
         AND C.ID_STAGE_PERSON_LINK =
    NVL (
                   (SELECT MAX(F.ID_STAGE_PERSON_LINK)
                   FROM STAGE_PERSON_LINK F
                   WHERE F.ID_PERSON=C.ID_PERSON
                   AND F.ID_CASE = C.ID_CASE
                        AND F.CD_STAGE_PERS_TYPE = 'PRN'
                        AND F.CD_STAGE_PERS_REL_INT IS NOT NULL)
                   (SELECT MAX(G.ID_STAGE_PERSON_LINK)
                   FROM STAGE_PERSON_LINK G
                   WHERE G.ID_PERSON=C.ID_PERSON
                   AND G.ID_CASE = C.ID_CASE
                        AND G.CD_STAGE_PERS_TYPE = 'PRN')
    AND A.ID_PERSON NOT IN
    SELECT S.ID_PERSON
    FROM STAGE_PERSON_LINK S,STAGE T
    WHERE S.ID_CASE = C.ID_CASE
    AND S.ID_CASE = T.ID_CASE
    AND S.ID_STAGE = T.ID_STAGE
    AND T.CD_STAGE &lt;&gt; 'INT'
    MINUS
    SELECT H.ID_PERSON
    FROM STAGE_PERSON_LINK H, STAGE F
    WHERE H.ID_CASE = F.ID_CASE
    AND H.ID_STAGE = F.ID_STAGE
    AND H.ID_CASE = C.ID_CASE
    AND H.CD_STAGE_PERS_ROLE &lt;&gt; 'XE'
    AND F.CD_STAGE &lt;&gt; 'INT'
    This query returns data when run in sqlplus.When used in a Pro*C C program and compiled the precompiler complains with syntax errors when used with EXEC SQL DECLARE CLSS82D_CURSOR CURSOR FOR &lt; query above &gt;.However removing the NVL function and retaining the subselect clause compiles but that is not what I want to do.
    Syntax error at line 262, column 20, file clss82d.pc:
    Error at line 262, column 20 in file clss82d.pc
    SELECT MAX( F.ID_STAGE_PERSON_LINK )
    ...................1
    PCC-S-02201, Encountered the symbol "MAX" when expecting one of the following:
    ( ) * + - / . @ | at, day, hour, minute, month, second, year,
    The symbol "(" was substituted for "MAX" to continue.
    Syntax error at line 263, column 10, file clss82d.pc:
    Error at line 263, column 10 in file clss82d.pc
    FROM STAGE_PERSON_LINK F
    .........1
    PCC-S-02201, Encountered the symbol "FROM" when expecting one of the following:
    , ) * + - / | at, day, hour, minute, month, second, year,

    Pro*C works bit differently tha sqlplus. try removing the blank line after
    SELECT MAX(G.ID_STAGE_PERSON_LINK)
    FROM STAGE_PERSON_LINK G
    WHERE G.ID_PERSON=C.ID_PERSON
    AND G.ID_CASE = C.ID_CASE
    AND G.CD_STAGE_PERS_TYPE = 'PRN')
    good luck,
    Gauranga

  • "SQL Query in HTTP Request" (5474:0)

    Hi,
    The IDS signature "SQL Query in HTTP Request" (5474:0) does not recognize all malicious SQL selects. Currently, the reg exp looks like [%]20|[=]|[+])[Ss][Ee][Ll][Ee][Cc][Tt]([%]20|[+])[^\r\n\x00-\x19\x7F-\xFF]+([%]20|[+])[Ff][Rr][Oo][Mm]([%]20|[+] . We noticed that subselects does not trigger the signature. For example, "...(select%20something%20from%20somethingmore%20where%20variable%20=%20(select%20....." which could be malicious. Is there any possibility to include "(" in the regexp to detect subselects?
    Regards,
    /Ola

    hmmm...That should actually match just fine. Let's break it down:
    ([%]20|[=]|[+]) <--"%20","=",or "+"
    [Ss][Ee][Ll][Ee][Cc][Tt] <-- "SELECT"
    ([%]20|[+]) <--"%20" or "+"
    [^\r\n\x00-\x19\x7F-\xFF]+ <-- NOT one or more ascii control or extended chars
    ([%]20|[+]) <-- "%20" or "+"
    [Ff][Rr][Oo][Mm] <-- "FROM"
    ([%]20|[+]) <-- "%20" or "+"
    The only reason I can think that it wouldn't match is if there some funky characters between the first SELECT and the first FROM (i.e. carriage return/line feed, etc). Also remember that a %20 or = or + must precede the SELECT and that a %20 or + must follow the FROM.

  • Using the result of a function, inside a subselect

    Hi!
    I´m wondering if it´s possible to use the result of a function inside a subselect. Let me give you an example of what I´m trying to do here:
    select * from t_node where node_pk in (get_node_parents_pk(22345));
    The function get_node_parents_pk stands in for the following SELECT-statment:
    select node_pk from t_node_child where parent_node_pk = 12345
    The statement above would return something like this: 12435,23423,23453,23452
    These values represent the node_pk value for the parent nodes.
    I want the get_node_parents_pk function to return a result set similar to this so that I might call it inside the IN ( ) statement.
    Any clue? =)

    I created a collection type in the database:
    CREATE OR REPLACE TYPE nodes_pk_arr IS TABLE OF INTEGER;
    The function get_node_parents_pk () is made to return the collection type above. However, this does not work. I get the following error message:
    SELECT *
    FROM t_node
    WHERE node_pk IN
    (SELECT * FROM TABLE (get_node_parents_pk (22345)));
    ORA-22905: cannot access rows from a non-nested table item
    However, if I insert a nodes_pk_arr collection directly into the SQL-statement, like I do below, it works:
    SELECT *
    FROM t_node
    WHERE node_pk IN
    (SELECT * FROM TABLE (nodes_pk_arr(24564,23545,34523));
    So, when returning the collection from the function I´m told that the collection is not a nested table, when in fact it is. What gives?
    Also, is there no way to return a result set directly from the get_node_parents_pk() function, making it possible to write the statement like that shown below?
    SELECT *
    FROM t_node
    WHERE node_pk IN (get_node_parents_pk (22345));
    Your reply is much appreciated!
    Kind regards
    Robert

  • Subselect in update

    Hello,
    i want to write an sql-update statement where a field through a part of another field will be supplemented.
    example:
    update tabelle set targetDirectiory = ' export/home/VALUE_FROM_FIELD x' where blablabla
    This should work as a subselect ?but I do not know how i can merge the strings
    Thanks a lot.
    Lutz

    It could have been better if you would have provided some supporting data. Anyway
    You can do it like
    UPDATE emp       e
       SET dept_name = 'DEPT-'||(SELECT d.dept_name
                                   FROM dept          d
                                  WHERE d.dept_id     = e.dept_id
    WHERE blahblahblah;Regards
    Arun

  • SQL statement using result of aggregate min function to fetch a row - how?

    Need help trying to get to something seemingly simple. I'll provide a simple example to illustrate the problem.
    I'll be using a simple addresses table with 4 fields.
    Create the table:
      CREATE TABLE "ADDRESSES"
       (     "OWNER_NAME" VARCHAR2(20 BYTE),
         "STREET_NAME" VARCHAR2(20 BYTE),
         "STREET_NUMBER" NUMBER
       ) ;populate with 6 rows
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('FRED','MAIN',1);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JOAN','MAIN',2);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JEAN','MAIN',3);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JACK','ELM',1);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JANE','ELM',2);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JEFF','ELM',3);We now have this:
    Select * from addresses
    OWNER_NAME           STREET_NAME          STREET_NUMBER         
    FRED                 MAIN                 1                     
    JOAN                 MAIN                 2                     
    JEAN                 MAIN                 3                     
    JACK                 ELM                  1                     
    JANE                 ELM                  2                     
    JEFF                 ELM                  3                     
    6 rows selectedNow i wish to group by StreetName, and get a count of houses. At the same time, i'd like to know the first and last house number
        select
        street_name,
        count(*) "NBR HOUSES",
        min(street_number) "First Number",
        max(street_number) "Last Number"
         from addresses
        group by street_name
    produces
    STREET_NAME          NBR HOUSES             First Number           Last Number           
    ELM                  3                      1                      3                     
    MAIN                 3                      1                      3                     
    2 rows selectedExcellent. Now for the problem. I wish to also list on each line, the owner that lives at the first and/or last house number. Note again, assume that house number and street name is unique
    It would seem i have all that i need. Not sure how to get at it.
    I tried:
    select
        street_name,
        count(*) "NBR HOUSES",
        min(street_number) "First Number",
        max(street_number) "Last Number",
        (Select b.owner_name from addresses b where b.street_number = min(street_number) and b.owner_name = owner_name) "First Owner"
         from addresses
        group by street_nameBut get a sql syntax error, group function not allowed when i add the subselect.
    any ideas?
    thanks for any help.
    Edited by: user6876601 on Nov 19, 2009 7:08 PM
    Edited by: user6876601 on Nov 19, 2009 7:30 PM

    Hi,
    Welcome to the forum!
    Getting the highest and lowest number for each street is a fairly simple concept; simpler to describe, and simple to code.
    Now you want the owner_name associated with the highest and lowest number, which is a more complicated concept; a little harder to describe, and, unfortunately, much less simple to code, and much, much harder to explain:
    select
        street_name,
        count (*)                "NBR HOUSES",
        min (street_number)      "First Number",
        min (owner_name) KEEP (DENSE_RANK FIRST ORDER BY street_number)
                        "First Owner",
        max (street_number)      "Last Number",
        min (owner_name) KEEP (DENSE_RANK LAST ORDER BY street_number)
                        "Last Owner"
         from addresses
        group by street_name
    ;Notice that I used min for both "First Owner" and "Last Owner". Why is that?
    The important keyword in these funtions is the word FIRST or LAST that comes after DENSE_RANK and before ORDER BY. The function at the beginning is merely a tie-breaker.
    That is, MIN in this context only refers to what should happen when there is a tie for the first or last in the group. Even if such a thing is impossibe in your data, the generic functions have to have some mechanism for returning a single owner_name when two or more rows have an equal claim to having the highest street_number. For example, if we change Joan's address to 1 Main, then MIN (street_number) is still 1, obviously, but who is the person associated with the minimum street_number: is it Fred or Joan? Both have an equal claim to being the owner with the lowest address on Main Street, but aggregate functions must return a single value, so we have to have some mechanism for tell the system whether to return 'JOAN' or 'FRED'. In this example, I arbitrarily said that in the een of a tie, the lowest name, in alphabetic order, should be returned. In this case, 'FRED' would be returned, since 'FRED' is earlier than 'JOAN' .
    Thanks for including the CREATE TABLE and INSERT statements!

Maybe you are looking for

  • Installing Multiple Operating Systems with grub and Arch Linux

    NOTE: Please keep in mind that there are many different ways to achieve this same result using various loop and ramdisk methods, read this with a separate window to jot down your comments and suggestions... this is ongoing for me so any help would be

  • Curve 3G/9300 no longer connects to Nokia CK-7W Handsfree set

    I've just updated to OS6 and my BB Curve 9300 no longer connects to the bluetooth handsfree set in my car (Nokia CK-7W). No problems before the update. Presumably this will be a software issue rather than hardware as everything else still connects wi

  • That little blue question mark

    I place a hyperlink to 'sending an email' and publish. On the published site a small blue question mark appears however the link is active. Why doesn't the email address show up as on the page in iWeb? Any ideas?

  • Verizion says Finders Keepers

    I'm on my 3rd Droid in less than 1 year. I guess my memory isn't as good as some because when the 3rd phone came I thought I knew the drill: They send you just the phone so you need your battery and back cover. Then you send the defective phone back

  • How  to align buttons using ActionScript in Flex

    Hi all, I'm pretty new to Flex and ActionScript but I've created an myAddForm() function in an actionscript class but I can't align the buttons - I've been looking at using a buttonbar but can't figure out how to convert the code in to actionscript f