Inline select statement and SQL optimizatino

Hi everyone,
I am trying to optimze a script but can't get the fulle explainplan in PL/SQL.
The problem is that the select statements in de column defenition is not explained. below are the 2 scripts I want to compare:
SQL1:
Select
z.title
, (select name from members where id =z.id) as name
, z.id
from job z
SQL2
Select
z.title
, d.name
, z.id
from job z
left outer join members d on z.id=d.id
My question is: what is the effect on performance and cost of the 'inline select' statement of name in SQL1
hope to hear form you soon
Harm
Edited by: HALI on 25-nov-2010 1:14

In respons to your question below is the output:
I altered the used names, tablenames etc. according to our privacy pollacy.
A far as I can see the inline statement is not traced.
The query with ansi-join:
xplain plan for
select
  id as Interne
, mv.ie_id as Act
, 'H_W' as Rl
from testing i
left outer join resutino m on i.hand=m.id
   left outer join vert mv on m.voor || case when m.voeg is not null then ' '|| m.voeg end ||' '||m.naam = mv.source and mv.field = 'employee'
explain plan succeeded.
select * from table(dbms_xplan.display)
PLAN_TABLE_OUTPUT                                                                                                                                                                                       
| Id  | Operation            |  Name               | Rows  | Bytes | Cost  |                                                                                                                            
|   0 | SELECT STATEMENT     |                     |   684 | 47880 |    19 |                                                                                                                            
|   1 |  HASH JOIN OUTER     |                     |   684 | 47880 |    19 |                                                                                                                            
|   2 |   HASH JOIN OUTER    |                     |   684 | 22572 |    15 |                                                                                                                            
|   3 |    TABLE ACCESS FULL | testing             |   684 |  5472 |     7 |                                                                                                                            
|   4 |    TABLE ACCESS FULL | resutino            |   308 |  7700 |     7 |                                                                                                                            
|   5 |   TABLE ACCESS FULL  | VERT                |   166 |  6142 |     3 |                                                                                                                            
Note: cpu costing is off, 'PLAN_TABLE' is old version                                                                                                                                                   
13 rows selected
The inline select query:
xplain plan for
SELECT
case when (select ie_id  from vert xov where xov.field = 'field' and source in
          (select m.voor || case when m.voeg is not null then ' '|| m.voegend ||' '||m.naam from resultino m where i.hand= m.id)) is not null then
          'X'||(select ie_id  from vert xov where xov.field = 'field' and source in
          (select m.voor || case when m.voeg is not null then ' '|| m.voegend ||' '||m.naam from resultino m where i.hand= m.id))
     else 'X' || (select ie_id from vert xov where xov.source = 'none' and xov.veld = 'employee')
end                                                    as  Act,
'ADM' as  Rol,
i.id as  Interne
FROM testing i
explain plan succeeded.
select * from table(dbms_xplan.display)
PLAN_TABLE_OUTPUT                                                                                                                                                                                       
| Id  | Operation            |  Name         | Rows  | Bytes | Cost  |                                                                                                                                  
|   0 | SELECT STATEMENT     |               |   684 |  5472 |     7 |                                                                                                                                  
|   1 |  TABLE ACCESS FULL   | testing       |   684 |  5472 |     7 |                                                                                                                                  
Note: cpu costing is off, 'PLAN_TABLE' is old version                                                                                                                                                   
9 rows selected

Similar Messages

  • Bind Variable in SELECT statement and get the value  in PL/SQL block

    Hi All,
    I would like  pass bind variable in SELECT statement and get the value of the column in Dynamic SQL
    Please seee below
    I want to get the below value
    Expected result:
    select  distinct empno ,pr.dept   from emp pr, dept ps where   ps.dept like '%IT'  and pr.empno =100
    100, HR
    select  distinct ename ,pr.dept   from emp pr, dept ps where   ps.dept like '%IT'  and pr.empno =100
    TEST, HR
    select  distinct loc ,pr.dept   from emp pr, dept ps where   ps.dept like '%IT'  and pr.empno =100
    NYC, HR
    Using the below block I am getting column names only not the value of the column. I need to pass that value(TEST,NYC..) into l_col_val variable
    Please suggest
    ----- TABLE LIST
    CREATE TABLE EMP(
    EMPNO NUMBER,
    ENAME VARCHAR2(255),
    DEPT VARCHAR2(255),
    LOC    VARCHAR2(255)
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (100,'TEST','HR','NYC');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (200,'TEST1','IT','NYC');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (300,'TEST2','MR','NYC');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (400,'TEST3','HR','DTR');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (500,'TEST4','HR','DAL');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (600,'TEST5','IT','ATL');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (700,'TEST6','IT','BOS');
    INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (800,'TEST7','HR','NYC');
    COMMIT;
    CREATE TABLE COLUMNAMES(
    COLUMNAME VARCHAR2(255)
    INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('EMPNO');
    INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('ENAME');
    INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('DEPT');
    INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('LOC');
    COMMIT;
    CREATE TABLE DEPT(
    DEPT VARCHAR2(255),
    DNAME VARCHAR2(255)
    INSERT INTO DEPT(DEPT,DNAME) VALUES ('IT','INFORMATION TECH');
    INSERT INTO DEPT(DEPT,DNAME) VALUES ('HR','HUMAN RESOURCE');
    INSERT INTO DEPT(DEPT,DNAME) VALUES ('MR','MARKETING');
    INSERT INTO DEPT(DEPT,DNAME) VALUES ('IT','INFORMATION TECH');
    COMMIT;
    PL/SQL BLOCK
    DECLARE
      TYPE EMPCurTyp  IS REF CURSOR;
      v_EMP_cursor    EMPCurTyp;
      l_col_val           EMP.ENAME%type;
      l_ENAME_val       EMP.ENAME%type;
    l_col_ddl varchar2(4000);
    l_col_name varchar2(60);
    l_tab_name varchar2(60);
    l_empno number ;
    b_l_col_name VARCHAR2(255);
    b_l_empno NUMBER;
    begin
    for rec00 in (
    select EMPNO aa from  EMP
    loop
    l_empno := rec00.aa;
    for rec in (select COLUMNAME as column_name  from  columnames
    loop
    l_col_name := rec.column_name;
    begin
      l_col_val :=null;
       l_col_ddl := 'select  distinct :b_l_col_name ,pr.dept ' ||'  from emp pr, dept ps where   ps.dept like ''%IT'' '||' and pr.empno =:b_l_empno';
       dbms_output.put_line('DDL ...'||l_col_ddl);
       OPEN v_EMP_cursor FOR l_col_ddl USING l_col_name, l_empno;
    LOOP
        l_col_val :=null;
        FETCH v_EMP_cursor INTO l_col_val,l_ename_val;
        EXIT WHEN v_EMP_cursor%NOTFOUND;
          dbms_output.put_line('l_col_name='||l_col_name ||'  empno ='||l_empno);
       END LOOP;
    CLOSE v_EMP_cursor;
    END;
    END LOOP;
    END LOOP;
    END;

    user1758353 wrote:
    Thanks Billy, Would you be able to suggest any other faster method to load the data into table. Thanks,
    As Mark responded - it all depends on the actual data to load, structure and source/origin. On my busiest database, I am loading on average 30,000 rows every second from data in external files.
    However, the data structures are just that - structured. Logical.
    Having a data structure with 100's of fields (columns in a SQL table), raise all kinds of questions about how sane that structure is, and what impact it will have on a physical data model implementation.
    There is a gross misunderstanding by many when it comes to performance and scalability. The prime factor that determines performance is not how well you code, what tools/language you use, the h/w your c ode runs on, or anything like that. The prime factor that determines perform is the design of the data model - as it determines the complexity/ease to use the data model, and the amount of I/O (the slowest of all db operations) needed to effectively use the data model.

  • Concat java variable to a MySql select statement and exeucte

    Hi,
    I am trying to append a variable to a MySql select statement.
    Overview: I need to retrieve data from a MySql database with a java variable as a reference and select the data in the database based on that variable.
    CODE THAT I CURRENTLY HAVE:
    // Declare variables
    Connection conn = null;
    Statement st = null;
    Resultset rs2 = null;
    String st2 = null;
    String keyid = null;
    // Connect to database
    try {
          Class.forName("org.gjt.mm.mysql.Driver").newInstance();
          conn = DriverManager.getConnection("jdbc:mysql://" + mysql_host + ":3306/" + mysql_database, mysql_login, mysql_password);
          st = conn.createStatement();
          // Select data in Database with hanging equal sign
          st2 = ("SELECT * FROM table WHERE keyid= ");
          // Append keyid to hanging equal sign of select statement
          rs2 = st.executeQuery(st2 + keyid);
    }This is not working when I try to display the data.

    What is not working about it? Is there an error message? Stack Trace?
    Where do you get the value of keyId from?
    I would suggest that you use a prepared statement rather than building up a sql string like this. It prevents sql injection attacks
    // Declare variables
    Connection conn = null;
    PreparedStatement stmt = null;
    Resultset rs2 = null;
    String sql= null;
    String keyid = null;
    // Connect to database
    try {
          Class.forName("org.gjt.mm.mysql.Driver").newInstance();
          conn = DriverManager.getConnection("jdbc:mysql://" + mysql_host + ":3306/" + mysql_database, mysql_login, mysql_password);
          // Select data in Database with place holder for parameter
          sql = "SELECT * FROM table WHERE keyid= ?";
           // prepare the statement
          stmt = conn.prepareStatement(sql);
          // set the value of key id to use with the query
          stmt.setString(1, keyId);
          // run the query
          rs2 = st.executeQuery();
    catch (Exception e){
      System.out.println("An error occurred " + e.getMessage());
      e.printStackTrace();
    finally{
      if (rs2 != null) try { rs2.close(); } catch(SQLException ex){}
      if (stmt != null) try { stmt.close(); } catch(SQLException ex){}
      if (conn != null) try { con.close(); } catch(SQLException ex){}
    }

  • Long running select statement and v$session_longops

    Oracle Version: 10.2.0.4
    I've a long running sql query that takes the estimated 6 minutes to complete and return the result.
    While it's running I'd like to observe it into the view v$session_longops.
    I altered the session that runs the query with
      ALTER SESSION SET timed_statistics=TRUE;The tables it queries have gathered statistics on them.
    However I don't see any rows in the view v$session_longops for the respective SID and serial#. Why is that? What am I missing?
    Thank you!

    Hi,
    Now I understand what you all meant by "loops" here .. Yes, the query does nested loops as one can see from the execution plan. So it could be the reason
    SELECT STATEMENT, GOAL = ALL_ROWS                                  
    SORT GROUP BY                                                             
      CONCATENATION                              
       TABLE ACCESS BY LOCAL INDEX ROWID     TABLE_1
        NESTED LOOPS                                                   
         NESTED LOOPS
          TABLE ACCESS BY GLOBAL INDEX ROWID     TABLE_2      
           INDEX RANGE SCAN                           IPK_t2_CDATE                               
          TABLE ACCESS BY INDEX ROWID     TABLE_3
           INDEX RANGE SCAN                     IPK_T3                            
         PARTITION RANGE ALL                                                 
          INDEX RANGE SCAN     IRGP_REGCODE                        
       TABLE ACCESS BY LOCAL INDEX ROWID     TABLE_1
        NESTED LOOPS                                                  
         NESTED LOOPS          
          TABLE ACCESS BY GLOBAL INDEX ROWID     TABLE_2     
           INDEX RANGE SCAN                       IPK_t2_STATUS          
          TABLE ACCESS BY INDEX ROWID     TABLE_3     
           INDEX RANGE SCAN                       IPK_T3
         PARTITION RANGE SINGLE               
          INDEX RANGE SCAN                     IRGP_REGCODE          

  • Select Statement (pl/sql) in ADF

    Hi,
    I am new in ADF.
    Please give any idea or sample code about how to write Select Statement in ADF and how can i catch value.
    Thanks

    Thanks for reply
    But i don't want to use View Object.
    Is there another way like below insert code
    public void insertTable() {
    //System.out.println("OK");
    DBTransaction trans = getDBTransaction();
    CallableStatement statement = null;
    String plsql =
    "DECLARE "
    + "PRAGMA AUTONOMOUS_TRANSACTION; "
    +"BEGIN "
    + "INSERT INTO test_check "
    + "(id,name) "
    + "VALUES (?,?); "
    + "COMMIT; "
    +"END;";
    statement = trans.createCallableStatement(plsql,DBTransaction.DEFAULT);
    try {
    statement.setInt(1,"001");
    statement.setString(2, "user10892984");
    int rows = statement.executeUpdate();
    } catch (SQLException e) {
    throw new JboException(e);
    } finally {
    try {
    if (statement != null)
    statement.close();
    } catch (SQLException e) {System.out.println("Not Insert.......");
    }

  • Usage of Xopen SQL states and SQL Exception?

    Hi
    Is there way to make full use of SQL Exceptions?
    Has anybody used sql states from sql exception?
    It is specified in the API reference that an sql exception object contains an xopen sql state which is a string. But the states in specs are defined as class, subclass.
    The question is how can i make use of these java strings to interpret what exactly happened at the database? Are they really useful? If they are, any utilities which converts these strings to a meaningful message? Any pointers on these question would also help me.
    Thanx in adv.
    Giridhar

    SQLException has inherited a method getMessage() which seems to be quite useful.
    For situations where you want to check on a specific one of several possible (or expected) states (like: maybe the table is not yet created ...), I think you can quite fine use getSQLState() and also getErorCode(). Try out in tests, which information is returned by which constellation, then you can use it for making decisions in your program logic.
    But be aware, that all these informations probably are DBMS specific!

  • In Oracle SQL, cannot use column in select statement and order by

    Hi,
    Is there a work around for this.
    Thanks in advance
    Pablo.

    Hi,
    943981 wrote:
    Hi All,
    This is the error I get:
    ORA-00960: ambiguous column naming in select list
    00960. 00000 - "ambiguous column naming in select list"
    *Cause:    A column name in the order-by list matches more than one select
    list columns.
    *Action:   Remove duplicate column naming in select list.
    Error at Line: 6 Column: 17That error message looks pretty clear to me. What don't you understand?
    Either
    (a) use aliases, so each column has a unique name, or
    (b) remove duplicate columns from the SELECT clause.
    Post your query. It's hard to say exactly what you're doing wrong when we don't know exactly what you're doing.
    For best results, post a complete test script (including CREATE TABLE and INSERT statements, if necessary) that people can to re-create the problem and test their ideas.
    See the forum FAQ {message:id=9360002}

  • How to processing the results from the select statement in SQL query?

    Hi
    This might be too simple, but my knowledge of the SQL is very limited...
    I have table where I do have details from calls (Lync QoE).
    I can take all calls from the table, but I would like to count the concurrent calls on the table. This is how I got it work on the Excel to work (but I would like to do that on the SQL statement to get it more dynamic use):
    Table have these line and this is what I get out from the Select):
    [callid],[start],[end]
    1ABC,1.1.2014 01:00:15, 1.1.2014 01:01:00
    5DEF,1.1.2014 01:00:45, 1.1.2014 01:05:00
    FDE2,1.1.2014 01:03:15, 1.1.2014 01:04:00
    KDJ8,1.1.2014 01:04:15, 1.1.2014 01:06:00
    FDJ8,2.1.2014 01:04:15, 2.1.2014 01:06:00
    KDSE,3.1.2014 01:04:15, 3.1.2014 01:06:00
    The information I would like to get, is what is the maximum amount of the concurrent calls per day.
    On the excel I basically count line by line how many concurrent calls each line have had, and then pickup the highest one. On above example the calls 5DEF, FDE2 and FDE2 have been active at the same time which gives 3 for the first day.
    The table is ordered by the start. So let say the code is on the third line (FDE2). I need to count calls from before which end time is after the start time (of FDE2), but also I need to count calls after (FDE2) which are started before the current
    call has ended.
    Petri

    Unfortunately your post is off topic as it's not specific to SQL Server Samples and Community Projects.  
    This is a standard response I’ve written in advance to help the many people who post their question in this forum in error, but please don’t ignore it.  The links I provide below will help you determine the right forum to ask your question in.
    For technical issues with Microsoft products that you would run into as an end user, please visit the Microsoft Answers forum ( http://answers.microsoft.com ) which has sections for Windows, Hotmail,
    Office, IE, and other products.
    For Technical issues with Microsoft products that you might have as an IT professional (like technical installation issues, or other IT issues), please head to the TechNet Discussion forums at http://social.technet.microsoft.com/forums/en-us, and
    search for your product name.
    For issues with products you might have as a Developer (like how to talk to APIs, what version of software do what, or other developer issues), please head to the MSDN discussion forums at http://social.msdn.microsoft.com/forums/en-us, and
    search for your product or issue.
    If you’re asking a question particularly about one of the Microsoft Dynamics products, a great place to start is here: http://community.dynamics.com/
    If you think your issue is related to SQL Server Samples and Community Projects and I've flagged it as Off-topic, I apologise.  Please repost your question and include as much detail as possible about your problem so that someone can assist you further. 
    If you really have no idea where to post your question please visit the Where is the forum for…? forum http://social.msdn.microsoft.com/forums/en-us/whatforum/
    When you see answers and helpful posts, please click Vote As Helpful,
    Propose As Answer, and/or Mark As Answer
    Jeff Wharton
    MSysDev (C.Sturt), MDbDsgnMgt (C.Sturt), MCT, MCPD, MCSD, MCSA, MCITP, MCDBA
    Blog: Mr. Wharty's Ramblings
    Twitter: @Mr_Wharty
    MC ID:
    Microsoft Transcript

  • Discrepancy between Select Expert and SQL Query

    Greetings.  I am having an issue with a report, but I think it's more cosmetic and may not be causing a functional issue...
    When I go into the Report...Select Expert...Record, I see that my criteria for the report is .AND. logic.
    When I go into the SQL Query view, it shows .OR. logic...
    After I verify the database, the SQL query still does not get updated.  Saving and re-opening the report still does not update. 
    Is there any reason this will never match?  Thanks in advance.

    Sorry.  I am on Crystal 12.  Database is SQL 2005.
    I didn't think the detail mattered much, but the select expert shows:
    isnull({NONCONFORMANCE.CLOSED_DATE}) and
    not isnull({NONCONFORMANCE.PRODUCT_ID}) and
    not({NONCONFORMANCE.PRODUCT_ID}= '') and
    not({NONCONFORMANCE.PRODUCT_ID}= ' ')
    SELECT N.NCM_ID, N.NCM_DATE, N.PRODUCT_ID, N.CLOSED_DATE, N.ENTITY_ID
    FROM   NONCONFORMANCE N
    WHERE  N.CLOSED_DATE IS  NULL  AND N.PRODUCT_ID IS  NOT  NULL  AND  NOT (N.PRODUCT_ID='' OR N.PRODUCT_ID=' ') AND N.ENTITY_ID='CHI'
    Now that I look at how the SQL is generated (after cleaning up the statement), it's the negatives that got me.  I originally had a problem with the report that was pulling back blanks and spaces.  I made changes and I didn't pay close enough attention to what exactly changed in the SQL...  It appears to be the way the logic in the Select Expert is converted to SQL.
    I just need to start using Command more often and write my own SQL instead of using the Select Expert!!!

  • Oracle 11g stats and SQL plan mgt

    Oracle 11.0.1.7:
    - According to what I have read so far in the various documents it looks like when dbms gather stats run and if that results in new sql plan oracle will not automatically start using that plan until it's verified by sql tuning advisor or is evolved. Is that correct? Is that the default behaviour?
    - I just upgraded from 10g to 11g so I am not sure how stats is behaving currently. I am really concerned and want to understand how it's behaving.
    - How can I tell what's going on currently in the system in terms of stats gathering and if the new better plan is being used or not.

    You have the default setting for the two parameters in place. That means, that if SQL Plan Baselines exist, they will be used, thereby preventing new execution plans from getting used without evolvement
    optimizer_use_sql_plan_baselines=true does that.
    But by default, there are no SQL Plan Baselines as long as you don't create them - for example with the setting of
    optimizer_capture_sql_plan_baselines=trueYou can check whether SQL Plan Baselines exist with
    select * from dba_sql_plan_baselines;It should return no rows.

  • PL/SQL cursors vs. SQL*plus Select statement

    Hi folks, hope you're doing well,
    Here is a question that kept me wondering:
    Why would I use cursors when i can achieve the same thing with a SQL+ Select statement which is much easier to formulate than a cursor (e.g. you need no declaration, loops etc)?.
    Thanks so much,
    -a

    There is no such thing as a SQL*Plus SELECT statement. The SELECT command is part of the SQL Language - not part of the SQL*Plus (very limited small vocabulary) macro language.
    All SQL SELECTs (from client languages) winds up in the SQL Engine as SQL cursors. A SQL Cursor is basically the:
    - SQL source code
    - SQL "compiled" code (instructions on how to fetch the rows)
    On the client side, client cursors (not to be confused with SQL cursors) are used. A client cursor is created in the client language when it makes SQL calls via the database client driver (called the OCI/Oracle Call Interface for Oracle clients).
    Typically this is what a client does. It makes a connection to the database and gets a database handler in return. The database handler is the "communication channel" from the client to the db. In Oracle, the database handler in the client refers to the Oracle session (for that client) on db server.
    A SQL statement (source code) is used by the client. This can be a SELECT statement you type in at the SQL*Plus command line. It can be a SELECT statement for the PL/SQL cursor command in a stored procedure.
    The client creates a SQL handle for this SQL statement, by calling the Oracle client driver. Note that this SQL handle is a client handle - a client cursor for that SQL statement.
    E.g.
    a) sqlHandle = CreateSQL( databaseHandle, 'SELECT ... FROM ...')
    b) sqlHandle.Parse
    c) sqlHandle.Execute
    After the SQL handle (client cursor) has been executed, the client can fetch rows from it.
    This is what SQL*Plus does automatically for you, without you having to write the code to do it. SQL*Plus CONNECT command create a database connection handle. You enter a SELECT statement and SQL*Plus creates a SQL handle (client cursor), executes it, fetches from it, displays the rows, and closes the SQL handle when done.
    The same applies to PL/SQL. You can use a SELECT statement just like that in PL/SQL. E.g.
    declare
      i integer;
    begin
      select count(*) into i from emp where deptid = 123;
    end;This is called an implicit cursor. PL/SQL creates (just like SQL*Plus) an implicit client cursor. It creates and disposes of that client SQL handle for you - you do not need to do it.
    Or, you can create an explicit cursor. E.g. declare
      cursor c is select count(*) from emp where deptid = 123;
      i integer;
    begin
      open c;
      fetch c into i;
      close c;
    end;The question as to when to use implicit (client) cursors versus explicit (client) cursors depends on your requirements. Do you need to cycle through the results of the SQL? Etc.
    And keep in mind that in either case, the SQL Engine creates a SQL cursor anyway on its side.

  • SQL column as select statement to be referenced into a group by

    Is there a notation or solution to be able to reference a column that is a inline select statement within a group by as detailed below? The group by will not accept the alias. I also tried to make the SQL a MAX to remove the need for the group by reference and this returned invalid expression.
    SELECT DISTINCT hdr.BUSINESS_UNIT,
    hdr.SESSN_ID,
    hdr.STREAM_ROOT_ID,
    hdr.SESSN_STS_CD,
    hdr.SESSN_CRE_DTTM,
    CASE
    WHEN C.OPRID <> ' ' THEN C.OPRID
    ELSE S.OPERATOR
    END OPRID,
    strm.QS_APP_CONTEXT,
    RECV.QTY_SH_RECVD Quantity_Received,
    CASE
    WHEN hdr.BUSINESS_UNIT = 'MFG01' THEN MAX(G.MFDS_SGRP_SIZE)
    ELSE MAX(S.SESSN_SGRP_SIZE)
    END Quantity_Inspected,
    MAX(S.QS_VALUEREADING_1) Defect_Count,
    CASE
    WHEN MAX(S.QS_VALUEREADING_1) = 0 THEN ' '
    ELSE MAX(G.MFDS_NAME)
    END Characteristic,
    MAX(CMNT.QS_COMMENT2) COMMENTS,
    strm.INV_ITEM_ID,
    itm.DESCR,
    strm.WORK_CENTER_CODE,
    strm.VENDOR_ID,
    *(SELECT V.NAME1 FROM PS_VENDOR V WHERE strm.VENDOR_ID = V.VENDOR_ID AND V.SETID = (SELECT SETID FROM PS_SET_CNTRL_REC*
    WHERE  RECNAME = 'VENDOR'
    AND SETCNTRLVALUE = strm.BUSINESS_UNIT)) VENDOR_NAME,
    strm.PRDN_AREA_CODE,
    strm.COMPL_OP_SEQ,
    strm.PRODUCTION_TYPE,
    C.RECEIVER_ID,
    C.RECV_LN_NBR,
    RECV.PO_ID,
    RECV.LINE_NBR,
    RECV.SCHED_NBR,
    C.PRODUCTION_ID,
    C.SERIAL_ID,
    C.INV_LOT_ID
    FROM PS_QS_SESSN_HDR8 hdr
    LEFT OUTER JOIN PS_QS_SESSN_TRACE8 C
    ON hdr.BUSINESS_UNIT = C.BUSINESS_UNIT
    AND hdr.SESSN_ID = C.SESSN_ID
    LEFT OUTER JOIN PS_RECV_INSPDTL_VW RECV
    ON C.BUSINESS_UNIT = RECV.BUSINESS_UNIT
    AND C.RECEIVER_ID = RECV.RECEIVER_ID
    AND C.RECV_LN_NBR = RECV.RECV_LN_NBR
    LEFT OUTER JOIN PS_QS_STREAM_ROOT strm
    ON hdr.STREAM_ROOT_ID = strm.STREAM_ROOT_ID
    AND hdr.BUSINESS_UNIT = strm.BUSINESS_UNIT
    LEFT OUTER JOIN PS_QS_STREAM8_VW G
    ON strm.STREAM_ROOT_ID = G.STREAM_ROOT_ID
    AND strm.BUSINESS_UNIT = G.BUSINESS_UNIT
    LEFT OUTER JOIN PS_QS_SUBGROUP S
    ON hdr.BUSINESS_UNIT = S.BUSINESS_UNIT
    AND hdr.SESSN_ID = S.SESSN_ID
    AND S.STREAM_ID = G.STREAM_ID
    LEFT OUTER JOIN PS_QS_SESSN_COMM8 CMNT
    ON S.BUSINESS_UNIT = CMNT.BUSINESS_UNIT
    AND S.SESSN_ID = CMNT.SESSN_ID
    AND S.STREAM_ID = CMNT.STREAM_ID
    AND C.SAMPLE = CMNT.SAMPLE
    LEFT OUTER JOIN PS_MASTER_ITEM_TBL itm
    ON itm.INV_ITEM_ID = strm.INV_ITEM_ID
    LEFT OUTER JOIN PS_SET_CNTRL_REC cntrl
    ON itm.SETID = cntrl.SETID
    AND cntrl.RECNAME = 'MASTER_ITEM_TBL'
    AND cntrl.SETCNTRLVALUE = strm.BUSINESS_UNIT
    WHERE S.QS_VALUEREADING_1 = (SELECT MAX(S2.QS_VALUEREADING_1)
    FROM PS_QS_SUBGROUP S2
    WHERE S2.BUSINESS_UNIT = S.BUSINESS_UNIT
    AND S2.SESSN_ID = S.SESSN_ID
    AND S2.STREAM_ID = S.STREAM_ID)
    GROUP BY hdr.BUSINESS_UNIT,
    hdr.SESSN_ID,
    hdr.STREAM_ROOT_ID,
    hdr.SESSN_STS_CD,
    hdr.SESSN_CRE_DTTM,
    C.OPRID,
    S.OPERATOR,
    strm.QS_APP_CONTEXT,
    RECV.QTY_SH_RECVD,
    strm.INV_ITEM_ID,
    itm.DESCR,
    strm.WORK_CENTER_CODE,
    strm.VENDOR_ID,
    VENDOR_NAME,
    strm.PRDN_AREA_CODE,
    strm.COMPL_OP_SEQ,
    strm.PRODUCTION_TYPE,
    C.RECEIVER_ID,
    C.RECV_LN_NBR,
    RECV.PO_ID,
    RECV.LINE_NBR,
    RECV.SCHED_NBR,
    C.PRODUCTION_ID,
    C.SERIAL_ID,
    C.INV_LOT_ID

    Hi,
    Assign the alias in a sub-query. Then you'll be able to use it wherever you want to, and how many times you want to, in a super-query.
    For example:
    WITH     got_vendor     AS
         SELECT     hdr.business_unit
                  SELECT  v.name1
                  FROM    ps_vendor     v
                  WHERE   strm.vendor_id     = v.vendor_id
                  AND     v.setid          = (
                                                SELECT  setid
                                        FROM    ps_set_cntrl_rec
                                        WHERE   recname          = 'VENDOR'
                                        AND     setcntrlvalue      = strm.business_unit
              )           AS vendor_name
         FROM      ps_qs_sessn_hdr8     hdr
    SELECT       business_unit          -- NOTE: no hdr.; all columns are from got_vendor now
    ,       vendor
    FROM       got_vendor
    GROUP BY  business_unit
    ,       vendor
    ;When you define an alias (such as vendor) in a query, you can use that alias in the ORDER BY clause of that same query, but that's the only place in that same query where you can use it. If you want to use the alias anywhere else (e.g., in the GROUP BY clause, as in your example, the WHERE clause, or elsewhere in the SELECT clause), then you probably want to compute it in a sub-query, as shown above.
    There's probably a better way to compute vendor, but that's a separate problem.
    Edited by: Frank Kulash on Jan 3, 2012 10:37 AM
    Added example

  • Hint in Update or Select Statement in an inline query ??

    Hi ,
    I had an update statement that will get the data from the inline select statement,now where can i can keep the hint ,either in update statement or in Select statement...
    Please let me know if my sample script is wrong or any better way to approach...Please assume that Salary table had millions of employee's salary records.
    update emp
    set salary = salary + (select /*+ full(a) parallel(a,4)  */ salary from Salary
                             where   experience > 5  and empno = 55 )
    where empno = 85Thanks
    Rede

    You would put the hint in the select statement as you have it, but it won't work until you alias your table name to "a" since that is how you are referencing it in the hint:
    update emp
    set salary = salary + (select /*+ full(a) parallel(a,4)  */ salary from Salary a
                             where   experience > 5  and empno = 55 )
    where empno = 85
    NOTE I added the "a" right after the Salary table name AND you can only do parallel updates on partitioned table, but the select will run in parallel to at least get the data for you quickly.
    To answer your other question about syntax, it is incorrect and there are a lot of ways to write it but a straight forward way would be to use the merge statement
    merge into emp e
    using (select /*+ full(s) parallel(s,4)  */ s.salary from salary s where s.experience > 5) s
    on (e.empno = s.empno)
    when matched then update
    set salary = s.salary;

  • How to generate mutiple Results for multiple SQL SELECT statements

    I just downloaded SQL Developer 1.5 and play around with it.
    On a daily basis, I need run 4 different SELECT statements and dump the output of each SELECT into an CSV file and send to some users. In SQL Navigator, I can select all 4 SELECT statements and execute them at same time. Once all complete, I will see 4 tabs, each represent the output for each SELECT statement. Then I can export output from each tab into a CSV file.
    It seems that SQL Developer 1.5 still can't run mutiple SELECT statements and display the output of each statement into a separate "Results" tab so that I can export the data into multiple CSV files easily.
    Right now, I have to hightlight each SELECT statement and press F9, then export the output data into CSV.
    I wish I can execute 4 SELECT statements all in once on SQL Developer and get all the output data and export 4 times into 4 CSV files.
    Thanks!
    Kevin

    How about doing it as a set of tabs within the Resuls Tab?
    So you would have your Top row of tabs:
    Results, Script Output, Explain, AutoTrace, DBMS Output and OWA Output
    Then When you have the Results tab selected you could have a row of tabs beneath the Top row with one tab for each result set. Switching between result sets should switch which section of SQL is highlighted as the "Current SQL".
    A similar mechinism could be employed for each of the top level tabs where it makes sense to have multiple output tabs.
    A further refinement of this feature might be to allow the result tabs to be dockable within the parent tab so that multiple result tabs can be viewed simultaneously. This way 2 or more explain plans (for example) could be visually compared without requiring the code to exist in two separate code panes.

  • PL/SQL 101 : Cursors and SQL Projection

    PL/SQL 101 : Cursors and SQL Projection
    This is not a question, it's a forum article, in reponse to the number of questions we get regarding a "dynamic number of columns" or "rows to columns"
    There are two integral parts to an SQL Select statement that relate to what data is selected. One is Projection and the other is Selection:-
    Selection is the one that we always recognise and use as it forms the WHERE clause of the select statement, and hence selects which rows of data are queried.
    The other, SQL Projection is the one that is less understood, and the one that this article will help to explain.
    In short, SQL Projection is the collective name for the columns that are Selected and returned from a query.
    So what? Big deal eh? Why do we need to know this?
    The reason for knowing this is that many people are not aware of when SQL projection comes into play when you issue a select statement. So let's take a basic query...
    First create some test data...
    create table proj_test as
      select 1 as id, 1 as rn, 'Fred' as nm from dual union all
      select 1,2,'Bloggs' from dual union all
      select 2,1,'Scott' from dual union all
      select 2,2,'Smith' from dual union all
      select 3,1,'Jim' from dual union all
      select 3,2,'Jones' from dual
    ... and now query that data...
    SQL> select * from proj_test;
             ID         RN NM
             1          1 Fred
             1          2 Bloggs
             2          1 Scott
             2          2 Smith
             3          1 Jim
             3          2 Jones
    6 rows selected.
    OK, so what is that query actually doing?
    To know that we need to consider that all queries are cursors and all cursors are processed in a set manner, roughly speaking...
    1. The cursor is opened
    2. The query is parsed
    3. The query is described to know the projection (what columns are going to be returned, names, datatypes etc.)
    4. Bind variables are bound in
    5. The query is executed to apply the selection and identify the data to be retrieved
    6. A row of data is fetched
    7. The data values from the columns within that row are extracted into the known projection
    8. Step 6 and 7 are repeated until there is no more data or another condition ceases the fetching
    9. The cursor is closed
    The purpose of the projection being determined is so that the internal processing of the cursor can allocate memory etc. ready to fetch the data into. We won't get to see that memory allocation happening easily, but we can see the same query being executed in these steps if we do it programatically using the dbms_sql package...
    CREATE OR REPLACE PROCEDURE process_cursor (p_query in varchar2) IS
      v_sql       varchar2(32767) := p_query;
      v_cursor    number;            -- A cursor is a handle (numeric identifier) to the query
      col_cnt     integer;
      v_n_val     number;            -- numeric type to fetch data into
      v_v_val     varchar2(20);      -- varchar type to fetch data into
      v_d_val     date;              -- date type to fetch data into
      rec_tab     dbms_sql.desc_tab; -- table structure to hold sql projection info
      dummy       number;
      v_ret       number;            -- number of rows returned
      v_finaltxt  varchar2(100);
      col_num     number;
    BEGIN
      -- 1. Open the cursor
      dbms_output.put_line('1 - Opening Cursor');
      v_cursor := dbms_sql.open_cursor;
      -- 2. Parse the cursor
      dbms_output.put_line('2 - Parsing the query');
      dbms_sql.parse(v_cursor, v_sql, dbms_sql.NATIVE);
      -- 3. Describe the query
      -- Note: The query has been described internally when it was parsed, but we can look at
      --       that description...
      -- Fetch the description into a structure we can read, returning the count of columns that has been projected
      dbms_output.put_line('3 - Describing the query');
      dbms_sql.describe_columns(v_cursor, col_cnt, rec_tab);
      -- Use that description to define local datatypes into which we want to fetch our values
      -- Note: This only defines the types, it doesn't fetch any data and whilst we can also
      --       determine the size of the columns we'll just use some fixed sizes for this example
      dbms_output.put_line(chr(10)||'3a - SQL Projection:-');
      for j in 1..col_cnt
      loop
        v_finaltxt := 'Column Name: '||rpad(upper(rec_tab(j).col_name),30,' ');
        case rec_tab(j).col_type
          -- if the type of column is varchar2, bind that to our varchar2 variable
          when 1 then
            dbms_sql.define_column(v_cursor,j,v_v_val,20);
            v_finaltxt := v_finaltxt||' Datatype: Varchar2';
          -- if the type of the column is number, bind that to our number variable
          when 2 then
            dbms_sql.define_column(v_cursor,j,v_n_val);
            v_finaltxt := v_finaltxt||' Datatype: Number';
          -- if the type of the column is date, bind that to our date variable
          when 12 then
            dbms_sql.define_column(v_cursor,j,v_d_val);
            v_finaltxt := v_finaltxt||' Datatype: Date';
          -- ...Other types can be added as necessary...
        else
          -- All other types we'll assume are varchar2 compatible (implicitly converted)
          dbms_sql.DEFINE_COLUMN(v_cursor,j,v_v_val,2000);
          v_finaltxt := v_finaltxt||' Datatype: Varchar2 (implicit)';
        end case;
        dbms_output.put_line(v_finaltxt);
      end loop;
      -- 4. Bind variables
      dbms_output.put_line(chr(10)||'4 - Binding in values');
      null; -- we have no values to bind in for our test
      -- 5. Execute the query to make it identify the data on the database (Selection)
      -- Note: This doesn't fetch any data, it just identifies what data is required.
      dbms_output.put_line('5 - Executing the query');
      dummy := dbms_sql.execute(v_cursor);
      -- 6.,7.,8. Fetch the rows of data...
      dbms_output.put_line(chr(10)||'6,7 and 8 Fetching Data:-');
      loop
        -- 6. Fetch next row of data
        v_ret := dbms_sql.fetch_rows(v_cursor);
        -- If the fetch returned no row then exit the loop
        exit when v_ret = 0;
        -- 7. Extract the values from the row
        v_finaltxt := null;
        -- loop through each of the Projected columns
        for j in 1..col_cnt
        loop
          case rec_tab(j).col_type
            -- if it's a varchar2 column
            when 1 then
              -- read the value into our varchar2 variable
              dbms_sql.column_value(v_cursor,j,v_v_val);
              v_finaltxt := ltrim(v_finaltxt||','||rpad(v_v_val,20,' '),',');
            -- if it's a number column
            when 2 then
              -- read the value into our number variable
              dbms_sql.column_value(v_cursor,j,v_n_val);
              v_finaltxt := ltrim(v_finaltxt||','||to_char(v_n_val,'fm999999'),',');
            -- if it's a date column
            when 12 then
              -- read the value into our date variable
              dbms_sql.column_value(v_cursor,j,v_d_val);
              v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
          else
            -- read the value into our varchar2 variable (assumes it can be implicitly converted)
            dbms_sql.column_value(v_cursor,j,v_v_val);
            v_finaltxt := ltrim(v_finaltxt||',"'||rpad(v_v_val,20,' ')||'"',',');
          end case;
        end loop;
        dbms_output.put_line(v_finaltxt);
        -- 8. Loop to fetch next row
      end loop;
      -- 9. Close the cursor
      dbms_output.put_line(chr(10)||'9 - Closing the cursor');
      dbms_sql.close_cursor(v_cursor);
    END;
    SQL> exec process_cursor('select * from proj_test');
    1 - Opening Cursor
    2 - Parsing the query
    3 - Describing the query
    3a - SQL Projection:-
    Column Name: ID                             Datatype: Number
    Column Name: RN                             Datatype: Number
    Column Name: NM                             Datatype: Varchar2
    4 - Binding in values
    5 - Executing the query
    6,7 and 8 Fetching Data:-
    1     ,1     ,Fred
    1     ,2     ,Bloggs
    2     ,1     ,Scott
    2     ,2     ,Smith
    3     ,1     ,Jim
    3     ,2     ,Jones
    1     ,3     ,Freddy
    1     ,4     ,Fud
    9 - Closing the cursor
    PL/SQL procedure successfully completed.
    So, what's really the point in knowing when SQL Projection occurs in a query?
    Well, we get many questions asking "How do I convert rows to columns?" (otherwise known as a pivot) or questions like "How can I get the data back from a dynamic query with different columns?"
    Let's look at a regular pivot. We would normally do something like...
    SQL> select id
      2        ,max(decode(rn,1,nm)) as nm_1
      3        ,max(decode(rn,2,nm)) as nm_2
      4  from proj_test
      5  group by id
      6  /
            ID NM_1   NM_2
             1 Fred   Bloggs
             2 Scott  Smith
             3 Jim    Jones
    (or, in 11g, use the new PIVOT statement)
    but many of these questioners don't understand it when they say their issue is that, they have an unknown number of rows and don't know how many columns it will have, and they are told that you can't do that in a single SQL statement. e.g.
    SQL> insert into proj_test (id, rn, nm) values (1,3,'Freddy');
    1 row created.
    SQL> select id
      2        ,max(decode(rn,1,nm)) as nm_1
      3        ,max(decode(rn,2,nm)) as nm_2
      4  from proj_test
      5  group by id
      6  /
            ID NM_1   NM_2
             1 Fred   Bloggs
             2 Scott  Smith
             3 Jim    Jones
    ... it's not giving us this 3rd entry as a new column and we can only get that by writing the expected columns into the query, but then what if more columns are added after that etc.
    If we look back at the steps of a cursor we see again that the description and projection of what columns are returned by a query happens before any data is fetched back.
    Because of this, it's not possible to have the query return back a number of columns that are based on the data itself, as no data has been fetched at the point the projection is required.
    So, what is the answer to getting an unknown number of columns in the output?
    1) The most obvious answer is, don't use SQL to try and pivot your data. Pivoting of data is more of a reporting requirement and most reporting tools include the ability to pivot data either as part of the initial report generation or on-the-fly at the users request. The main point about using the reporting tools is that they query the data first and then the pivoting is simply a case of manipulating the display of those results, which can be dynamically determined by the reporting tool based on what data there is.
    2) The other answer is to write dynamic SQL. Because you're not going to know the number of columns, this isn't just a simple case of building up a SQL query as a string and passing it to the EXECUTE IMMEDIATE command within PL/SQL, because you won't have a suitable structure to read the results back into as those structures must have a known number of variables for each of the columns at design time, before the data is know. As such, inside PL/SQL code, you would have to use the DBMS_SQL package, just like in the code above that showed the workings of a cursor, as the columns there are referenced by position rather than name, and you have to deal with each column seperately. What you do with each column is up to you... store them in an array/collection, process them as you get them, or whatever. They key thing though with doing this is that, just like the reporting tools, you would need to process the data first to determine what your SQL projection is, before you execute the query to fetch the data in the format you want e.g.
    create or replace procedure dyn_pivot is
      v_sql varchar2(32767);
      -- cursor to find out the maximum number of projected columns required
      -- by looking at the data
      cursor cur_proj_test is
        select distinct rn
        from   proj_test
        order by rn;
    begin
      v_sql := 'select id';
      for i in cur_proj_test
      loop
        -- dynamically add to the projection for the query
        v_sql := v_sql||',max(decode(rn,'||i.rn||',nm)) as nm_'||i.rn;
      end loop;
      v_sql := v_sql||' from proj_test group by id order by id';
      dbms_output.put_line('Dynamic SQL Statement:-'||chr(10)||v_sql||chr(10)||chr(10));
      -- call our DBMS_SQL procedure to process the query with it's dynamic projection
      process_cursor(v_sql);
    end;
    SQL> exec dyn_pivot;
    Dynamic SQL Statement:-
    select id,max(decode(rn,1,nm)) as nm_1,max(decode(rn,2,nm)) as nm_2,max(decode(rn,3,nm)) as nm_3 from proj_test group by id order by id
    1 - Opening Cursor
    2 - Parsing the query
    3 - Describing the query
    3a - SQL Projection:-
    Column Name: ID                             Datatype: Number
    Column Name: NM_1                           Datatype: Varchar2
    Column Name: NM_2                           Datatype: Varchar2
    Column Name: NM_3                           Datatype: Varchar2
    4 - Binding in values
    5 - Executing the query
    6,7 and 8 Fetching Data:-
    1     ,Fred                ,Bloggs              ,Freddy
    2     ,Scott               ,Smith               ,
    3     ,Jim                 ,Jones               ,
    9 - Closing the cursor
    PL/SQL procedure successfully completed.
    ... and if more data is added ...
    SQL> insert into proj_test (id, rn, nm) values (1,4,'Fud');
    1 row created.
    SQL> exec dyn_pivot;
    Dynamic SQL Statement:-
    select id,max(decode(rn,1,nm)) as nm_1,max(decode(rn,2,nm)) as nm_2,max(decode(rn,3,nm)) as nm_3,max(decode(rn,4,nm)) as nm_4 from proj_test group by id order by id
    1 - Opening Cursor
    2 - Parsing the query
    3 - Describing the query
    3a - SQL Projection:-
    Column Name: ID                             Datatype: Number
    Column Name: NM_1                           Datatype: Varchar2
    Column Name: NM_2                           Datatype: Varchar2
    Column Name: NM_3                           Datatype: Varchar2
    Column Name: NM_4                           Datatype: Varchar2
    4 - Binding in values
    5 - Executing the query
    6,7 and 8 Fetching Data:-
    1     ,Fred                ,Bloggs              ,Freddy              ,Fud
    2     ,Scott               ,Smith               ,                    ,
    3     ,Jim                 ,Jones               ,                    ,
    9 - Closing the cursor
    PL/SQL procedure successfully completed.
    Of course there are other methods, using dynamically generated scripts etc. (see Re: 4. How do I convert rows to columns?), but the above simply demonstrates that:-
    a) having a dynamic projection requires two passes of the data; one to dynamically generate the query and another to actually query the data,
    b) it is not a good idea in most cases as it requires code to handle the results dynamically rather than being able to simply query directly into a known structure or variables, and
    c) a simple SQL statement cannot have a dynamic projection.
    Most importantly, dynamic queries prevent validation of your queries at the time your code is compiled, so the compiler can't check that the column names are correct or the tables names, or that the actual syntax of the generated query is correct. This only happens at run-time, and depending upon the complexity of your dynamic query, some problems may only be experienced under certain conditions. In effect you are writing queries that are harder to validate and could potentially have bugs in them that would are not apparent until they get to a run time environment. Dynamic queries can also introduce the possibility of SQL injection (a potential security risk), especially if a user is supplying a string value into the query from an interface.
    To summarise:-
    The projection of an SQL statement must be known by the SQL engine before any data is fetched, so don't expect SQL to magically create columns on-the-fly based on the data it's retrieving back; and, if you find yourself thinking of using dynamic SQL to get around it, just take a step back and see if what you are trying to achieve may be better done elsewhere, such as in a reporting tool or the user interface.
    Other articles in the PL/SQL 101 series:-
    PL/SQL 101 : Understanding Ref Cursors
    PL/SQL 101 : Exception Handling

    excellent article. However there is one thing which is slightly erroneous. You don't need a type to be declared in the database to fetch the data, but you do need to declare a type;
    here is one of my unit test scripts that does just that.
    DECLARE
    PN_CARDAPPL_ID NUMBER;
    v_Return Cci_Standard.ref_cursor;
    type getcardapplattrval_recordtype
    Is record
    (cardappl_id ci_cardapplattrvalue.cardappl_ID%TYPE,
    tag ci_cardapplattrvalue.tag%TYPE,
    value ci_cardapplattrvalue.value%TYPE
    getcardapplattrvalue_record getcardapplattrval_recordtype;
    BEGIN
    PN_CARDAPPL_ID := 1; --value must be supplied
    v_Return := CCI_GETCUSTCARD.GETCARDAPPLATTRVALUE(
    PN_CARDAPPL_ID => PN_CARDAPPL_ID
    loop
    fetch v_return
    into getcardapplattrvalue_record;
    dbms_output.put_line('Cardappl_id=>'||getcardapplattrvalue_record.cardappl_id);
    dbms_output.put_line('Tag =>'||getcardapplattrvalue_record.tag);
    dbms_output.put_line('Value =>'||getcardapplattrvalue_record.value);
    exit when v_Return%NOTFOUND;
    end loop;
    END;

Maybe you are looking for