Showing posts with label howto. Show all posts
Showing posts with label howto. Show all posts

Tuesday, August 13, 2013

Conditional Formatting of Calculated Items in OBIEE 11g

By Victor Fagundo

Calculated items in OBIEE Pivot tables can be very useful in certain reporting circumstances, either for ease of development, or to meet specific report requirements. While calculated items in OBIEE are easy, and flexible, they do have one important drawback: they take on the data and display formatting of the fact column they are calculated against.

The most common case is the calculation of a % change across a time dimension in financial reporting ( Year over Year, Quarter over Quarter, etc.). 1   This type of calculation usually takes the form of a percent change calculation similar to below:

 (( $2 - $1 ) / $1) *100 

By default, if you perform this calculation against a numerical fact ( sales, customers) you will run into the problem of how to display the % change in the correct format, since the calculated % will want to take the form of the fact it is calculated against, as can be seen in the example 2 below:


Figure 1 - Pivot Table


Figure 2 - Calculated item


Figure 3 - Results

Not very pretty at all.

As people searched for a work around to this problem 3 common solutions have arisen:
  1. Use HTML formatting tricks to “hide” trigger text in the results, then conditionally format off those triggers. While inventive, as the comments note, this solution falls flat if the report is ever printed, as the PDF engine will pick up and display all of the hidden characters.

  2. Convert the pivot table to a regular table with some complex column formulas. Very time consuming and cumbersome, would also not solve the requirement of showing the dimension values noted as noted in Footnote1.

  3.  Convert the calculated result to text and manually add your formatting characters. I don’t think this actually works since the calculated fields won’t accept logical SQL functions, and this would be very cumbersome.
Now with 11g providing conditional formatting that allows you to override the default data format, this is possible via the following steps:
  1. Add a column that is a COUNT DISTINCT on the dimension that you are calculating across ( in the displayed example, “Time T05 Per Name Year”. This column will serve as your “trigger” to apply your conditional formatting.

    Figure 4 - Column Formula

  2. For each of your facts, apply a conditional format that is triggered when the above column value is zero. In the formatting, apply whatever visual and data formats you desire. In this example we will format the data as a percent, with one decimal place.

    Figure 5 - Condition


    Figure 6 - Format when condition is met

  3. Exclude the “trigger” column from your pivot view. View your results and be satisfied:

    Figure 7 - Correct formatting of calculated item.

* Note that this would also allow you to apply visual formatting if you wanted to distinguish this row/column as a total.

Why it works

The use of conditional formatting that applies a data type as part of the format is a straightforward leap of logic, but what to use as the trigger? Most people will try to use the dimension they have setup the calculation in. However, if you try to use the text description given to the calculated item you will find that the condition is never applied:

Figure 8 - Condition on dimension

Figure 9 - Condition never met, format never applied

If you try to setup a filter that is true when the dimension is not in reasonable range of values ( in this example we try to format off all years not in the 2000s ) you will find that your calculated item is skipped as well (this has the added vulnerability of being very explicit):

Figure 10 - Condition on dimension values


Figure 11- Condition never met, format never applied

The reason for all this is that the calculated item “borrows” EACH of the dimension values it operates against. Hence, no matter how inventive your filter is, as long as you are trying to somehow separate the calculated member away from the members it is operating on, you will never succeed. This member “borrowing” is apparent if you add the dimension it operates against to the query a 2nd time, and look at the table view.

Figure 12 - Calculated item "borrows" members

But since the “member value” given to the calculated item does not actually exist in the dimension, if you try to perform a count distinct against it, you will always get zero.

Figure 13 - Count distinct against dimension

There is your difference; there is your “trigger.” The rest is basic formatting.

1: You might suggest that this requirement is better served using column(s) with time series calculations, and you might be right. However, more often than not the user will want to SEE the time periods being compared ( 2012 vs 2011, or 08/07/2012 vs 08/07/2011). When using facts with time series calculations you will only be able to show “this year” vs “last year” since the column heading of the time series calculated fact will always be static. In these cases you will need to use the base fact and a time dimension, along with the solution provided here.

2: All screen shots, and examples used in this post are performed in Sample App V305. An XML of the final correctly formatted report can be downloaded here.

Monday, July 8, 2013

Write It Out

This one was sitting in the drafts folder for a week or two, then I saw this post on Twitter:

Years ago I had a boss who was my technical superior (he may still be). I used to pop in and out of his office, or try to, and ask questions. Most of them were silly, n00b questions.

He was nice, but busy. It didn't take me very long to "read" that. So I slowed down my pace of questions. I began to write things up via email so that he could respond when he the had time. I started to use forums as well. Then I found was directed to How To Ask Questions The Smart Way.

One of the things that became evident quickly is that I didn't always have to hit Send (email) or Submit (forum post), just the act of writing it out forced me to think through the issue and more often than not, I would figure out the answer on my own.

Flash forward five or six years and I started to receive all these questions, either in person or via chat. "Send me an email" was usually my response, especially if I was in the middle of something (see: Context Switching). I was happy to help, just not at that moment. With email, I could get to it when I got a break (or needed one).

One of my favorite people, Jason Baer, who has worked for RittmanMead for the last couple of years, took this to heart. We started working together in December of 2009 and he would pepper me with questions constantly. I could never keep up. "Email the question Jason."

I didn't realize it, but I started getting fewer and fewer emails/questions from him. He began to figure them out on his own. It seemed most of the time he had just missed something, other times he just figured out another way to do something.

Jason is a smart guy. I think I'm smart. Sometimes it's just easier to ask the question without thinking it through. In fact, I do that quite a bit on The Twitter Machine ™, especially those errors that I seem to know but just don't have the bandwidth to research (think DBA type questions). I believe the types of questions that should must be written down are those that deal with Approach (design, architecture, etc). Any of those ORA errors better come along with a link to the error code in the documentation and some proof that you've researched it a bit yourself...but then that's getting into How To Ask Questions The Smart Way.

Go out and practice. Next time you have a (technical) question for someone, anyone, write it down and see what happens.

Monday, July 1, 2013

Context Switching: An Example

Last week at #kscope13 I saw an outstanding example of context switching. If you don't know what it is, Tom Kyte explains it here.

The two environments are just "different", separate and distinct. You can do plsql without SQL, you can do SQL (and many times do) without invoking plsql. There is a call overhead to go from SQL to PLSQL (the "hit" is most evident when SQL invokes PLSQL - not so much the other way, when SQL is embedded in PLSQL). Even if this hit is very very small (say 1/1000th of a second) - if you do it enough, it adds up. So, if it can be avoided - it should be.

The session was Using Kanban and Scrum to Increase Your Development Throughput presented by Stew Stryker (not to be confused with Ted Striker) of Dartmouth College (Stew gave me a gallon of Vermont Maple Syrup which exploded in my bag on the flight home, a gift for sharing my hotel room. Thanks Stew! ;)). So here's the example he gave to demonstrate context switching.

Take a list of names and time yourself writing out the first letter of each name, then the second, until you are finished.



Now, same list of names and write them out the way you normally would, left to right.



If the first method was faster, you are a freak of nature.

Wednesday, June 12, 2013

Required Reading

It's not often that I run across articles that really resonate with me. Last night was one of those rare occasions. What follows is a sampling of what I consider to be required reading for any IT professional with a slant towards database development.

Bad CaRMa


That led me to Bad CaRMa by Tim Gorman. This was an entry in Oracle Insights: Tales of the Oak Table, which I have not read, yet.

A snippet:

...The basic premise was that just about all of the features of the relational database were eschewed, and instead it was used like a filing system for great big plastic bags of data. Why bother with other containers for the data—just jam it into a generic black plastic garbage bag. If all of those bags full of different types of data all look the same and are heaped into the same pile, don't worry! We'll be able to differentiate the data after we pull it off the big pile and look inside.

Amazingly, Randy and his crew thought this was incredibly clever. Database engineer after database engineer were struck dumb by the realization of what Vision was doing, but the builders of the one-table database were blissfully aware that they were ushering in a new dawn in database design...

This is from 2006 (the book was published in 2004). Not sure how I missed that story, but I did.

Big Ball of Mud

I've read this one, and sent it out, many times over the years. I can't remember when I first encountered it, but I read this once every couple of months. I send it out to colleagues about as often. You can find the article here.

A BIG BALL OF MUD is haphazardly structured, sprawling, sloppy, duct-tape and bailing wire, spaghetti code jungle. We’ve all seen them. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.

Read it. Remember it.

How To Ask Questions The Smart Way

Ever been in a forum? Has anyone ever given you the "RTFM" answer? Here's how you can avoid it. How To Ask Questions The Smart Way. I read this originally about 9 or 10 years ago. I've sent it out countless times.

The first thing to understand is that hackers actually like hard problems and good, thought-provoking questions about them. If we didn't, we wouldn't be here. If you give us an interesting question to chew on we'll be grateful to you; good questions are a stimulus and a gift. Good questions help us develop our understanding, and often reveal problems we might not have noticed or thought about otherwise. Among hackers, “Good question!” is a strong and sincere compliment.

Despite this, hackers have a reputation for meeting simple questions with what looks like hostility or arrogance. It sometimes looks like we're reflexively rude to newbies and the ignorant. But this isn't really true.

What we are, unapologetically, is hostile to people who seem to be unwilling to think or to do their own homework before asking questions. People like that are time sinks — they take without giving back, and they waste time we could have spent on another question more interesting and another person more worthy of an answer. We call people like this “losers” (and for historical reasons we sometimes spell it “lusers”).

Business Logic - PL/SQL Vs Java - Reg

The article can be found here.

I don't believe this is the one that I would read just about every day during my first few years working with Oracle, but it's representative (I'll link up the original when I find it). I cut my teeth in the Oracle world by reading AskTom every single day for years. Some of my work at the time included working with java server pages (jsp) - at least until I found APEX. I monkeyed around with BC4J for awhile as well, but I believe these types of threads on AskTom kept me from going off the cliff. In fact, I got to a point where I would go to an interview and then debate the interviewer about this same topic. Fun times.

if it touches data -- plsql.

If it is computing a fourier transformation -- java.

If it is processing data -- plsql.

If it is generating a graph -- java.

If it is doing a transaction of any size, shape or form against data -- plsql.

Thinking Clearly About Performance

Cary Millsap. Most of the people seem to know Cary from Optimizing Oracle Performance, I didn't. I first "met" Cary virtually and he was gracious enough to help me understand my questions around Logging, Debugging, Instrumentation and Profiling. Anyway, what I've learned over that time, is that Cary doesn't think of himself as a DBA, he's a Developer. That was shocking for me to hear...I wonder how many others know that. So I've read this paper about 20 times over the last couple of years (mostly because I'm a little slow). I organize events around this topic (instrumentation, writing better software, etc) and this fits in perfectly. My goal is to one day co-present with Cary, while playing catch, on this topic (I don't think he knows that, so don't tell him). Link to his paper can be found here. Enjoy!

The Complicator's Gloves

One of my favorite articles from The Daily WTF of all time. Find the article here. The gist of the story is this: an internal forum where people were discussing how to warm a given individuals hands on his bike ride to work. The engineers then proceeded to come up with all kinds of solutions...they spent all day doing this. Finally, someone posts, "wear gloves." End of discussion. Love it. I wrote about it years ago in Keeping it Simple. For a few years I considered buying up thecomplicatorsgloves.com and try to gather related stories, but I got lazy. You should read this often, or better, send it out to colleagues on a regular basis to remind them of their craziness.

I'll continue to add to this list as time goes on. If you have any suggestions, leave a comment and I'll add them to the list.

Tuesday, March 19, 2013

dbms_output.put_line

I've been scratching my eyes out lately trying to reverse engineer some lots of PL/SQL.

One thing I've seen a lot of is calls to dbms_output.put_line. Fortunately, I've seen some dbms_application_info.set_module and other system calls too. But back to that first one.

1. When I used dbms_output, I would typically only use it in development. Once done, I would remove all calls to it, test and promote to QA. It would never survive the trip to production.
2. Typically, when I used it in development, I would tire of typing out d b m s _ o u t p u t . p u t _ l i n e so I would either a, create a standalone procedure or create a private procedure inside the package, something like this (standalone version).
CREATE OR REPLACE
PROCEDURE p( p_text IN VARCHAR2 ) 
IS
BEGIN
  dbms_output.put_line( p_text );
END p;
Easy. Then, in the code, I would simply use the procedure p all over the place...like this:
  l_start_time date;
  l_end_time date;
begin
  l_start_time := sysdate;
  p( 'l_start_time: ' || l_start_time );

  --do some stuff here
  --maybe add some more calls to p

  l_end_time := sysdate;
  p( 'l_end_time: ' || l_start_time );

end;
Since the procedure is 84 characters long, I only have to use the p function 4 times to get the benefit. Yay for me...I think. Wait, I like typing.

Thursday, February 21, 2013

Run Scripts in SQL Developer

I finally decided to save a script that cleans out a couple of tables for me.

Now I have a script, how do I run it in SQL Dev? In SQL*Plus, I would run it like @clean_tables. Two things to note there, 1, I didn't have to put the extension on the file and b, I assumed SQL*Plus was running from the directory where my file was located. If I was running the script from a different directory, I would have to use either a relative path...or something, but I digress.

I wanted to be able to run my script in a SQL Developer worksheet. How?
@clean_tables

Error starting at line 38 in command:
@clean_tables
Error report:
Unable to open file: "clean_tables.sql"

Twitter. Jeff Smith hangs out there, a lot. He supposedly has a real job as the Senior Assistant Principal Skinner Product Dude for SQL Developer at Oracle. Crazy title, I know. Back to Twitter.

Since he lives there (Twitter) (and I'm glad he does), I got an immediate response. Yay for Jeff.

Wait, what? Parent file? WTF are you talking about?

(I then remove the snark and try to put more details)

(oh, and I don't like that I can't just embed a single tweet...sorry, their fault, not mine)


Two seconds later:


Tested, and it works. Yay for me. Yay for Jeff.



In case it isn't obvious, I'm being sarcastic. Jeff is a fantastic advocate for SQL Developer. Yes, he gets paid to do it, but he goes above and beyond on a daily basis. Oracle is lucky to have him.

Thursday, December 20, 2012

PDI: Pass Parameters to Jobs/Transformations

I had been working on trying to get a process to run for each file. I used the Get File Names step followed by the Copy rows to result step. I had placed this in front of my Text file input step, which is where you define the file for further processing.

That method produced a stream (that's what it's called in PDI) with each and every file and each and every record in those files. If I were just loading that into a table, it would have worked. However, I was assigning a identifier to each file using a database sequence. I needed a sequence for each file, but I wasn't getting it.

With some help and pointers from the ##pentaho IRC channel, I found this post (more on that one in the future), Run Kettle Job for each Row. I downloaded the sample provided to see how it worked.



The calc dates transformation just generates a lot of rows. Not much to see there. The magic, at least for me, was in the run for each row job entry.



Specifically, the Write to log step. (I have this need to see things, since I don't understand everything about the tool yet, Write to log provides me that ability.)



See date, better, ${date}? That's how you reference parameter and variables.

I ran the job and watched the date scroll by. Nice. Then I tried to plug it into my job.

Zippo. Instead of seeing, "this is my filename: /data/pentaho/blah/test.csv" in the log output, I just saw "this is my filename:" Ugh. I went back to the sample and plugged in my stuff. It worked. Yay. Went back to mine, it didn't. Gah! I tried changing the names, then I'd just see "this is my filename: ${new_parameter_name}" so it wasn't resolving to the value.

Finally...after comparing XML for the sample file and mine and finding no real differences, I just about gave up.

One last gasp though, I went to the IRC channel and asked if there was some way to see the job or transformation settings. No one was home. I tried right-clicking to bring up the context menu and there was Job Settings



Job Settings brought up this one:



date is defined there. I checked mine. Nothing defined. Added filename to mine, ran it, Success!

Wednesday, August 1, 2012

Building an OBIEE Test Lab - Part II

So it's taking a little longer than I anticipated. That's a good thing (for me anyway). In Part I, I tried to diagram out what my plans were. My drawing was crude, and remains so. Mike Durran left me a link to the drawing below which is found here in the docs.



Now I'm an ambitious lad, but not that ambitious. This is for fun and amusement, perhaps I'll learn a thing or two along the way.

So how does this qualify as Part II? Well, I finally created the database. (No, I'm not going RAC like the diagram and docs say. Like I said, I'm not completely nutters.) This is an accomplishment for me as it's been quite some time since I've built anything, close to a year. So I'm celebrating by writing.
Oracle Enterprise Linux 64 bit, 5.8
2.6.32-300.32.1.el5uek
Database: 11.2.0.1
Database host: oracle-db
Database SID: TESTING
I used OEL 5.8 because that's the latest version I could find that was certified for 11.2.0.1 (straight from OTN). I was unable to find a single document that listed out the supported OSes, but I'm not that adept at searching through MOS yet (LOWER( DBA )). If you know where it is, please link it up.

This database will serve as the repository home for OBIEE and perhaps something like Identity Manager (OVM, OAM). I'll probably end up using it as a source and target for various projects as well.

Tuesday, July 3, 2012

OBIEE: Where'd my SQL go?

With the introduction of 11g, you can now deploy your opaque views to the database as, well, database views. It will simply wrap up your SQL statement inside a CREATE OR REPLACE VIEW... and run that statement using the connection pool you specified. Of course this means your connection pool has to have privileges to create objects, which may not be the case if you are using "read only" connections.

Anyway, if your development environment is refreshed from production on a regular basis, objects and all, you'll need to redeploy those views. Naturally, you saved that ad-hoc like SQL in subversion or some other source control tool...oops, you didn't?

All is not lost.

First, it's relatively easy, if you have a magnifying glass, to pick out the deployed views, they look like this:



Now, just go into the table properties, General tab and go to the dropdown box:



Select the Select selection (hah!). If you're a bit uptight about putting it in the correct location (like I am), you may have to navigate to the appropriate database version. For me, Oracle 10g R2:



Voilà!

Another option that you could use would be to Copy (Ctrl+C) the object in question and then paste (Ctrl+V) into notepad or some similar tool. Should be fairly easy to spot the SQL.

Thursday, June 14, 2012

TRUNC Time Off Date in OBIEE

"How do I get a prompt to display the day, minus 3 hours?" was the question.

This was a dashboard prompt (calendar widget) with a default value that used the following SQL:
SELECT CURRENT_DATE
FROM "Subject Area"
OK, easy enough.

We just needed to add a predicate or WHERE clause. What would I compare it with?

OK, I have a date column (with the no time component), so I can use that. I also have to use OBIEE (Logical) SQL. Gah. I wrote it in Oracle SQL first, day_column = sysdate - ( 3 / 24 ). Wait, I have to TRUNC the date to compare it to a date or else I won't get anything back. day_column = TRUNC( sysdate - ( 3 / 24 ) ). Better. I test it out and it does what I need it to do.

Now, to convert it to OBIEE SQL.

Instead of SYSDATE, I'll use CURRENT_DATE. Now I need to subtract 3 hours. TIMESTAMPADD for that.
[nQSError: 22025] Function TimestampAdd is called with an incompatible type. (HY000)
Oops. How about CURRENT_TIMESTAMP? Yeah, that works. Here's what I have so far:
TIMESTAMPADD( SQL_TSI_HOUR, -3, CURRENT_TIMESTAMP )
That doesn't work either. Ah, the time component, need to get rid of that. TRUNCATE? Nope, it's for numbers. Hmmm...wait, CAST! I'll just cast it to a date which should remove the time component.
CAST( TIMESTAMPADD( SQL_TSI_HOUR, -13, CURRENT_TIMESTAMP ) AS DATE )
Awesome. The final logical SQL looks like this:
SELECT CURRENT_DATE
FROM "Subject Area"
WHERE
( ( "Date"."Date" IN ( CAST( TIMESTAMPADD( SQL_TSI_HOUR, -13, CURRENT_TIMESTAMP ) AS DATE ) ) ) )
Easy.

Thursday, May 31, 2012

Building an OBIEE Test Lab

About 1.5 years ago I bought myself a nice little desktop. The only issues I've had with this computer over that time are the OS upgrades (Ubuntu). It has been an outstanding machine. I currently have 3 "computers" running, 2 Windows VMs and the host machine. I've had upwards of 5 running at once. That's with only 24 GB of RAM. I plan on upgrading to 48 in the near future (max of 96).

One of the motivators for buying the machine was the recent (at the time) release of OBIEE 11g, which required significantly more power. I've installed OBIEE 11g a number of times in virtual machines, but usually just put everything on a single machine (Oracle Enterprise Linux).

Now, I'd like to build out a machine for each component. Why? I have no earthly idea. Fun perhaps?

So here's my starting point:



There are no lines or anything yet, I'm just trying to get it down on paper before I start.

There are 4 distinct sets of software there: That means you can ignore the "Oracle LDAP" and replace it with Oracle Identity Management. I'll figure out later what all the components will be.

Also, you could split that up into 5 software components. You can install WebLogic by itself and then install (software only) OBIEE on top of that. Doubt I'll go that route for this first go, but we'll see. None of this includes source systems either. Somewhere around here I have a fresh install of EBS. Then I would have to install Informatica and the DAC. I'm sure I could get this up to 10 machines. I must watch out for scope creep. Bah, who am I kidding?

As I update my Visio doc I'll update the blog as well and share the progress with you.

I'll start by creating a snapshot of Oracle Enterprise Linux (5.7 I believe is the latest compatible release with OBIEE) and then use that as the base for everything else (database, web tier, etc). If I'm missing something or you think I should add something, leave a comment.

Monday, January 23, 2012

OBIEE 11g: Where's the Compare Repositories Dialog?

Recently I decided to try out the new patching capabilities for the metadata in OBIEE 11g. The big reason for me was to avoid having to reset my connection pools. Each time I did a 3 way merge, the connection pools would get over-written with their development credentials. When I was doing the merge, I could never find a way to isolate (leave out) those objects, so it was off to try the patching.

What this patching does is creates an xml file of the differences between 2 RPDs. You can then edit that XML file if you so desire. Most of my duties over the last couple of years have centered around the RPD and front-end stuff, not nearly as much on the administrative side (i.e. migrations). So I need to catch up with the rest of the world.

Reading through the docs, I'm told that I need to use the "Compare repositories" dialog. OK, easy enough.



Where is my entry for it?

OK, let's try the Compare entry.



Since I'm using the prod_20120122 RPD, I select the dev_20120122 RPD.

I'm prompted for the Repository Password and then it spins for a few seconds, then gives me this



I select Yes.



OK...where's the Compare Repositories Dialog like the docs say?

I see the icons have changed signifying differences, but no dialog as mentioned in the docs.

What if I select No?



Ah, there it is.

Interestingly, if I maximize that Compare Repositories Dialog, the next time I run the Compare, I can see it plain as day.



Hopefully you'll find this next time you endeavor to learn how to patch your RPD and can't seem to find the Compare Repositories Dialog.

Thursday, December 15, 2011

Trace Data: Not Just For DBAs

On Wednesday, I attended Cary Millsap's Mastering Oracle Trace Data class here in Tampa.

Why?

Why would I go? I am working with OBIEE which is about 42 layers above the database...who cares about trace data? Well, performance is usually the number 1 item on everyone's list. Page loads to slow. Report takes to long to run. Whether it's trying to tune the application server (WLS) or figure out why Report A takes so long to run, we do a lot of performance analysis. In most cases, it ends up being the SQL that is run. What I mean by the SQL is that it's usually bringing back quite a few records. I've seen people try to pull back millions of records and then pivot all that data putting a nice load on the BI Server and hogging all the resources from everyone else.

On occasion though, there are other things that are going on (with the SQL) that we can't pinpoint.

Recently we had to back out a production implementation because one of the load processes seemed to just hang, threatening to slow down a larger process.

I asked the DBAs why.

Crickets.

Shouldn't that be an answer a DBA provides?

Disk? Network? CPU? Memory? Which one?

Crickets. (I didn't ask those exact questions, I think I said, "Reads? Writes? Network? Load?")

That is just one of the reasons I wanted to attend Mr. Millsap's class. That, and I've heard he's well regarded and does a pretty decent job presenting. OK, I admit it, I just want to show the DBA up. There, said it.

I really shouldn't have to though. It's supposed to be a partnership. They don't know much about OBIEE, so I help them there. I expect help in things like this.

Why? Part II

If you are a developer, understanding trace data will make you better. You'll no longer have to guess, you'll know.

Of course there's what I hinted at above, being able to go to your DBA(s) and prove something. No better feeling in the world.

How?

MR Trace is by far the easiest. It's integrated with SQL Developer. It's a great place to start.

MR Tools - For the more advanced professional. Mostly geared towards the DBA type, but incredibly useful to developers as well. It includes:

- mrskew - your trace file profiler and data miner
- mrls: your trace file lister
- mrcallrm: your trace file correction fluid
- mrtrim: your trace file tim calculator
- mrtrimfix: your trace file time value fixer

Method R Profiler:
The classic tool that started it all, the Method R Profiler is software that makes simple work of knowing exactly why your application consumes the response time it does. With minimal training, a Method R Profiler user can—in just minutes—identify the root cause of an Oracle-based application performance problem, propose sensible solutions to it, and predict the end-user response time impact of each proposed solution.

There are of course other products, check them out here.

Ask Mr. Millsap to come to your town. Try out MR Trace. You won't be sorry you did.

Wednesday, September 14, 2011

OBIA: Installing Informatica 9.0.1

I'm in the process of building out a tip-to-tail dev/test system that includes the components from OBIA.

The components include:
- EBS Vision database
- Informatica PowerCenter 9.0.1
- Data Warehouse Administration Console (DAC)
- OBIEE 11.1.1.5
- OBIA 7.9.6.3

I recently rebuilt my EBS instance. I put my last go at it on a removable disk and seem to have misplaced it.

This will be part of a series of posts describing the entire process. I don't do it often enough and so I have to "remember" what I did, now I'll have my own reference.

Environment

As usual, this is running in a VirtualBox virtual machine.
- Host: Ubuntu 11.04, Natty Narwhal
- VirtualBox: 4.1.2
- Guest: Oracle Enterprise Linux (64 bit)
Linux oracle-web-tier 2.6.32-200.13.1.el5uek #1 SMP
x86_64 x86_64 x86_64 GNU/Linux
- Installed software: 11gR2 Database, OBIEE 11.1.1.5, Oracle Web Tier

I grabbed the download from edelivery, file name is: V26109-01.zip.

Other references:

- OBIA 7.9.6.3 Documentation Library
- OBIA Installation Guide for Informatica PowerCenter Users Release 7.9.6.3: Specifically this section, Installing Informatica PowerCenter Services.

Step 1, create a database account.
CREATE USER infa IDENTIFIED BY testing
  DEFAULT TABLESPACE users;

GRANT DBA TO infa;
**Note I have given DBA privileges, this is not necessary.**

It is simply easier, for now, to do it this way.

Step 2, unzip the files on your system.

It is recommended that you create an OS user specific to this task. I am using my previously existing oracle (dba, oinstall) account

Step 3, run the install.sh file
[oracle@oracle-web-tier infa_zips]$ ./install.sh
OS detected is Linux
unjar task is in progress.............
unjar of ESD completed.....
Do you want to continue installation (y/n) ?
y
Starting installation ...

\***************************************************************************
\* Welcome to the Informatica 9.0.1 HotFix 2 Server Installer.  *
\***************************************************************************


To verify whether a machine meets the system requirements for an Informatica installation, 
run the Pre-Installation System Check Tool (i9Pi) before you start the installation process. 
You can find the i9Pi tool in the following directory: /i9Pi


Before you continue, read the 9.0.1 HotFix 2 Installation Guide and Release Notes.
You can find the 9.0.1 HotFix 2 documentation in the Documentation Center at 
http://my.informatica.com
Configure the LANG and LC_ALL variables to generate appropriate code pages and 
create and connect to repositories and Repository Services.
Do you want to continue? (Y/N)Y
Installer requires operating system Linux version 2.6 and later.
Current operating system Linux version 2.6.
Current operating system meets minimum requirements.

 Select a choice :  
1.   Install Informatica 9.0.1 with Hot Fix 2 or Upgrade from a previous version of Informatica 
to Informatica 9.0.1 with Hot Fix 2 
2.   Apply Informatica 9.0.1 Hot Fix 2 to existing 9.0.1 install.
Enter the choice(1 or 2):1
 
-----------------------------------------------------------
Checking for existing 9.0.1 HotFix 2 product installation.
Select (G)UI mode (needs X Window support) or (C)onsole mode (G/C):G
Launching installer in GUI mode ...
Preparing to install...
Extracting the JRE from the installer archive...
Unpacking the JRE...
Extracting the installation resources from the installer archive...
Configuring the installer for this system's environment...

Launching installer...

Preparing SILENT Mode Installation...

===============================================================================
Informatica 9.0.1 Services HotFix2               (created with InstallAnywhere)
-------------------------------------------------------------------------------


System Requirements:



License Key and installation directory:



Confirmation:



Running...



Configuring...



Create a domain and Enable HTTPS. Enable HTTPS is checked by default, I won't be using it.



Configure the database connection and JDBC URL



Testing the connection...



Informatica Domain. I'm going to accept the defaults:



Summary


===============================================================================
Configuring Installation...
---------------------------

 [==================|==================|==================|==================]
 [------------------|------------------|------------------|------------------]

Installation Complete.
To verify your installation, open up http://localhost:6007/administrator/, username is administrator and the password is the one you supplied during installation.



You'll be redirected to this page.



Next steps will be to cover the Information Repository Service and Informatica Integration Service. That of couse, is later.

Saturday, September 10, 2011

OBIEE: Start/Stop Individual Components (Manually)

Previously I wrote about how to start and stop individual components via Enterprise Manager.

This time, I'm going to run through the manual steps to do the same, start and stop individual components using the Oracle Process Manager and Notification Server (OPMN) Tool.

First, navigate to the ORACLE_INSTANCE/bin directory. For me on Linux, that is /obiee/Middleware/instances/instance. List out the directory contents and you should see the opmnctl
[oracle@oracle-web-tier bin]$ ls -lah
total 56K
drwx------  3 oracle dba 4.0K Aug 16 00:53 .
drwx------ 14 oracle dba 4.0K Sep  8 17:09 ..
drwxr-x---  2 oracle dba 4.0K Aug 16 00:53 essbase_ha
-rwx------  1 oracle dba  44K Aug 16 00:53 opmnctl
Let's see what is running:
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    1525 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    1443 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    1487 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    1469 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |   30698 | Alive
All of the components are running. Good. Let's shut down everything.
[oracle@oracle-web-tier bin]$ ./opmnctl shutdown
[oracle@oracle-web-tier bin]$ ./opmnctl status
opmnctl status: opmn is not running.
And bring everything back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startall
opmnctl startall: starting opmn and all managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3122 | Alive
Now, let's stop the BI Server, coreapplication_obis1 or OrcleBIServerCom~. There are 2 ways to bring this down. Well, one command, stopproc, but 2 different ways. Notice the column headers up above, you have ias-component and process-type. Using ias-component:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc ias-component=coreapplication_obis1
opmnctl stopproc: stopping opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |     N/A | Down
Start it back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startproc ias-component=coreapplication_obis1
opmnctl startproc: starting opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3525 | Alive 
process-type shutdown:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc process-type=OracleBIServerComponent
opmnctl stopproc: stopping opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |     N/A | Down
Note that I didn't use OracleBIServerCom~. It expects the full name of the component, in this case, OracleBIServerComponent. If you use the shortened name, you'll get this:
[oracle@oracle-web-tier bin]$ ./opmnctl stopproc process-type=OracleBIServerCom~
opmnctl stopproc: stopping opmn managed processes...
================================================================================
opmn id=oracle-web-tier:9501
    No processes or applications match the specified configuration.
Finally, bring the BI Server back up.
[oracle@oracle-web-tier bin]$ ./opmnctl startproc process-type=OracleBIServerComponent
opmnctl startproc: starting opmn managed processes...
[oracle@oracle-web-tier bin]$ ./opmnctl status

Processes in Instance: instance1
---------------------------------+--------------------+---------+---------
ias-component                    | process-type       |     pid | status  
---------------------------------+--------------------+---------+---------
coreapplication_obiccs1          | OracleBIClusterCo~ |    3124 | Alive   
coreapplication_obisch1          | OracleBIScheduler~ |    3123 | Alive   
coreapplication_obijh1           | OracleBIJavaHostC~ |    3121 | Alive   
coreapplication_obips1           | OracleBIPresentat~ |    3120 | Alive   
coreapplication_obis1            | OracleBIServerCom~ |    3803 | Alive
Fairly simple.

For a full list of opmnctl commands, simply run ./opmnctl help and you'll get the following output:
[oracle@oracle-web-tier bin]$ ./opmnctl help

usage: opmnctl [verbose] [<scope>] <command> [<options>]

verbose: print detailed execution message if available

Permitted <scope>/<command>/<options> combinations are:

 scope    command     options
-------  ---------   ---------
          start                         - Start opmn
          startall                      - Start opmn & all managed processes
          stopall                       - Stop opmn & all managed processes
          shutdown                      - Shutdown opmn & all managed processes
[<scope>] startproc   [<attr>=<val> ..] - Start opmn managed processes
[<scope>] restartproc [<attr>=<val> ..] - Restart opmn managed processes
[<scope>] stopproc    [<attr>=<val> ..] - Stop opmn managed processes
[<scope>] reload                        - Trigger opmn to reread opmn.xml
[<scope>] status      [<options>]       - Get managed process status
[<scope>] metric      [<attr>=<val> ..] - Get DMS metrics for managed processes
[<scope>] dmsdump     [<dmsargs>]       - Get DMS metrics for opmn
[<scope>] debug       [<attr>=<val> ..] - Display opmn server debug information
[<scope>] set         [<attr>=<val> ..] - Set opmn log parameters
[<scope>] query       [<attr>=<val>]    - Query opmn log parameters
          launch      [<attr>=<val> ..] - Launch a configured target process
          phantom     [<attr>=<val> ..] - Register phantom processes
          ping        [<max-retry>]     - Ping local opmn
          validate    [<filename>]      - Validate the given opmn xml file
          help                          - Print brief usage description
          usage       [<command>]       - Print detailed usage description
          createinstance                - Create an Oracle Instance
          createcomponent               - Create a specified component
          deleteinstance                - Delete an instance and components
          deletecomponent               - Delete a specified component
          registerinstance              - Register with admin server
          redeploy                      - Redeploy the admin server application
          unregisterinstance            - Unregister with admin server
          updateinstanceregistration    - Update instance registration
          updatecomponentregistration   - Update component registration

Friday, September 9, 2011

OBIEE: Start/Stop Individual Components (Enterprise Manager)

The very first thing I thought, after firing up my first OBIEE 11g instance, was how freaking intimidating it was.

You have Enterprise Manager, the WLS Console and regular old /analytics. Nah...not too much.

Whatever.

Of course I'm still learning it daily, but most of the basics I have down now.

A basic concept which was super-easy in 10g, like stopping and starting individual services like the BI Server and Presentation Server, didn't seem so easy any more.

Now this isn't rocket science, but I'm sure it will help someone new (and intimidated!) by OBIEE 11g.

First, using Enterprise Manager.

After logging in, you'll see the Farm_bifoundation_domain (essentially your home) page:



From there, navigate to the Business Intelligence folder and click on coreapplication:



This will take you to your coreapplication (BI) page:



From there, you can stop all components of the BI Server; BI Server, Presentation, Java Host, etc.



Easy.

Sometimes though, you just need to restart one of the services, usually the BI Server or the Presentation Server.

Easy enough, see that tab Capacity Management, click on it:



That'll take you here, where you can start, stop and restart individual services:



Simply select the service you want to stop, start or restart like so:



Then select Stop Selected and you'll be prompted to confirm your selection:



Now you've stopped the BI Server service.



You can confirm this by looking at the Overview page as well:



There is also a manual way of doing this. Since it's Friday evening, I will wait until later to write that one up. Must go watch Megamind or some other fun kids movie with one of the monsters.