Feed aggregator

Our first official book review in on its way...

Eduardo Rodrigues - Fri, 2009-04-10 18:42
by Eduardo Rodrigues Great news! We have been contacted (surprisingly) by Packt Publishing a few days ago and asked if we would be interested in read one of their new books and then publish an...

This is a summary only. Please, visit the blog for full content and more.

Our first official book review in on its way...

Java 2 Go! - Fri, 2009-04-10 18:42
by Eduardo Rodrigues Great news! We have been contacted (surprisingly) by Packt Publishing a few days ago and asked if we would be interested in read one of their new books and then publish an...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

How to talk your way out of a hole

Oracle WTF - Fri, 2009-04-10 02:31

One last shot from our favourite consultant:

Be careful what you expect from this proof of concept. We can’t prove the performance will match the requirements, and I would argue that performance isn’t a function of this architecture, it’s a function of technology.

The issue is not the architecture, it’s that [this company] doesn’t have the technology. I would even argue that the technology required might not exist yet.

We can say that indicatively if the technology did exist, then this architecture would hit that performance requirement.

Let's hear it for architecture astronauts.

Oracle Discoverer - help people write ugly code :)

Moans Nogood - Thu, 2009-04-09 03:34
There's been a discussion going on among some of my friends about all this horrible-looking (and often badly performing) auto-generated SQL coming out of Discoverer and other tools. Here are some of the comments made during the discussion, and some of my memories of how I got started with Oracle with the help of my good friend Mogens Egan...

=======================

Me:

"Oracle Discoverer - helping developers write ugly code for more than a decade."

=======================

NN:

"no no no!

the real beauty of discoverer (and similar tools) is not that it lets developers write ugly code, but it lets people who don't know what code is (business users), write code and share it with other users who also don't know what code is. It's entire purpose in life is to let people who don't know what they are doing, do it. developers do what they do with some understanding and can, sometimes, be educated. accountants and hr people can't."

=======================

Me:

"This brings me back. From 1987 to 1990 I was in a bank, sharing an office with Mogens Egan (the father of Morten Egan) and basically creating a datawarehouse (although we didn't know it) for internal users in the bank.

Our strategy was this:

1. Every night (or once a week or whatever) we would transfer data from the banks mainframe system via a SNA gateway to our VAX. The data came from IMS databases and was delivered as flat ASCII files (one physical record = one logical record) which often resultet in very very long records, of course, since IMS is hierachical. We would then load it into tables and let the users access it.

2. I would hold one- or two-day courses where I'd teach the attendees (who had probably only used a PC for a very short time) how to log onto the VAX using Smarterm, how to use VMS basic commands (including the editor), how to use SQL and SQL*Plus, how to create default forms in Forms 2.3 - and some other stuff.

3. Mogens Egan's idea was that it was better to turn users/experts (SME's in todays jargon) into "programmers" than vice versa. And then it should be our job to fix run-away jobs (read: SQL that performed bad or messed up things for others).

A rather anarchistic approach, you could say. But man, it worked. In three years we had 1000 users, some of who turned out to be natural super users, who started creating systems that helped their co-workers.

Since they were not officially named super users they couldn't demand to be given time to develop something they thought could be useful - they were by natural selection only allowed to spend time on something their co-workers thought useful.

Mogens and I are still in contact with many of those users. The machine is now an Alpha cluster, the data it manages runs a rather large banks' trading stuff, and all that - but its name is still Samson. And the super user we created back then is still called Supermule, which is the Danish name for Super Goof. With the introduction of English-speaking consultants in the last 10 years it has proved a minor mistake - they all ask "What's a super mule?"

So yes, we had many incidents of run-away jobs where the poor user had issued a SQL statement without the proper where-clause, etc. But then we would discover it, kill it, help the user - and all of the victims of this bad SQL knew it could be their turn one day, so they didn't get mad or upset.

That playground which we created back then generated a lot of Oracle-lovers who are still around in various higher positions, and perhaps it would have been even easier for them back then if we had had Discoverer.

So I think you're absolutely right: Discoverer will help computer-illeterates write really bad code even faster. But at least it gets them to use Oracle, and it creates wonderful problems that finances our fantastic lifestyles.

Mogens

PS: In the World as a whole, I think Discoverer had a presence (penetration) of about 2% of customers. In Denmark it was 20% due to my ex-wife Laila (Nathalie's mother), then product sales rep for Discoverer, who insisted that every single customer should have this product, like it or not. And notice how well Miracle is doing here. Perhaps there's a relationship."

===================================

UKOUG Northern Server Technology Day 2009

Lisa Dobson - Mon, 2009-04-06 11:12
This year’s Northern Server Technology Day will take place on Tuesday 28th April at the Park Inn hotel in York.This annual event is aimed at DBA’s and Developers in the North of England and delivers a full day of server tech presentations over two streams.Previous events have taken place in Manchester, Leeds and Newcastle and the day has always proved to be popular for technical content and Lisahttp://www.blogger.com/profile/16434297444320005874noreply@blogger.com2

Caution: FOR loop and CONTINUE in Oracle 11g

Pawel Barut - Mon, 2009-04-06 04:59
Written by Paweł Barut
Friend of mine showed me interesting issue of using CONTINUE Statement. CONTINUE is an new statement in Oracle 11; it allow to skip processing of current iteration of look, and go to begging of next iteration. So here is working sample:
SQL> set serveroutput on
SQL> begin
  2    dbms_output.put_line('=== START');
  3    for i in 1..15 loop
  4      dbms_output.put_line('before:'||i);
  5      if mod(i, 5) = 0 then
  6        dbms_output.put_line('CONTINUE');
  7        continue;
  8      end if;
  9      dbms_output.put_line('after:'||i);
 10    end loop;
 11    dbms_output.put_line('=== STOP');
 12  end;
 13  /
=== START
before:1
after:1
before:2
after:2
before:3
after:3
before:4
after:4
before:5
CONTINUE
before:6
after:6
before:7
after:7
before:8
after:8
before:9
after:9
before:10
CONTINUE
before:11
after:11
before:12
after:12
before:13
after:13
before:14
after:14
before:15
CONTINUE
=== STOP

But when we use CONTINUE in loop, that is based on implicit cursor, it gives wrong results:
SQL> begin
  2    dbms_output.put_line('=== START');
  3    for r in (select level num from dual connect by level <= 115) loop
  4      dbms_output.put_line('before:'||r.num);
  5      if mod(r.num, 5) = 0 then
  6        dbms_output.put_line('CONTINUE');
  7        continue;
  8      end if;
  9      dbms_output.put_line('after:'||r.num);
 10    end loop;
 11    dbms_output.put_line('=== STOP');
 12  end;
 13  /
=== START
before:1
after:1
before:2
after:2
before:3
after:3
before:4
after:4
before:5
CONTINUE
before:101
after:101
before:102
after:102
before:103
after:103
before:104
after:104
before:105
CONTINUE
=== STOP

In that case CONTINUE statement goes to iteration no 101 instead of going to iteration 6, as expected!!
To make the long story short, I've experiment with few setting and found that setting PLSQL_OPTIMIZE_LEVEL to 1 this block runs as expected:
SQL> ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 1;
SQL> begin
  2    dbms_output.put_line('=== START');
  3     for r in (select level num from dual connect by level <= 115) loop
  4       dbms_output.put_line('before:'||r.num);
  5       if mod(r.num, 5) = 0 then
  6         dbms_output.put_line('CONTINUE');
  7         continue;
  8       end if;
  9       dbms_output.put_line('after:'||r.num);
 10     end loop;
 11     dbms_output.put_line('=== STOP');
 12  end;
 13  /
=== START
before:1
after:1
before:2
after:2
before:3
after:3
before:4
after:4
before:5
CONTINUE
before:6
after:6
[... many lines cutted out from output...]
after:99
before:100
CONTINUE
before:101
after:101
before:102
after:102
before:103
after:103
before:104
after:104
before:105
CONTINUE
before:106
[... many lines cutted out from output...]
after:114
before:115
CONTINUE
=== STOP

For me it looks as bug in PL/SQL Optimizer on level 2. In that case PL/SQL does bulk collect for 100 rows when FOR LOOP with cursor is used. Seems that CONTINUE in that case causes to fetch next portion of records instead of taking next record from buffer. I've reported bug to Oracle Support, but until it will get fixed, be aware of possible wrong results.
This was tested on Oracle 11.1.0.6 and 11.1.0.7 Enterprise Edition.

Keep reading,
Paweł

--
Related Articles on Paweł Barut blog:
    Categories: Development

    Core ADF 11: Abandoning a Bounded Taskflow with Stand-Alone Pages

    JHeadstart - Thu, 2009-04-02 22:14

    In the first post of this Core ADF 11 series, I discussed various options for designing your page structure. This post applies when you choose to use bounded task flows with stand-alone .jspx pages. If you make these bounded task flows available through a menu where each menu item calls a bounded task flow, you will hit the "cannot abandon bounded taskflow" issue: when you start the home page of your application (located in the unbounded taskflow), and then click on a menu item for the first time, you start the bounded taskflow associated with the menu item. Now, the menu is still visible, and the end user might decide to click on another menu item before he correctly finished the bounded task flow. In other words, he wants to abandon the task flow he started through the first menu item. However, when the user clicks on another menu item, nothing will happen! This is because the control flow rules that start each bounded taskflow are defined in the unbounded taskflow (in adfc-config.xml). They are not available in the context of the first bounded taskflow started by the user.

    The "poor man's" solution to this problem is hiding or disabling all menu items and other global actions that will launch a bounded task flow (like "Help" and "Preferences") until the user executes a bounded task flow return action and returns to a page in the unbounded task flow. Not a very user friendly solution....

    Another technique is to use a bounded taskflow template for all your bounded task flows. In the template you duplicate all control flow rules and all task-flow call activities that are defined in the unbounded task flow. While this might seem to work at first sight, this is not a viable option. What happens with this approach is that each time you click on another menu item, a new bounded sub task flow is started in the context of the current task flow: in other words, you keep on nesting bounded task flows. This is highly undesirable and will cause problems sooner or later with memory resources and/or transaction management. Since the task flows are nested, taskflow resources are never released, and transactions are never rolled back. Don't do this!

    The only proper solution is to execute a return activity to quit the current task flow before starting the new bounded task flow. In this post, I will describe how you can implement this in a generic way which hides the complexity for your developers. The outline of the solution is as follows:

    • The action property of all menu items as defined in the XML menu Model is prefixed with "abandon:" (This is all what your developers need to know)
    • A custom navigation handler is used that checks whether the navigation outcome starts with "abandon:". If so, and the current task flow context is a bounded task flow, then the navigation outcome as specified after the "abandon:" prefix is stored in a request attribute named "callMenuItem", and the super navigation handler is called with the CallMenuItem outcome. If we are not in the context of a bound taskflow, we call the super navigation handler directly with the navigation outcome as specified after the "abandon:" prefix.
    • The CallMenuItem outcome navigates to a generic task flow return activity named "CallMenuItem" which in turn navigates to the CallMenuItem activity in the unbounded taskflow.
    • The CallMenuItem activity in the unbounded taskflow is a "dynamic router" a Java class with a getOutcome method that returns the value of the EL expression passed in as argument. In our case, the router returns the value of the currentMenuItem request attribute, which causes navigation to the end target: either some page in the unbounded task flow, or another bounded task flow call activity in the unbounded task flow.

    Here are the detailed steps to implement this:

    1. Prefix the value of the action property in all your menu items in XML MenuModel with "abandon:"

    2. Create a custom navigation handler with the following code:

    public class MyNavigationHandler
      extends NavigationHandlerImpl
    {
      public static final String ABANDON_PREFIX = "abandon:";
      private static final String CURRENT_MENU_ITEM = "currentMenuItem";
      private static final String CALL_MENU_ITEM = "CallMenuItem";


      public MyNavigationHandler(NavigationHandler navHandler)
      {
        super(navHandler);
      }


      public void handleNavigation(FacesContext facesContext, String action,
                                   String outcome)
      {
        if (outcome != null && outcome.startsWith(ABANDON_PREFIX))
        {
          abandonTaskFlowIfNeeded(facesContext, action, outcome);
        }
        else
        {
          super.handleNavigation(facesContext, action, outcome);
        }
      }


      public void abandonTaskFlowIfNeeded(FacesContext facesContext,
                                          String action, String outcome)
      {
        String strippedOutcome =
          outcome.substring(MyNavigationHandler.ABANDON_PREFIX.length());
        TaskFlowContext tfc =
          ControllerContext.getInstance().getCurrentViewPort().getTaskFlowContext();
        if (tfc.getTaskFlowId() == null)
        {
          // we are not in a bounded task flow, do normal navigation
          handleNavigation(facesContext, action, strippedOutcome);
        }
        else
        {
          String newOutcome = strippedOutcome;
          Map requestMap = 
              FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
          requestMap.put(CURRENT_MENU_ITEM, newOutcome);
          handleNavigation(facesContext, null, CALL_MENU_ITEM);
        }
      }
    }

    3. Register your custom navigation handler in the faces-config.xml. Go to the Overview tab, click on Application, and set your class name in the navigation handler property.

    4. Create a bounded taskflow template used by all your bounded task flows, and add the following code to it:

    <task-flow-return id="CallMenuItem">
      <outcome>
        <name>CallMenuItem</name>
      </outcome>
    </task-flow-return>
    <control-flow-rule>
      <from-activity-id>*</from-activity-id>
      <control-flow-case>
        <from-outcome>CallMenuItem</from-outcome>
        <to-activity-id>CallMenuItem</to-activity-id>
      </control-flow-case>
    </control-flow-rule>
    </task-flow-template>

    When using declarative transaction management, you can add that a rollback should be performed as part of the return activity.

    5. Create a Java class named DynamicRouter with the following code:

    public class DynamicRouter implements Serializable
    {
      public String getOutcome(String outcome)
      {
        return outcome;
      }
    }

    6. Add the following code to adfc-config.xml (the unbounded task flow):

    <method-call id="CallMenuItem">
      <method>#{dynamicRouter.getOutcome}</method>
      <parameter>
        <class>java.lang.String</class>
        <value>#{requestScope.currentMenuItem}</value>
      </parameter>
      <outcome>
        <to-string/>
      </outcome>
    </method-call>


    <control-flow-rule>
      <from-activity-id>*</from-activity-id>
      <control-flow-case>
        <from-outcome>CallMenuItem</from-outcome>
        <to-activity-id>CallMenuItem</to-activity-id>
      </control-flow-case>
      ...
    </control-flow-rule>  


      <managed-bean>
        <managed-bean-name>dynamicRouter</managed-bean-name>
        <managed-bean-class>view.DynamicRouter</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
      </managed-bean>

    That's it. You can download a sample workspace that illustrates the solution here. In a later post, we will discuss how to add an alert to warn the end user about unsaved changes when he abandons a task flow.

    Categories: Development

    Java and the Timezones

    Eduardo Rodrigues - Thu, 2009-04-02 13:55
    by Fábio Souza Timezone, when using Java, can be something tricky. You can get surprised when you change your OS timezone (something common to countries with DST) and it doesn't take any effect on...

    This is a summary only. Please, visit the blog for full content and more.

    Java and the Timezones

    Java 2 Go! - Thu, 2009-04-02 13:55
    by Fábio Souza Timezone, when using Java, can be something tricky. You can get surprised when you change your OS timezone (something common to countries with DST) and it doesn't take any effect on...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    Web Component Developer Exam (SCWCD) for JEE 5

    Eduardo Rodrigues - Thu, 2009-04-02 13:39
    by Wellington Carvalho I hope my feedback can help those who want to prepare for The Web Component Developer exam (SCWCD) for JEE 5. I will use the same structure of an older post that Fabio Souza...

    This is a summary only. Please, visit the blog for full content and more.

    SCJP 6 Upgrade Exam (310-056)

    Eduardo Rodrigues - Thu, 2009-04-02 13:39
    by Fábio Souza Guys and girls, I guess the best way to start this post is with my appologies. I really wanted to post it earlier, but you all know how things are =P. It has been almost three months...

    This is a summary only. Please, visit the blog for full content and more.

    SCJP 5 and 6

    Eduardo Rodrigues - Thu, 2009-04-02 13:39
    by Fábio Souza OK, I know that is a little late to talk about SCJP 5 but I will give my feedback about the exam. This will help people that feels unprepared to take SCJP 6 (that was my case) and the...

    This is a summary only. Please, visit the blog for full content and more.

    Web Component Developer Exam (SCWCD) for JEE 5

    Java 2 Go! - Thu, 2009-04-02 13:39
    by Wellington Carvalho I hope my feedback can help those who want to prepare for The Web Component Developer exam (SCWCD) for JEE 5. I will use the same structure of an older post that Fabio Souza...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    SCJP 6 Upgrade Exam (310-056)

    Java 2 Go! - Thu, 2009-04-02 13:39
    by Fábio Souza Guys and girls, I guess the best way to start this post is with my appologies. I really wanted to post it earlier, but you all know how things are =P. It has been almost three months...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    SCJP 5 and 6

    Java 2 Go! - Thu, 2009-04-02 13:39
    by Fábio Souza OK, I know that is a little late to talk about SCJP 5 but I will give my feedback about the exam. This will help people that feels unprepared to take SCJP 6 (that was my case) and the...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    OracleAS Java Object Cache

    Eduardo Rodrigues - Thu, 2009-04-02 13:39
    by Fábio Souza Before I start, I would like to say that many texts and observations were took from the Oracle® Containers for J2EE Services Guide 10g (10.1.3.1.0), Chapter 7. What is it? The Java...

    This is a summary only. Please, visit the blog for full content and more.

    Diagnostics beyond OracleAS Control Console

    Eduardo Rodrigues - Thu, 2009-04-02 13:39
    by Eduardo Rodrigues One of the many companies recently acquired by Oracle is a small one called "Auptyma", whose founder and former CEO, Mr. Virag Saksena, was previously Director of the CRM...

    This is a summary only. Please, visit the blog for full content and more.

    OracleAS Java Object Cache

    Java 2 Go! - Thu, 2009-04-02 13:39
    by Fábio Souza Before I start, I would like to say that many texts and observations were took from the Oracle® Containers for J2EE Services Guide 10g (10.1.3.1.0), Chapter 7. What is it? The Java...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    Diagnostics beyond OracleAS Control Console

    Java 2 Go! - Thu, 2009-04-02 13:39
    by Eduardo Rodrigues One of the many companies recently acquired by Oracle is a small one called "Auptyma", whose founder and former CEO, Mr. Virag Saksena, was previously Director of the CRM...

    This is a summary only. Please, visit the blog for full content and more.
    Categories: Development

    There's a cook in JDev's development team indeed

    Eduardo Rodrigues - Thu, 2009-04-02 13:37
    Sometime ago I was surprised with a peculiar "tip of the day" which simply mentioned a traditional angel cake recipe. Well, today I got the confirmation. There's certainly a cook amongst JDev's...

    This is a summary only. Please, visit the blog for full content and more.

    Pages

    Subscribe to Oracle FAQ aggregator