Tuesday, December 26, 2006
Pool Boy Wonder - Christmas Day 2006
Well, then Eli turned 15, 16...and he was soon way more interested in playing with his friends, so we played but not as often. Now Eli is 20, living in his own apartment 8 miles away, studying jazz guitar fulltime at DePaul University. All very wonderful.
But he came over on Christmas for dinner -- and some pool. Hurray! So we played some games and that was fun, but then before he left, he had a very amusing time popping the cue ball off the table....why do that? Well, click here to watch the movie and you will see what I mean.
Wednesday, December 06, 2006
A sign of the times, or just of Orlando?
And since it is wintertime and very cold in Chicago, my wife Veva actually agreed to accompany me, in search of sun and warmth. How nice!
Now, I must admit: I find it hard to visit Orlando, at least the Disney World zone, which is where I almost always end up (Oracle conferences and so on). It is such an relentlessly fabricated pseudo-reality. It is bad enough that most of America seems to be paved over with malls, fast food "restaurants" and chain stores - it all looks enough. In Orlando, that homogeneity is celebrated with bigger versions of the Sameness, as if everything has been supersized and plasticized.
Through the Internet, I reserved a room at the Sherato Vistana, which seemed like a really nice resort hotel. I guess it was, but when we arrived, we were thoroughly alienated by its sprawl. Hey, plus there wasn't even Internet access in the room. Had to visit the (I kid you not) cyber.internet.cafe (really cool name).
Anyway, we stayed there one night and then escaped to an almost-normal hotel, the Doubletree Club, where I gave my training. On the day before the training the skies were overcast and the temperature was only in the 60s. Not poolside weather. But we adjusted our expectations and, determined to enjoy the outdoors (still much better than the 20 degrees in Chicago), we headed to the Leu Gardens.
This is a beautiful nature preserve near downtown Orlando that is filled with enormous Southern Live Oaks covered with Spanish moss, hundreds of Camelia bushes, and much much more. We walked around it for a couple of hours, enjoying the sounds of the bamboo scraping in the wind, the smell of the tropical flowers, and the wonderful colors of the butterfly garden. I encourage everyone visiting the Orlando area to take time away from Wet N Wild, Universal Gardens, Disney World, etc., to visit the Leu Gardens.
Now, as to the "sign of the times", we got back late one evening to the Doubletree Club and the parking lot was quite full. So we drove all the way to the back and as we parked in an empty spot, we noticed the sign to the right. It says "Reserved for Parking Only." Which immediately begs the question: what exactly are they worried people might do in these parking spots besides park? Hold a seance? Swear in the next Supreme Court Justice?
Well....we were in any case careful to do nothing more than park there.
Tuesday, December 05, 2006
An abomination in the supermarket
What is a TV Kart? Here is a quote from Cabco:
"Cabco is the world leader in mobile children’s entertainment for retailers. With over eight years experience and millions of happy retail shoppers, Cabco works with some of the world’s largest retail chains.
"Our program is unique and has rapidly become a retailing phenomenon
- TV Karts are a great service program for retailers to offer customers
- Parents shop in peace while their children watch their favorite programs, or listen to songs and stories in the Karts
- There is no cost to, or operational impact on, retailers
- Real time online remote Management System"
I understand why some parents want/need to distract their child. Many are seriously stressed for time, working two jobs, dealing with endless money problems, wanting some time to themselves, and so on).
But overall I find this trend of 100% Distraction for both children and adults very worrying. Essentially, we are being trained to be uncomfortable in our own mind. Rather than be left to our own to think about things, to puzzle out problems, to be in contact with and learn from the world around us, we plug into a screen that feeds us compelling images and voices. When this happens we move into a dangerously passive mode. This is bad enough when we are fully grown, but it is truly horrible to do this to children.
So for any parents reading this, I urge you to get rid of the DVD player in your car - and stay off the phone when you are with them. Instead, play games with your kids in the car, sing together, point out things passing by, ask them questions. In the supermarket, ask them about the prices of things, about what they like to eat, show them the amazing variety of veggies and fruits that the world just produces all on its own.
Make sure your children are engaged, curious, questioning. Passive children lead to passive adults, lead to people who are more easily manipulated, lead to further degradation of human society, and increase the likelihood that those with power and money will continue to kill and destroy to get their way.
All because of a TV Kart.
I kid you not.
Sunday, November 26, 2006
Minor violation of the Hippocratic oath?
While we can get certainly delve into the details of the Hippocractic oath, I generally interpret the oath as a commitment by those who choose to practice medicine to do all they can to help others and, conversely, to do everything possible to avoid harm.
I walked past the outpatient eye surgery clinic in which I got my eyes lasered a couple years ago and something about the sign on their door caught my eye. STOP! Don't read further. Instead, look at the sign and see if you can identify what bothered me.
It took me a little while to figure it out, but in the end I came to the conclusion that the Lakeshore Surgery Center has violated the Hippocratic Oath in a small way that I hope will never bring anyone to harm.
Here is my explanation: Imagine that your child (or spouse or best friend) hurt her eye in an accident. It is Sunday morning. You rush to the Lakeshore Surgery Center, because it is right around the corner and you've been there before. You are in a panic, your child wails in pain, you come to a screeching halt in front of the entrance, and rush to the door, child in your arms. Closed. You read the sign and then roar in agnoized frustration:
"The nearest hospital? I don't know where that is! What am I going to do now?"
See my point? It seems like the good doctors at this center could have and should have taken a bit more care with their sign. The generic "Please Go to the Nearest Hospital" reveals a lack of thoughtfulness in this context. There can only be one nearest hospital. So what the doctors should have done, to completely fulfill their oath to help and to avoid harm, is ask the sign company to show the name and address of the nearest hospital, and even add a little map showing how to get there.
You are thinking this is such a minor thing? Hey, it could save a life!
Thursday, November 23, 2006
National holidays in the United States
And it is very fascinating to look through her eyes at what goes in our simultaneously crazy, wonderful and revolting "advanced" society.
Today, Thanksgiving Day, the newspaper arrived. The size of the usual Sunday monstrosity (about 3 inches high), it consisted of the "news" section, plus three other bundles of advertisements, each as large as the "news" section (which itself is full of ads, of course).
She looked through some ads and then gasped: "Open at 5 AM?"
I glanced over at what she was reading. The advertising supplement for Kohl's. Like many other retailers, Kohl's now offers special, ultra, super deals for those people who want to haul themselves out of bed and go shopping at mind-boggling times: 5 AM, 6 AM, 7 AM. Before the usual opening time of 10 AM.
And it suddenly came to me:
This is what a national holiday now means in the United States:
Out of respect for our veterans or to give thanks for all that we have been given, you can't start shopping until 10 AM. This is the respite now offered by a capitalism run rampant in search of profits from our increasingly squeezed middle class and desperate poor.
But the day after the holiday? Time to get serious about shopping.
Sunday, November 19, 2006
What I Have Lived For - Bertrand Russell
What I Have Lived For
(The Prologue to Bertrand Russell's Autobiography)
Three passions, simple but overwhelmingly strong, have governed my life: the longing for love, the search for knowledge, and unbearable pity for the suffering of mankind. These passions, like great winds, have blown me hither and thither, in a wayward course, over a great ocean of anguish, reaching to the very verge of despair.
Saturday, October 28, 2006
Oracle Open World 2006 - miscellaneous meanderings from a week in San Fran
Awe-inspiring and quite overwhelming: attend OOW and you enter a very unnatural world of harsh lighting, frigid air conditioning, and lots and lots of people walking around with the same bags, the same name badges swinging from their necks, the same look of determination as they make their way either to the next session of interest. And then there is the loud, frenetic exhibition hall (actually, two separate halls this year), where the objective seems to be to gather as many t-shirts, tote bags and a multitude of other throw-away give-aways that companies have deemed will draw participants to their booths. Of course, there are also the magicians, the mugglers, the masseurs, the mini-arcade games, the barristas, and rarely but still occasionally the scantilly clad attractive women who no doubt are also ace PL/SQL developers. It's like a circus for otherwise sophisticated, highly technical people.
For the vendors, it's a numbers game: how many badges can we scan so that we have a fat list of leads to pursue after the show? It is a fairly indiscriminate process. For example, when I was about to do my theater presentation on code testing, the magician Quest hired would do his tricks and then draw people to the booth with the promise of a free t-shirt, and a raffle of $10,000 to take place on Wednesday afternoon (you have to be wearing your shirt to win). Nothing subtle there, and no mention of my name, what I did, what I would talk about. Seemd kind of odd (and for some of my presentations, we did actually let people know I would be speaking),but it works just fine. Anyway, it's not like this isn't an already qualified audience: you wouldn't be walking the floor there unless you had some sort of interest in Oracle technology.
In any case, I think that some graduate students could write some very interesting PhD theses on the human dynamics revealted at this show. I can still recall an OOW from years past, at which a company with the booth next to that of RevealNet was giving out beanie babies in exchange for people filling out a detailed, 6-page personal history for marketing analysis purposes. Attendees were lined up 5 layers deep to hand over their details in exchange for a toy they could buy for $5. Very very strange...
Anyway, Wednesday afternoon rolls around and the crowd assembles for the drawing of three names for three checks ($2500, $2500, $5000 -- and your name goes back into the pot after you win, so you can theoretically win more than once. Forget theoretical! In 2005, a very lucky guy had his named pulled TWICE!): a veritable sea of grey ToadWorld t-shirts. That was incredible and you can get a sense of it by clicking here (watch out: 65MB file).
Well, knowing that this was going to be my universe for the next five days, I started off my trip to the San Fran area by heading outdoors on the Saturday before, in a beautiful park in the San Jose area. I gulped in the very clean air amongst towering redwood trees, along with my sister-in-law, Carmen, and a nephew and niece. I then stayed over at Carmen's place on Saturday night. On Sunday morning, I strolled into the main conference hotel, the Marriott, where the friendly fellow at the front desk told me that I had been scheduled to arrive the night before, so they cancelled my reservation and the hotel was now sold out (as was, likely, every other hotel for the surrounding 10 miles). Not a very nice piece of news, and all my fault! But we worked it out, and I did stay at the Marriott the whole time (thank you, Kathleen, thank you, thank you). Very nice hotel, excellent fitness center, and only one truly bizarre experience:
It was 10 PM on Wednesday night, back from Quest's special premiere event for ToadWorld. I was working on my laptop, with Johnny Cash explaining why he wears black seeping out of my speakers, when I realized that I was also listening to the sounds of a very distressed woman out in the hallway somewhere. Beaten and collapsing, calling weakly for help? Horrible sounds. I grabbed my phone, my card key, opened my door, and looked up and down the hallway, ready to help. No one there. And then I realized that all the noise was coming from the room across the hall. It wasn't a woman in distress I was listening to, it was the sound of a woman pretending to have a really good time. It was the soundtrack of a porno film, with the volume turned up to the max. Argh......
I called the front desk and asked them to deal with it. Ten minutes later, a security guard was knocking on my neighbor's door. "Sir? Sir? You must turn down the volume on your TV." He said this and knocked loudly several times. I went over to the keyhole to watch. For the next 5 minutes or so, he pleaded with the person in the room to turn down the TV, but there was no response. Finally he opened the door, peeked in, quickly came back out, again calling "Sir? Sir?" Then he finally called someone on his phone, probably his superior. "The customer is lying on the bed, knocked out," he says in a hushed voice, "and completely exposed." Silence as he listens. Then: "Yes, yes, what do you think I'm going to do? I'll go in there and turn it off." And finally, he did. Ah, the joys of attending Oracle Open World.
OK, enough of my meandering thoughts, here are some of my highlights from the show:
* Quest announced availability of Toad 9.0, a substantial upgrade to the 8.6 version, with a powerful single editor that replaces the SQL editor, Proc Editor and Offline Text Editor. They crammed something like 153 separate enhancements into the product. I continue to be amazed at the pace with which the Toad development team can add solid, useful, well-designed features to what was already the best PL/SQL IDE on the planet.
* Live penguin steals Larry's show. Larry Ellison's keynote was, I thought, mostly a rehash of previous keynotes (Unbreakable Linux, grid, RAC, finally got it right, really cool stuff, etc.). Then he announced his cleverly masked plan to squash Red Hat by offering support for Linux at half the Red Hat price. And to celebrate, out came a live penguin. Aw, it was so cute. That deeply educational moment was followed by quick videos of each CEO of the major sponsoring companies (AMD, HP, IBM, Sun, etc.) telling us how fantastic Oracle technology was and how much it had helped them. I was totally convinced. But mostly what I thought was: Wow, Larry didn't really have all that much to say this year, if he needed to fall back on live animals and video clips of talking heads. Regardless, he is still my hero. After all, without Larry and PL/SQL, I would be, let's see, well, maybe I would have written a popular book about Java. Probably did in some alternative universe, where I am the Guru of Squiggly Brackets.
* This was the best and more important OOW for me in many years. Quest announced availability of Quest Code Tester for Oracle, the testing tool on which I have been working hard, really hard, extra super-duper hard, for the last year. Quest Code Tester 1.2.5.5 is a completely free version, with commercial, trial and freeware versions arriving in February 2007. You can download it from www.ToadWorld.com (click on the Downloads tab). This is one very cool piece of technology. If you write PL/SQL code, I strongly suggest you check out Code Tester. I did a bunch of theater presentations on the tool and received lots of very positive feedback (or maybe they were just all excited about their t-shirts).
* Beyond Code Tester, I did four presentations, including two back-to-back talks on Thursday morning on error management and test driven development. Very friendly and appreciative audiences. I also was the recipient of the Oracle Magazine PL/SQL Developer of the Year for 2006, which means I will soon receive a very tasteful piece of nicely engraved Lucite. I will be honored to place it next to the Oracle Magazine PL/SQL Developer of the Year for 2002 piece of Lucite on the shelf in my office. No, truly, it is quite an honor and I very much appreciate the support and recognition I have received from Oracle Magazine and Oracle Technology Network over the years. On Sunday night, OMag sponsored a dinner for awardees, Oracle ACEs and others. I met Eddy Awad (OMag Blogger of the Year!) for the first time, saw Tom Kyte again (met him for the first time just a week or two ago at the KC OUG conference) and reconnected with a whole bunch of other top notch technologists, in particular the illustrious Bryn Llewellyn, PL/SQL Product Manager.
* Other exciting announcements at the show: Quest has launched ToadWorld, mentioned above, which is a fantastic portal for all things Toad, plus a ton of resources for anyone writing PL/SQL code. I've got an Experts Corner, as well as a blog, at ToadWorld, so come and visit: www.ToadWorld.com.
And that's not all!
* ODTUG (Oracle Developer Tools User Group) announced OPP2007, the second nothing-but-PL/SQL conference ever to be held. I sponsored the first one back in November 2005 (organized by the wonderful folks at Your Conference Connection) and it was so popular, ODTUG agreed to take over the main sponsorship of future, annual PL/SQL conferences. This pleases me to no end. I have tremendous respect for ODTUG, and much admiration for the hard work of its volunteer board. It is going to be held on February 28-March 1 out in San Mateo. I'll be there, as will Bryn Llewellyn and Christopher Racicot, Development Manager for Oracle PL/SQL, along with many other excellent PL/SQL educators. I hope you can join. Click here for more information and to register.
* As always, the best part of OOW was meeting people who had read my books or attended my trainings and felt that my work had made a big difference in their professional careers. I don't mind helping companies improve their software quality and perhaps even make more money, but I am most jazzed about helping individual programmers lead better and more satisfying lives. Also very gratifying: after my talk on error management on Thursday morning (8-9 AM!), the young guy taking care of the audio visual equipment told me that he'd done some programming in the past. He'd also been listening to talks all week long and this was the first presentation that he could actually understand and get something useful from. Very cool.
* I decided on the spur of the moment during one of my talks to launch a global Campaign to Implement a Boolean Overloading for DBMS_OUTPUT.PUT_LINE (CIBODOPL). Sure, it is a bit silly, but silly can be good in our often all-too-serious jobs, and such an effort might actually move this enhancement request towards the top of the list and just get it done (in Oracle12, anyway). I can't imagine it is going to take much of an effort on the part of the PL/SQL development team. So soon, soon (not yet) you will be able to visit CIBODOPL.net or some similar location and add your name and support to this campaign. You can also tell us on this website what small, annoying feature or lack thereof is on the top of your list to fix/add to PL/SQL.
Thursday, October 05, 2006
The life of a (well, this) software developer
I would like to say that everything is pretty much done and I am coasting to the finish line, but that is not the case. Instead, we are working extremely hard to pack in as much functionality (and the fewest possible bugs) into what I believe will be a truly revolutionary killer app for PL/SQL developers.
Here is what my day looks like in this race to the finish line (which is not really any sort of finish. Software is never really finished. It is "just" a release. As soon as it goes out, we get back to work improving the tool):
- Try to get up at 6 AM. Usually that is possible.
- Work work work all day long (my office is in my home), with regular breaks, stretching, situps, lots of water, too much coffee. Communicate with my developers in Russia, Ohio and across my office space. Respond to bugs entered by beta testers and our full time QA resource in Alisa Viejo, CA.
- At around 7 PM, my co-worker Leonid (who comes to work with me here in my home office) heads home (where he apparently takes a short break and gets back to work!).
- At 7:30 or 8, I have dinner with my wife, Veva, and our house-mate, Ying - both of whom are amazing cooks. So I eat well, and mostly vegetables.
- Between 8:30 and 10:00, I head to the basement for 45-60 minutes of exercylcing (finally broke down and got a decent Diamondback model, cause I realized that I wouldn't give myself the time to head to the fitness center during the week), and then some weight lifting, more situps (best way to avoid lower back pain, I have found).
- At 10 PM, I join Veva for a half hour of the best comedy, satire and news on television: the Comedy Central's Daily Show.
- At 10:30 PM, I yank myself away (I don't find the Colbert Report quite as enjoyable, but still it exerts its pull) and back to work.
- Try to work till 1 AM.
- Reward myself with bed and sleep.
I am also extremely happy that Quest Software is investing in this tool to bring it to maturity so much faster than would otherwise have been possible.
Time for bed.
Saturday, September 02, 2006
The amazing and creepy transformations of Christian Bale
The movies were:
American Psycho
"A wealthy New York stock executive hides his alternate psychopathic ego from his co-workers and friends as he escalates deeper into his illogical, gratuitous fantasies."
The Machinist
"An industrial worker who hasn't slept in a year begins to doubt his own sanity."
Two very understated descriptions of very intense movies, by the way.
The movies themselves are disturbing enough, but what I found most creepy about watching them almost back to back was the astonishing contrast between the Christian Bales of these two movies.
In American Psycho, the psychopath pampers his body, hones it to a buff, highly developed machine. This is critical, as it serves as a human covering over what he recognizes is an empty husk. Thus, an attractive physique is transformed into something menacing and un-human.
In The Machinist, Bale plays a man who hasn't slept for a year. We find out at the very end of the movie why that is. But during the year, he not only doesn't sleep, but he apparently doesn't eat very much at all, either. By the time the climax of his year of decay takes place in the movie, the character is, well, a skeletal figure. Literally. The thing is, this is Bale. He really did this. He starved himself for this movie.
It is hard to look at him ,and even more troubling to think....
- That Bale made this enormous sacrifice for a movie that tanked and disappeared almost overnight. I wonder how he must have felt, after all that suffering...
- About the extremes to which actors and actresses will push themselves and their bodies for their craft.
Monday, August 28, 2006
Scattered shots across my bow
Yeah, right.
Anyway, I have been incredibly busy doing some incredibly interesting stuff. Want to hear about it? Oh, okay, you twisted my arm.
First of all and most exciting, I and my development team have been putting in lots of hours to complete the beta release of Qute, the Quest Unit Testing Tool. If you write PL/SQL code, this product is going to rock you back in your shoes. It will completely change the way you think about and do testing of your PL/SQL code. We now enter a 6 week QA period and then move to an October 2006 release. The beta program is closed (unless you are really serious about getting involved, in that case, get in touch...), but you can download and try out the software - starting tomorrow, August 29. Just visit the Qute Community and have a look around after we load up the beta software at the end of this day.
Beyond that, I just finished one of the most interesting books I have ever read in my life. It is called On Intelligence, by Jeff Hawkins, and it offers a paradigm for understanding how our brain works (that is, how we are able to function in the world, type on a keyboard, think abstract thoughts, build cars, etc.). He thinks that with this paradigm shift, we will relatively soon be able to make true thinking machines, as opposed to computing machines, the dumb things that we call "computers" today. Yes but what about Skynet?
Read this book. It is short and mostly very accessible. It could change your life! I strongly urge you to get a copy, only $7.99 at Amazon!
On to less pleasant matters. Just when I thought I had managed to put an arm's length between my emotional well being and the awful conflicts raging between Israel's fanatical, aggressive military-governmental complex and its neighbors, I read this article and found myself in tears.
C'mon, Olmert. Even if you are totally justified in using cluster bombs on towns in Lebanon (which usage almost certainly violates US law), couldn't you have the grace to now say: "We will help you clean up our mess. We will provide soldiers to gather up all those little colored balls that look like toys but will actually destroy life."
Just think how much good will Israel would gain.
Sorry, just dreaming about a better world again...may I never break the habit!
Meanwhile, my wonderfully creative wife, Veva, a ceramist of fine skill and aesthetic sense, just installed her latest "goddess" statue in front of our house. She calls it the Bird Lady. I like it alot.
I will end on that more upbeat note.
Tuesday, August 08, 2006
Abe Foxman Defames Kofi Annan: will he apologize?
Abe Foxman is National Director and chairman of the Anti-Defamation League of B'nai B'rith. He started working for the Anti-Defamation League 1965. He was promoted to National Director in 1987.
The mission of the ADL is:
The immediate object of the League is to stop, by appeals to reason and conscience and, if necessary, by appeals to law, the defamation of the Jewish people. Its ultimate purpose is to secure justice and fair treatment to all citizens alike and to put an end forever to unjust and unfair discrimination against and ridicule of any sect or body of citizens.
This is a very noble mission and the ADL has over the years indeed helped to secure justice and fair treatment for some citizens. But lately Abe Foxman has become an incredibly obnoxious cheerleader for the State of Israel (by which I mean those executing the policies of the repulsive former Prime Minister, Ariel Sharon, and his pathological Likud party).
Ok, fine. This is America. Freedom of speech and all that. Fine. Then let him spout his self-absorbed nonsense. But, particularly given the name of his organization, you'd think he would at least take care not to defame people.
Defamation is the "...publication of a false statement of fact, made with the requisite state of mind, that causes injury." (http://en.wikipedia.org/wiki/Defamation#_note-0)
On August 8, I read the following article on Ha'aretz, a popular Israeli daily that is also published in English.
ADL blasts Annan as 'blatantly one-sided' and 'anti-Israel'
By Shlomo Shamir, Haaretz Correspondent
http://haaretz.com/hasen/spages/748265.html
NEW YORK - The National Director of the Anti-Defamation League (ADL), Abraham Foxman, accused United Nations Secretary General Kofi Annan on Tuesday of demonstrating "blatant one-sidedness" in his comments about Israel's war against Hezbollah in Lebanon.
"I am stunned that the UN secretary general cannot find his tongue except to criticize and denounce Israel, and is unable to raise his voice to denounce Hezbollah's daily firing of hundreds of rockets that are specifically intended to hurt civilians," Foxman said Tuesday in an exclusive interview with Haaretz.
"In addition, [Annan] has not bothered to mention the loss of life in Israel as a result of the rocket attacks," Foxman continued. "When will the UN secretary general begin to give Jewish lives the same respect he extends to other human beings," the ADL head asked.
===========END ARTICLE
I was at first shocked to see the ADL describe Kofi Annan as "anti-Israel." That is a very serious charge to level at the Secretary General of the United Nations. Then I read what Foxman said and found myself wondering...it certainly would be shocking and disgraceful for Annan to never mention that Israelis have died from rocket attacks, never denounce Hezbollah's those same attacks on Israeli towns and cities. That sure would be one-sided and, at a minimum, thoroughly lacking in compassion for Israelis.
You really would have to question Annan's objectivity, his fitness for the position he holds today.
Surely Foxman or someone at ADL had carefully gone over all of Annan's public pronouncement to make sure Fox's claims were accurate; namely, that Annan had "not bothered to mention the loss of life in Israel as a result of the rocket attacks."
But why assume that? Why not check for myself? So here it is, 1:10AM in the morning. I need to sleep. I am overwhelmed by work. But I find myself visiting www.un.org and reviewing Annan's personal statements. This is what I found (and fortunately very quickly as well):
July 30
http://www.un.org/News/Press/docs//2006/sgsm10580.doc.htm
"Meanwhile, over 50 Israelis have died, including 19 civilians, and the population of northern Israel has been subjected to intense and continuous rocket fire, and thousands are now in shelters. "
July 26
http://www.un.org/News/Press/docs//2006/sgsm10578.doc.htm
"First and most urgent, we need an immediate cessation of the hostilities that began on 12 July with Hizbollah's reckless attack across the Blue Line and the abduction of two Israeli soldiers.
"We need a cessation of hostilities because we face a grave humanitarian crisis. The United Nations Emergency Relief Coordinator, Jan Egeland, has just visited Lebanon, and reports that some 800,000 people are being affected in one way or another, whether through displacement, injury, trauma or other fallout. Meanwhile, rockets continue to fall on Israeli cities, taking lives and instilling deep fear among hundreds of thousands of people. Some 400 Lebanese have been killed, and many thousands wounded. Several dozen Israelis have been killed, and hundreds wounded.
...
"
Therefore, I call on Hizbollah to stop its deliberate targeting of Israeli population centres.
"And I call on Israel to end its bombardments, blockades and ground operations."
======== END ANNAN'S STATEMENT
I imagine there are other, similar comments in press releases, comments to the media, and so on. It seems pretty clear to me that Annan did, indeed, mention all the things that Foxman claims Annan did not. From the brief review I performed, it also seemed rather clear that Annan was very consistent in condemning all violations of international law, and in particular the use of violence against civilians.
It just so happens that the Israel Defense Forces are inflicting orders of magnitude more violence against Lebanese and Palestinians than Hezbollah and Hamas are inflicting on Israelis.
As a result, there are many more deaths to condemn, much more destruction of civilian infrastructure, vastly more refugees and a full-blown humanitarian crisis -- all the direct result of Israel's attack on Lebanon. Whether you consider this attack justified or not, there is no doubt about whose bombs are doing what, and to whom.
The conclusion should be patently clear to all:
Abe Foxman and the Anti-Defamation League have defamed Kofi Annan and the United Nations. He should immediately offer an apology (I am sure he can find some intern assigned to do the research to take the fall) or he should resign from his position in the ADL.
Saturday, August 05, 2006
Execute DDL statement from file
I was thinking the other day that I have written so many little utilities that I imagine many PL/SQL developers would appreciate. So I am going to post them occasionally on this blog, in the hopes that that code I wrote will be more widely used.
The exec_ddl_from_file program will execute the contents of your file as a DDL statement. This means that you may not use any bind variables, nor may you return information from the statement that is executed dynamically. But you can use this program to read in a file (using UTL_FILE) that contains, say, the CREATE OR REPLACE PACKAGE definition of a package, and create that package. Hopefully you will find such a utility handy, but I wrote it mostly to demonstrate how you can use DBMS_SQL.PARSE to execute arbitrarily large dynamic SQL strings. EXECUTE IMMEDIATE of Native Dynamic SQL fame is limited to 32K characters. Not so with DBMS_SQL. So here are the files in the download:
exec_ddl_from_file.sql - creates a procedure that executes the contents of a file. You will need to have UTL_FILE configured to get this program to run properly.
exec_ddl_from_file2.sql - creates a procedure that executes the contents of a file and includes the logic required to verify that you are indeed running under invoker rights.You will need to have UTL_FILE configured to get this program to run properly.
invdefinv.sql - a script that demonstrates how when a definer rights program calls an invoker rights program, the current user for that invoker rights program is set to the owner of the definer rights program. It also shows the usefulness of the DBMS_UTILITY.FORMAT_CALL_STACK, which reveals the PL/SQL call stack.
Death of a Child
12/13/98 - I played Pitch, a very interesting card game with numerous levels of strategy, several times today with Eli (my youngest son, 13 yrs old at this time). He has a sharp mind. I sat there looking at him, his long, hairy legs, his ever-lengthening feet, his expanding chin, and I saw:
Eli in motion -- even as he just sat there: growing, growing, growing.
It was such a wonderful feeling and then I thought to myself: "How awful it would be to have the death of a child on one's hands."
So many men in this world (sure, and some women , too) have directly caused the death of a child; hell, some men have caused the deaths of thousands of children. Try to imagine it yourself (no, Henry Kissinger, you have to skip this step): because of something you did, or a decision you made from a position of authority, a little boy or girl stopped breathing.
Maybe you ordered a bomb to be dropped on a village. You didn't want to, but the General made it clear that this entire sector had to be clear of enemy forces within two weeks, and you just didn't have the time or the men to check every population center individually.
Maybe you dropped the bomb on that village. You didn't want to, but the alternative was court-martial, and maybe there were Viet Cong down there, just like the Lieutenant said.
Maybe you ran over a little girl crossing the street because you were drunk - or just picking your nose (after all, anything can happen).
Maybe you're the CEO of an extremely profitable corporation that laid off 3,000 workers just before Christmas to increase the value of the stock. Joe, a seriously depressed, 27-year employee, shoots his wife and two kids, and then himself.
Kids die all the time; some times it's the result of an "honest" accident. You still have to figure out how to live with the results of your action, but at least it wasn't your intention. So many children are killed each year, however, by people who went ahead with their action or decision, even though they knew that children would, as a result, die.
So here is my idea: create a website, called www.deathofachild.com, which would be used to propose individuals who are responsible for the death of a child. We would then have an open debate on the Internet about whether or not that individual is responsible or if the charge was unwarranted (the death was, for example, "justifiable" - whatever that might mean - or truly an accident).
Visitors would submit a name and history; those names would be researched by an independent group. If they recommended that there is sufficient evidence, the name and situation would be posted on the website, and let the debate commence. What do you think?
Tuesday, August 01, 2006
Back when I was young and much less mature
I am deeply ashamed of those kinds of statements now. They demonstrated a callousness and also a sort of defensiveness. I understand now that, deep down, I knew that what the PLO was doing was wrong, but I was not confident enough in my beliefs and understanding to take a more nuanced position (the Palestinian people have been hurt grievously by the Israeli Defense Forces over the years, but that never justifies the wielding of violence against innocents). I was also rebelling against any number of things, which had little to do with Israel....
Whatever the explanation, saying things like that not only insulted those who died and grieved, but also degraded me. I was a caricature of a living, feeling, compassionate human being.
When I talk to fellow Jews now and hear them oh so blithely dismiss Israel's devastating attacks on an entire nation (Lebanon), the killing of scores, maybe even hundreds of innocent children, and simply blame it on Hezbollah, never Israel, I hear an echo of my earlier pathetic and immature stance.
When I talk to fellow Jews who are unable to admit that the vaunted Israeli Air Force can do anything wrong, who believe that anything the government of Israel does is, by definition, correct and moral (for example, "The IDF is the most moral military force in the world"), I feel very sad and depressed. I can almost sense their soul going gray, their moral edge going dull, their ability to celebrate all life and all people diminished, their humanity seeping out of them....
Prime number generator for PL/SQL
I have been heads-down, coding and documenting, documenting and coding -- working furiously to meet deadlines that would allow my unit testing tool, code-named Qute (the Quest Unit Test Engine), to go production in October. Wow...what a brain drain.
One of the features offered by Qute is the ability to select test data values from pre-defined groups. And I thought that, what the heck, I would provide a set of prime numbers between 1 and 100, as one of those groups.
To do that, I built a little prime number generator package. It is definitely not anything fancy and I include it below. The generator tries to divide into a given number every integer between 2 and one less than that number. In none of the divide evenly, I've got a prime.
Hey, what can I say? I've got a Bachelors Degree with High Distinction in Mathematics, Summa Cum Laude, from the University of Rochester, 1980. This kind of brute force algorithm comes to me naturally.
Anyway, I also added the ability to generate text that contains the prime number. Here is an example of using the program to generate code that I needed to insert into my Qute install script:
BEGIN
prime_numbers.show_primes (
prefix_in => 'intval_insert ( ''$prime - a prime number'', '''
, suffix_in => ''', is_expression_in => qu_config.c_no);'
);
END;
The code (sorry about the formatting; sometimes I hate HTML - but I have no time to fix this. Use the Toad or SQL Navigator formatter to make it look nice).
Hope you find it useful!
CREATE OR REPLACE PACKAGE prime_numbers
IS
TYPE primes_aat IS TABLE OF VARCHAR2 ( 32767 )
INDEX BY PLS_INTEGER;
FUNCTION is_prime (
number_in IN INTEGER
)
RETURN BOOLEAN;
PROCEDURE show_primes (
start_in IN INTEGER DEFAULT 1
, end_in IN INTEGER DEFAULT 100
, prefix_in IN VARCHAR2 DEFAULT NULL
, suffix_in IN VARCHAR2 DEFAULT NULL
, placedholder_in IN VARCHAR2 DEFAULT '$prime'
);
FUNCTION primes (
start_in IN INTEGER DEFAULT 1
, end_in IN INTEGER DEFAULT 100
, prefix_in IN VARCHAR2 DEFAULT NULL
, suffix_in IN VARCHAR2 DEFAULT NULL
, placedholder_in IN VARCHAR2 DEFAULT '$prime'
)
RETURN primes_aat;
END prime_numbers;
/
CREATE OR REPLACE PACKAGE BODY prime_numbers
IS
FUNCTION is_prime (
number_in IN INTEGER
)
RETURN BOOLEAN
IS
c_limit INTEGER := ABS ( number_in );
retval BOOLEAN DEFAULT TRUE;
divisor INTEGER := 2;
BEGIN
WHILE ( divisor < c_limit AND retval )
LOOP
retval := MOD ( number_in, divisor ) <> 0;
divisor := divisor + 1;
END LOOP;
RETURN retval;
END is_prime;
FUNCTION primes (
start_in IN INTEGER DEFAULT 1
, end_in IN INTEGER DEFAULT 100
, prefix_in IN VARCHAR2 DEFAULT NULL
, suffix_in IN VARCHAR2 DEFAULT NULL
, placedholder_in IN VARCHAR2 DEFAULT '$prime'
)
RETURN primes_aat
IS
retval primes_aat;
BEGIN
FOR indx IN start_in .. end_in
LOOP
IF is_prime ( indx )
THEN
retval ( retval.COUNT + 1 ) :=
REPLACE ( prefix_in, placedholder_in, TO_CHAR ( indx ))
|| TO_CHAR ( indx )
|| REPLACE ( suffix_in, placedholder_in, TO_CHAR ( indx ));
END IF;
END LOOP;
RETURN retval;
END primes;
PROCEDURE show_primes (
start_in IN INTEGER DEFAULT 1
, end_in IN INTEGER DEFAULT 100
, prefix_in IN VARCHAR2 DEFAULT NULL
, suffix_in IN VARCHAR2 DEFAULT NULL
, placedholder_in IN VARCHAR2 DEFAULT '$prime'
)
IS
l_primes primes_aat
:= primes ( start_in, end_in, prefix_in, suffix_in, placedholder_in );
BEGIN
FOR indx IN 1 .. l_primes.COUNT
LOOP
DBMS_OUTPUT.put_line ( l_primes ( indx ));
END LOOP;
END show_primes;
END prime_numbers;
/
Wednesday, July 26, 2006
Is IKEA totally insane?
I opened up my Chicago Tribune (which means I took out of not one, but two separate plastic bags an enormous pile of paper, some of which is news and most of which are ads) and found within it the 370-page 2007 IKEA catalogue. Glossy, heavy paper, full color, etc.
The Chicago Tribune has a Sunday circulation of 950,582.
So about 1,000,000 people received this very-expensive-to-print catalogue. And what will most of them do with it?
OK, honestly, I don't really know. Perhaps 950,582 Chicagoans have a strong attachment to IKEA (just one "Chicago-area" locations out in the Northwest suburbs) and will treasure this catalogue. Realistically, I've got to think that hundreds of thousands of these catalogues will be thrown away, not even recycled (Chicago's recycling program is a joke, a travesty, very pathetic).
What an awesome waste of money and disgusting addition to the region's landfills.
PS: If you don't have a 2007 IKEA catalogue, would like one, and live in the US, I will send mine to you. Please let me know (include address).
Profoundly distasteful
Anyway, the main, pschotic character marries into a rich family and gets his own chaffeur. And as I watched the driver open the limo door for this character and other members of the family, I found myself squirming uncomfortably.
What was making me uncomfortable? Ah, yes, the fact that this guy had a personal servant. That got me thinking about various things that I find profoundly distasteful.
So I thought I would share them with you (you are so lucky!). Here goes:
Personal servants: I am not a history major, but my understanding/belief is that part of what the colonists rebelled against in their war for independence was the ariostcracy that sucked the lifeblood out of British subjects. We don't officially have a inherited-wealth aristocracy anymore (though we will soon, if the estate tax is fully repealed), but it seems to me that the best way to define an aristocrat is a person who has personal servants. I find this really bothersome. I don't like to have people taking care of my personal needs. I am pschologically unable to let someone shine my shoes for me, for example. I am not convinced that there is a qualitative, rather than quantitiative, difference between personal servants and slaves. I sense that hiring someone to dress you, buy things for you, drive you around, etc., is a corrupting process. [ Having said all that, we pay a woman named Walentyna to visit our house weekly and clean up for us. So I am a hypocrite. Isn't that a part of being a human who is not a saint? ]
Commercials: I like to watch television programs -- way too much. So perhaps I am fortunate that I have close to zero tolerance for TV commercials and advertisements generally. I see it as a kind of bargain with the devil: we will give you "free" programming if you will subject yourself to our propaganda. I continue to be totally amazed that companies will pay billions of dollars to produce and distribute/present advertisements. I have probed deep within and truly believe that ads have a very minimal influence on my decision-making. But obviously ads do work -- companies would not throw away their money. Which makes me feel very sad for those whose minds are twisted around to follow the trail of compulsion to make purchases that they would otherwise not make. BMW makes a cool car ad, so I should then want to buy a BMW? Why would you trust or let yourself be influenced by anything you see in an ad? [ If you do not already know about Consumer Reports, visit www.consumerreports.org and join this wonderful organization! Then you can skip the commercials, visit this website, and obtain an objective, thorough review and recommendation of things you want to buy. If millions of people joined CR, we could band together and publicly reject commercials...]
Laugh tracks: Even if I can make it past the ads to watch a TV program, if it has a laugh track, those sounds are like fingernails scratching a blackboard. I cannot abide being told when to laugh, what to find funny. It is a very subversive, low-level form of coercion.
"He (she) is such a good baby." I shudder every time I hear someone say this (especially if it is the parent of the baby). How can a baby be anything but good, wonderful, incredible, beautiful, astonishing? Really, babies aren't good or bad, they are just sponges soaking up the world, responding to stimulation.
Monday, July 24, 2006
Miss Congeniality 2006
It's because I am super, tremendously busy, and I should tell you all about that.
And because I am so super, over-the-top busy, I have to stay very focused.
But here I was just a moment ago staring at Miss Congeniality 2006.
What is my excuse and why am I telling you about it? Okay, you said you wanted to know.
I zipped over to MyYahoo to check the latest headlines, see how many more innocents had been killed by Israel's ferocious, unconscionable bombing of Lebanon, and by Hezbollah's own set of war crimes: shooting missiles at Israeli towns.
And there, the word Puerto Rico caught my eye:
Miss Puerto Rico crowned Miss Universe, collapses
A few years ago, we bought an old coffee farm (derelict, really just a small out of the way mini rain forest) on the western side of Puerto Rico. So I am interested in all things PR.
Well, I followed the link, eventually ending up at missuniverse.com. I noticed the Miss Congeniality prize and, having enjoyed Sandra Bullock tremendously in Miss Congeniality 1 and been horribly disappointed in Miss Congeniality 2 (a perfect example of a movie which definitely does not warrant a sequel!), I had to take a look at Miss Congeniality 2006.
As one might expect, Angela Asare of Ghana is absolutely stunning.
But I must admit to you, she doesn't look all that congenial. I find it very amusing that the Miss Universe entity would use this photo for her Miss C award....
Anyway, back to work, tell you about it soon!
Oh and congratulations to Zuleyka Rivera! You are welcome to visit my old finca any time....
Sunday, June 25, 2006
Report from ODTUG, Washington DC 2006
Well, back to ODTUG. I was very fortunate that my wife, Veva, came with me. As a result, I stayed longer and was in a better mood than usual. See, when I go to conferences, I mostly just want to go back home as soon as possible, to be with my family and get back to my comfort zone of programming and writing. With Veva around, however, I actually attended some of the social events!
Here are some PL/SQL-related ODTUG highlights:
1. Quest announced that it had acquired my two tools, Qnxo and Qute. We are now working hard to prepare Qute, a revolutionary unit testing tool for PL/SQL developers, for general availability at Oracle Open World 2006 (October 2006). You can download, try and give feedback on Qute by visiting www.unit-test.com.2. The ODTUG board of directors announced on Monday that it would henceforth be sponsoring and organizing an annual PL/SQL training conference, chaired by, well, me. I held the first PL/SQL conference, Oracle PL/SQL Programming 2005, last November. Attendees enjoyed it greatly and immediately clamored for another in 2006. We are not yet sure of the date and location for this event, but I am very pleased to be working closely with ODTUG for future PL/SQL events. More news to come.
3. Lots of well-attended PL/SQL sessions. As Lucas Jellema of AMIS mentioned at the start of his Wednesday presentation, he has discovered the secret to a successful ODTUG session: put "PL/SQL" in the title. Not only were there a goodly number of PL/SQL presentations, but there were some new and very interesting ones, including: "PL/SQL for Dummies" by Paul Dorsey and Michael Rosenblum, authors of a new book by the same name; "Design Patterns in PL/SQL: Pre-inventing the Wheel" by Lucas, a fascinating look at how we in the PL/SQL world can leverage the concept and power of design patterns in our work; . Oh, and I gave two talks, one on "SQL games we can play in PL/SQL" and "Six simple steps to unit testing happiness"— I think they went well. I guess I will find out when I see the evaluations!
But as wonderful as all of the above happenings were, for me by far the absolute highlight of ODTUG 2006 was Bobert Dorsey. Bobert is 6 months old, the son of renowned author and teacher, Dr. Paul Dorsey, and his wife, Illeana Balcu. Bobert's real name is Robert, but he goes by Bobert (as well as "What a cute baby!"), he has wonderfully big round cheeks, and an incredibly friendly disposition. We got along famously.
As you well know, I enjoy PL/SQL greatly, but I would much rather hold, play with, and talk to babies any and every time. After all, who and what can be more important to humanity than its children? When I see a baby, I am totally shameless about asking his or her parent if I can hold him/her. Just ask Paul when you see him next. Thanks, Paul and Illeana, for being so generous and trusting!
For some additional commentary on the ODTUG show check out:http://www.rittman.net/archives/2006/06/odtug_day_2_keynotes_bi_presen.html
http://technology.amis.nl/blog/?p=1233
And I strongly encourage you to read Lucas' (and other Amis consultants') recent writings on PL/SQL, which do a great job at getting us to think about different ways to use PL/SQL.
Tuesday, May 23, 2006
The sidewalks of Prague
I think the sidewalks caught my attention so dramatically because my views on ornamentation in architecture and public space generally have been changing. I used to be a "form follows function" kind of guy: I appreciated the clean lines of modern design and scorned elaborate designs that didn't seem to really do anything. If it isn't "doing" anything, then why waste time, effort and money building it?
Then I came across the writings of the architect Christopher Alexander. Alexander has developed a healthy dislike for modern architecture and believes that it is possible to come up with a "pattern language" that is universal and can help us design and build structures that improve our quality of life on multiple levels.
Alexander has in recent years published his "Nature of Order" series of books, which argue for the place of ornamentation in our architecture and other aspects of human creativity. I have come to agree and urge you to check out his writings, especially: The Timeless Way of Building and the Nature of Order series.
These sidewalks not only reflect a wonderful aesthetic, but also a very smart practicality. In Chicago and many/most US cities, the sidewalks are slabs of concrete. Very dull and in many ways not all that functional. With the extreme temperatures of Chicago, the concrete usually cracks shortly after it is laid in place. And in the many tree-shaded sidestreets of Chicago's numerous neighborhoods, roots cause the most delightful disruptions in the straight surfaces of the sidewalks.
Prague has similar problems with tree roots and wide fluctuations in temperature. Their "mosaic" sidewalks offer something of a solution. As temperature changes cause movement in the ground, the individual cubes will shift and sometimes pop out, but they are easily repaired, since the damage is much more localized.
Saturday, May 13, 2006
KUMU: the sparkling new Kunst (Art) Museum of Estonia
I started the day by heading to KUMU, the sparkling new Kunst (Art) Museum of Estonia. It is a remarkable building with an excellent array of creativity. Whenever I visit a city for the first time, I always seek out the main art museum/gallery. I believe that one of the most human (that is, beyond mammalian) acts is to create, and art (a creation that is generally not tied to concrete purpose or objective, as compare to, say, an automobile or microwave machine) is the most direct expression of the mind (of course, functional objects often are works of art as well). I feel so fortunate to have been able to visit places like the Prado, London's National Gallery, Amsterdam's Rijksmuseum, and many more over the years.
The most striking of all the works I saw at KUMU was Ever is Over All by Pipilotti Rist. Here is a description of the work: "In Ever Is Over All, a young woman in a light blue dress merrily walks along the street with a huge, colorful, long-stemmed tropical flower in her hand. She smashes the flower into the windows of parked cars as she passes them."
That sort of captures a part of the work. At KUMU, it was projected onto two walls of a large room (each wall perhaps 25 feet in length). One wall shows the woman strolling down the street and occasionally and clearly with great exuberance smashing a car window. The other wall shows a field of the flowers the woman is holding (not that it could really be one of those flowers, as it pretty smoothly breaks through car glass). As and after she breaks a window, the woman is enraptured. A policewoman walks by at one point and salutes her. And rolling over all the action is very melodic, slightly haunting music.
I found it very exhilarating. I hope at some point it will be fully viewable from the web; do check out her website to see some of her other pieces. I took a fifteen second clip of the piece, but I don't want to post it without her permission.
OK, it is now 7:45 PM, and the sun is still very high in the sky. Time to venture forth once again from the Radisson and wander the Old Town.
Thursday, May 11, 2006
Letter from Scandinavia and the Baltics
I am on a whirlwind sweep through Scandinavia, doing Best Practice PL/SQL seminars for Oracle Corporation in
Interest in PL/SQL in northern
I had a bit of a rough start, though. I boarded the 10 PM SAS flite to
I wasn't sure what telephone service back to the
Another big step for me on this trip is that I finally broke down and bought an MP3 player. First, I tried the Sony Bean. I love its compact form, but its one-line screen (yes, that is not a typo. Just one visible line of text at a time) was beyond the capabilities of this middle-aged programmer. So I traded that for a Creative Zen Microphoto. 8GB capacity and a slide bar that I still have lots of trouble with, but is at least manageable. I loaded up some 50 CDs, added Shure e3c noise canceling headphones, and I was so ready to liven up by hours at the airport and on planes (I am, after all, traveling on nine different airplanes in 10 days) with my favorite music.
But then reality set in: I don't really like having anything stuffed into my ears or even covering them (those Bose noise cancelling headphones work very well, too, but they make my head ache). So I haven't been using my wonderful gadgets at all....I now plan to return them all when I get back to
Thursday, April 13, 2006
Obsessive, compulsive me
[ Note: I put "suffer" in quotes because pretty clearly I haven't actually suffered, in fact, I have benefited from my obsession. I also use quotes because I generally find objectionable the tendency of medical professionals to give names to behaviors and medical conditions they don't necessarily really understand or are outside the norm. ]
And then there is my attitude towards GUIDs. I talked about these "Globally Unique Indentifiers" earlier in my blog. A GUID is a long sequence of characters that are supposed to be globally unique -- that is, the likelihood of a particular sequence of characters appearing (returned by the GUID generating function) more than once on any computer running on our globe is miniscule. Thus, you can use GUIDs when you need unique values that span, say, database instances or multiple networks.
I just ran into the need to generate about a dozen GUIDs for new assertions I have defined in Qute, the Quick Unit Test Engine. Unfortunately, I forgot to enable output to the screen for my block of code, so I could not use those GUIDs.
And I found myself feeling sad, a sense of loss. I found myself thinking: I just wasted those GUIDs. They will never reappear (as I would ever know!), they are gone forever.
Worrying about "losing" or "wasting" GUIDs? Now, that's surely a bit obsessive!
Time to enable output, run my script again, grab those GUIDs, and get on with my life!
Friday, April 07, 2006
Soduku and PL/SQL
Hello Steven,To check out Phillip's implementation of a Sudoku puzzler, click here.
I'm not sure how much Sudoku puzzles have caught on in the US, but they are fairly big in the UK, particularly in all of the daily papers. Well I've probably been using PL/SQL much too long or probably am well due for retirement out of computers, but I was presented with a challenge the other day which some might consider quite sad. I wrote a Sudoku puzzle solver in SQL and PL/SQL which solves most puzzles presented to it.
The proud thing about it is that a colleague of mine who gave me the idea wasn't able to get his MS Excel VBA solution to work properly. Another colleague also took up the challenge, and again could not get his Java solution to fully work and has spent weeks compared to my days programming it. I'm not sure whether this is saying something for SQL and PL/SQL, but in any event I thought you might be interested. This could be a great opportunity to see whether anyone can use an alternative language to write a solution in less lines of code than a PL/SQL solution - now that would be a challenge!!
Thursday, April 06, 2006
PL/SQL + PDF = PL/PDF - PDF docs from PL/SQL programs!
PL/PDF - http://plpdf.com
"Generate dynamic PDF documents from data stored in Oracle databases using the PL/PDF program package. PL/PDF is written exclusively in PL/SQL. It is able to either store the generated PDF document in the database or provide the results directly to a browser using MOD_PLSQL. No third-party software is needed; PL/PDF only uses tools provided by the installation package of an Oracle Database (PL/SQL, MOD_PLSQL). Use PL/PDF to quickly and easily develop applications with dynamic content but also quality presentation and printing capabilities."
Sounds like fun! I have only played around with PL/PDF a little bit, but it looks like they have put together a very nice, clean API to the underlying functionality, making it extremely easy to use PL/PDF. To give you a sense of that, check out the explanation of their approach.
You can trial PL/PDF by downloading the software and specifying 'TRIAL' word as the certification key. Limitations: max. 5 pages, watermarked pages.
My compliments and best wishes to Laszlo Lokodi and others at PL/PDF for showing how useful and flexible PL/SQL can be!
Tuesday, March 14, 2006
Some gotchas with Oracle XE
I ran into a couple of glitches, however, that I thought I would share:
1. UTL_FILE is not available. Usually, when you install Oracle, the UTL_FILE package (used to read/write files within PL/SQL) is installed, EXECUTE is granted to PUBLIC, and a public synonym is created. With XE, the package is installed and the synonym created, but the GRANT EXECUTE has not been run.
To fix this problem, connect to a SYSDBA account and run the $ORACLE_HOME/RDBMS/Admin/utlfile.sql file, or simply execute this command (from a SYSDBA account):
GRANT EXECUTE on SYS.UTL_FILE TO PUBLIC
/
2. Oracle XE does not include a Java Runtime Environment. I have been using some Java classes, installed in the database, in my unit testing product, Qute. Here is an example of a call to this Java code:
PROCEDURE parse_package (
owner IN VARCHAR2
, package_name IN VARCHAR2
, program_name IN VARCHAR2
)
AS
LANGUAGE JAVA
name 'quPlSqlHdrParser.parsePackage(
java.lang.String, java.lang.String, java.lang.String)';
In pre-production versions of Oracle XE, the code compiled, but then raised runtime errors, sometimes ORA-00600, which are not trap-able with an exception section.
The production version still does not include a JRE and even worse, if you install the Oracle Database 10g Express Edition (Western European; " Oracle Database 10g Express (Western European) Edition - Single-byte LATIN1 database for Western European language storage, with the Database Homepage user interface in English only.") then the above code will not even compile. Very strange. Oracle seems to actually be looking at the literal string and attempting to validate it at compile time.
Yet if I install the Oracle Database 10g Express Edition (Universal; Multi-byte Unicode database for all language deployment, with the Database Homepage user interface available in the following languages: Brazilian Portuguese, Chinese (Simplified and Traditional), English, French, German, Italian, Japanese, Korean and Spanish), then I do not get a compilation error.
Sunday, March 05, 2006
Ah, the good old days of high mileage vehicles....
I now own a Honda Insight, the two-seater hybrid they released in 2000. Got mine in April 2000 and since then have averaged 49.8 MPG for some 46,000 miles. I love that car, too.
Got up this morning and somehow ended up going through the backroom in our basement, clearing out old stuff (and getting lungfuls of dust in the process) and came across a reminder of another Honda Civic I leased, and how far we haven't come in the last couple of decades.
Back in 1992, I left Oracle Corporation and become a consultant. Took a job working at McDonald's headquarters in Oak Brook -- and suddenly I was a commuter. So I looked around at my options and found the Civic VX. The VX was a Civic coupe with a VTEC engine adapted from the early Acura Integra.
It cost $10,550, which was considered fairly pricy for a little car back then, and boasted the following mileage:
Highway MPG: 55
City MPG: 48
Of course, I didn't hit those numbers, just like I only occasionally match the EPA MPG ratings for the Insight. But I clearly remember averaging MPGs in the 40s on the highway commutes I made to BurgerLand.
That was back in 1992-93!
So while I am glad to have my Insight (I really, really enjoy driving that car, even though its suspension is, shall we say, a bit brittle), I am also disappointed that the auto companies haven't come further in 14 years.
Sunday, February 26, 2006
PL/sql Experts Determined to Give their Expertise -- ???
PLEDGE -PL/sql Experts Determined to Give their Expertise
Let's face it: not all developers are equal. We have widely varied levels of skill, experience and communications abilities. Any such group of professionals has a tiny subset of members who are perceived as the "elders" (aka, gurus, experts, etc.) -- and age has little to do with this status. I feel strongly that those of us in the PL/SQL world who are deeply experienced should come together to make our contributions more visible and widely available to the worldwide PL/SQL community.
Disclosure: I am especially desirous of a group like this, and will benefit greatly from it, because I cannot possibly answer all the questions that come my way (either because my time is limited or the question involves how PL/SQL code interacts with technologies like XML or Java, about which I have little experience). I would like to formalize the group of people I can turn to, to assist me in such matters. But I certainly don't want to limit it just to helping me answer my questions.
What is PLEDGE?
PLEDGE is (would be) a group of highly experienced PL/SQL developers who are committed to sharing their knowledge and code with others, at no cost.
I bet you are already thinking one or more of the following:
- Should PLEDGE be a part of IOUG?
- Should PLEDGE be or is it the same as a PL/SQL SIG?
As to whether it should be a part of IOUG, I don't have strong feelings about that right now. See my comments in the section titled Resources below. I am not sure that this would be consistent with an IOUG entity.
How would PLEDGE work?
Here are some initial thoughts/guidelines...
1. PLEDGE has members and guests.
2. A PLEDGE member is a PL/SQL expert who has agreed to contribute her or his time/effort to improve the skills, productivity and code quality of the worldwide PL/SQL community.
3. A PLEDGE guest is a developer who has registered with PLEDGE so as to take advantage of the resources offered by PLEDGE, participate in forums and so on.
4. There is no cost associated with any level of participation in PLEDGE.
5. A PLEDGE member or user can post a challenge/requirement to PLEDGE, and then a member can volunteer to implement/guide/answer that challenge.
6. All code that is posted on the PLEDGE website needs to be documented, tested and testable (preferably with a Qute harness; check out www.unit-test.com for my latest and greatest product/concept).
Resources needed
This community needs to be supported by commercial vendors who are committed to the Oracle space. I do not believe that we can make it work the way it should with only volunteer time contributed, though it is certainly a possibility....
I do believe that any number of vendors could provide a base of support, including Quest and Oracle.
Areas of expertise
We need general PL/SQL pros, but also people who have specialized in various areas of technology that commonly connect to PL/SQL, including but not limited to:
- Java-PL/SQL interface
- .Net-PL/SQL interface
- VB-PL/SQL interface
- Using XML in PL/SQL
- Oracle Applications and PL/SQL
- Object-Oriented development with PL/SQL
Monday, February 20, 2006
Gambling addictions
An article in today's Chicago Tribune drives that point home, based on data gathered by the Center for Responsive Politics:
In 1990, the gambling industry "contributed" $478,000 to federal campaigns (that is, the "war chests" of individuals running for federal office, or more to the point, running to keep their position in Congress or control the Oval Office).
In 2004, that same industry forked over $13 million. Here are the top 5recipients from the 2004 election cycle:
1 | Bush, George W (R) | Pres | $345,610 |
2 | Reid, Harry (D-NV) | Senate | $309,713 |
3 | Porter, Jon (R-NV) | House | $243,968 |
4 | Berkley, Shelley (D-NV) | House | $199,441 |
5 | Daschle, Tom (D-SD) | Senate | $193,900 |
So who is addicted to gambling? I would venture to guess that our elected officials (I hestiate to call them our representatives, because it seems to me that they more closely represent corporate interests and CEOs, not the rest of us) fit the bill very nicely.
Sunday, February 19, 2006
Watch out for sequential Oracle GUIDs!
A GUID is a long sequence of characters that are supposed to be globally unique -- that is, the likelihood of a particular sequence of characters appearing (returned by the GUID generating function) more than once on any computer running on our globe is miniscule. Thus, you can use GUIDs when you need unique values that span, say, database instances or multiple networks.
My latest obsession is a product named Qute - the Quick Unit Test Engine. You can find out more about it at www.unit-test.com. We use GUIDs for primary keys; this makes our work substantially easier since the product and underlying data are installed on a user's computer, and we do not have to worry about possible conflicts with sequence-generated primary key values.
The Delphi frontend in Qute also takes those GUIDs and hashes their values to integers, which are then used to index arrays of data and speed up access to browser data. All fine so far.
Unfortunately, a number of users reported an error involving a "Hash Mismatch" on starting up of Qute. After lots of patient cooperation from those users, we were amazed to find that the Oracle SYS_GUID function (the GUID generator offered by Oracle) was returning sequentially-incremented values, rather than pseudo-random combinations of characters.
We then had a bug in our Delphi code such that the hashing algorithm was set to "quick and not very secure" -- meaning that strings which were not very different were hashing to the same number, which then triggered our error. We adjusted that algorithm, making it more robust, and the problem seems to have disappeared. But I thought I should let the world know about our experience.
To see if you have this issue in your installation of Oracle, run the following script:
SET SERVEROUTPUT ON
BEGIN
FOR indx IN 1 .. 5
LOOP
DBMS_OUTPUT.put_line ( SYS_GUID );
END LOOP;
END;
/
You should see five rows of wildly different values, like this:
E9DF272C0D284B338E27455430022D67
B513F57A646E4136AB220BAE52A0F6E8
A95CBEE73C404E52A28608FFFFE209DA
6F28A3D06E7143868E8E4AF92F43A085
4095D2129505456A9F6B2C001F06EDF7
But some Qute users on AIX and Compaq 64bit operating systems were instead seeing results like this:
0CC2D8AF5A0A6C9FE044080020C482B7
0CC2D8AF5A0B6C9FE044080020C482B7
0CC2D8AF5A0C6C9FE044080020C482B7
0CC2D8AF5A0D6C9FE044080020C482B7
0CC2D8AF5A0E6C9FE044080020C482B7
See the difference? The algorithm that Oracle is using on these operating systems is clearly faulty; yes, the values are unique but they are far from even pseudo-random.
The moral of the story is: if you are going to rely on the Oracle SYS_GUID function to generate GUID values, test the algorithm and make sure you are satisfied and can live with the results.
Going Global with GUIDs
Steven Feuerstein, Copyright 2005
Originally published in Oracle Professional, Ragan Communications
What is a GUID?
You've probably heard about and even seen some funky-looking string that is referred to as a "GUID". This article explains what a GUID is, how they can be very useful, and how you can work with them inside Oracle.
Let's start with a formal definition of a GUID, taken from Wikipedia (http://en.wikipedia.org/wiki/GUID):
"A Globally Unique Identifier or GUID is a pseudo-random number used in software applications. Each generated GUID is "mathematically guaranteed" to be unique. This is based on the simple principal that the total number of unique keys (264 or ) is so large that the possibility of the same number being generated twice is virtually zero. The GUID is an implementation by Microsoft of a standard called Universally Unique Identifier or UUID, specified by the Open Software Foundation (OSF)."
Ah! So a GUID is actually the Microsoft version of the UUID, about which Wikipedia tells us:
"A Universally Unique Identifier is an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE). The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. Thus, anyone can create a UUID and use it to identify something with reasonable confidence that that identifier will never be unintentionally used by anyone for anything else. Information labelled with UUIDs can therefore be later combined into a single database without need to resolve name conflicts. The most widespread use of this standard is in Microsoft's Globally Unique Identifiers (GUIDs) which implement this standard.
"A UUID is essentially a 16-byte number and in its canonical form a UUID may look like this:
550E8400-E29B-11D4-A716-446655440000"
So, in point of fact and strictly speaking, a GUID is a special (Microsoft-specific) case of a UUID. Perhaps because "GUID" is easier and more fun to pronounce than "UUID," it is the most common of the two terms, even when used in a non-Microsoft context (as we find in Oracle and as I will be doing in this article). I will continue, therefore, to refer to this number as a GUID.
One comment regarding the "mathematical guarantee" mentioned above: as far as I understand, no one has come up with an algorithm that really does quarantee a unique GUID. It is possible, though very, very improbable, that you could generate a GUID that conflicts with an existing value.
GUIDs are GOOD for...
The core value of a GUID is expressed in a single line of the UUID definition above, namely: "The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination." This statement should get Oracle database programmers thinking about two things:
- Distributed databases: they are certainly a kind of "distributed system." So GUIDs should help us identify unique objects not just in a single instance but across different database instances.
- Primary keys and unique indexes: we use these constraints to "uniquely identify" rows of information within a given relational table. Perhaps a GUID could be used for these situations?
If I am writing code for an application that resides in a single database instance, then GUIDs are probably not very compelling. Suppose I face a different scenario: my application runs on many different instances. Each instance has its own users inserting their own data. On a regular basis, however, data from one instance must be merged into another instance.
In this scenario, reliance on sequence-generated primary keys gives me serious heartburn. Since users are inserting rows independently in multiple instances, sequence values are being used up at different rates. When I move data from one instance to another, I have to assume and program for primary key conflicts of various kinds.
This is exactly the situation I encountered as I built Qnxo (www.qnxo.com). This product provides access to a large and ever growing/changing set of PL/SQL scripts (reusable code and generation templates). Any changes to my central PL/SQL repository must be distributed to users. In my first phase of design and construction of Qnxo, I relied on sequence-generated primary keys. As soon as I realized the error of my ways, I converted as much as possible over to GUIDs.
Let's take a closer look at some of the lessons I learned about applying GUIDs in the PL/SQL environment.
Oracle and GUIDs
To help us work with GUIDs, Oracle provides a SQL function named SYS_GUID, documented as follows:
"SYS_GUID generates and returns a globally unique identifier (RAW value) made up of 16 bytes. On most platforms the generated identifier consists of a host identifier, a process or thread identifier of the process or thread invoking the function, and a non-repeating value (sequence of bytes) for that process or thread."
The difference between a RAW and a VARCHAR2 is that RAW string is not explicitly converted to different character sets when moved between systems by Oracle. This point is critical for GUIDs, since we wouldn't want our GUIDs to be changed as they move from one system to another. Conversely, it is also a non-issue for GUIDS, because the characters used in GUIDs are drawn from a restricted subset of ASCII characters, which are static across all character sets.
This function is also exposed in PL/SQL through the STANDARD package as follows:
CREATE OR REPLACE PACKAGE BODY STANDARD
AS
...
FUNCTION SYS_GUID
RETURN RAW
IS
c RAW (16);
BEGIN
SELECT SYS_GUID ()
INTO c
FROM SYS.DUAL;
RETURN c;
END;
END STANDARD;
I can therefore immediately obtain a GUID from within my PL/SQL program by writing code like this:
DECLARE
l_guid_raw RAW (16);
l_guid_vc2 VARCHAR2 (32);
BEGIN
DBMS_OUTPUT.put_line (SYS_GUID);
l_guid_raw := SYS_GUID;
l_guid_vc2 := SYS_GUID;
DBMS_OUTPUT.put_line (l_guid_raw);
DBMS_OUTPUT.put_line (LENGTH (l_guid_raw));
DBMS_OUTPUT.put_line (l_guid_vc2);
DBMS_OUTPUT.put_line (LENGTH (l_guid_vc2));
END;
/
And here is the output from running this code:
E7D3F9F0A0B24390AA504E79EC132677
6FB0B56BA65C4B1580827575F0DDB602
32
693295E9405D4C7C8B3453E481EF4DA5
32
Formatting for GUIDs
As Wikipedia specified earlier in this article, ""a UUID is essentially a 16-byte number and in its canonical form a UUID may look like this: 550E8400-E29B-11D4-A716-446655440000."
In addition, in many situations, the common presentation format for a GUID is:
{550E8400-E29B-11D4-A716-446655440000}
So as you decide to incorporate GUIDs in your code and underlying database, you should decide how you want to store the GUIDs. You could stick with the unvarnished RAW values, or you could store a formatted version, if that is how the GUIDs are going to be used in your application.
We decided that in the Qnxo, we decided that the GUIDs would be stored with the full formatting, including dashes and the open and close brackets.
Using GUIDs in Oracle tables
Let's look at how we can use GUIDs inside a relational table.
Below I create a table using a GUID as the primary key for a table.
CREATE TABLE guid_table (
pky RAW(16) PRIMARY KEY
, NAME VARCHAR2(100));
When I insert a row into this table, I can use the SYS_GUID function to generate my unique GUID. I try to do it this way:
INSERT INTO guid_table
VALUES (SYS_GUID, 'Steven');
but I get the following error:
ORA-00984: column not allowed here
As with
DECLARE
l_pky guid_table.pky%TYPE;
BEGIN
l_pky := SYS_GUID;
INSERT INTO guid_table
VALUES (l_pky, 'Steven');
l_pky := SYS_GUID;
INSERT INTO guid_table
VALUES (l_pky, 'Sandra');
END;
/
Now I can select the data from this table:
SQL> SELECT * FROM guid_table;
PKY NAME
-------------------------------- ---------------
DF832F19657645A2866E7AD15E9F59AF Steven
5FBAB1A92157434EBDBDB5880556D151 Sandra
That's certainly easy enough! Of course, since we want to make certain that a valid GUID is placed is in this column, it would be best to encode that logic into a BEFORE INSERT trigger on this table, as in:
CREATE OR REPLACE TRIGGER guid_table_bi
BEFORE INSERT
ON guid_table
FOR EACH ROW
BEGIN
IF :NEW.pky IS NULL
THEN
:NEW.pky := SYS_GUID;
END IF;
END;
/
And I can now insert into this table as simply as this:
INSERT INTO guid_table
(NAME
)
VALUES ('Joe'
);
In the case of Qnxo, since we decided to store the formatted version of the GUID, we created tables with primary keys defined as follows:
CREATE TABLE sg_favorite (
universal_id VARCHAR2(38) PRIMARY KEY
...
);
Encapsulating Oracle's GUID function
If you decide that you want to work with Oracle GUIDs in the RAW format and never need to deal with the formatted version, then you are pretty much ready to go. If, on the other hand, you want to able to work with GUIDs in a "standard" format, you may want to take advantage of the guid_pkg I wrote to assist in Qnxo development.
The elements in the package are:
guid_t
A SUBTYPE that encapsulates the RAW(16) declaration of a GUID and gives it a name. With this subtype in place, you can declare GUIDs in your code as follows:
DECLARE
my_guid guid_pkg.guid_t;
formatted_guid_t
Another SUBTYPE, this time designed to allow you to easily and readably declare variables that hold a formatted GUID, used as follows:
DECLARE
my_guid_with_brackets guid_pkg.formatted_guid_t;
c_mask
A mask that specifies the valid format for a formatted GUID. It also serves as a wildcarded string that I can use within a LIKE statement to determine if a string matches the standard GUID format.
is_formatted_guid
A Boolean function that returns TRUE if the string passed to it has a format consistent with the standard GUID format.
formatted_guid (2)
Two overloadings of functions that return a formatted GUID. In the first overloading, you pass a string, which could be a RAW GUID value or a VARCHAR2 string. It will return a string containing the GUID in the standard format (as specified by c_mask).
Here is a script that exercises this package:
DECLARE
l_oracle_guid guid_pkg.guid_t;
l_formatted_guid guid_pkg.formatted_guid_t;
PROCEDURE bpl (val IN BOOLEAN)
IS
BEGIN
IF val
THEN
DBMS_OUTPUT.put_line ('TRUE');
ELSIF NOT val
THEN
DBMS_OUTPUT.put_line ('FALSE');
ELSE
DBMS_OUTPUT.put_line ('NULL');
END IF;
END;
BEGIN
DBMS_OUTPUT.put_line (guid_pkg.formatted_guid);
bpl (guid_pkg.is_formatted_guid (guid_pkg.formatted_guid));
bpl (guid_pkg.is_formatted_guid (SYS_GUID));
bpl (guid_pkg.is_formatted_guid ('Steven'));
DBMS_OUTPUT.put_line (guid_pkg.formatted_guid (SYS_GUID));
DBMS_OUTPUT.put_line
(guid_pkg.formatted_guid ('B16079A0567148608C171FA89E7187B3')
);
END;
/
With this output after execution:
{B33204AD-ADDB-4CC6-87F2-2D0D13594F7C}
TRUE
FALSE
FALSE
{1F17C465-E58E-4F8B-AABA-9C1C712D992B}
{B16079A0-5671-4860-8C17-1FA89E7187B3}
Listing 1. The specification of the guid_pkg package
CREATE OR REPLACE PACKAGE guid_pkg
IS
SUBTYPE guid_t IS RAW (16);
SUBTYPE formatted_guid_t IS VARCHAR2 (38);
-- Example: {34DC3EA7-21E4-4C8A-BAA1-7C2F21911524}
c_mask CONSTANT formatted_guid_t
:= '{________-____-____-____-____________}';
FUNCTION is_formatted_guid (string_in IN VARCHAR2)
RETURN BOOLEAN;
FUNCTION formatted_guid (guid_in IN VARCHAR2)
RETURN formatted_guid_t;
FUNCTION formatted_guid
RETURN formatted_guid_t;
END guid_pkg;
/
The implementation of this package is shown in Listing 2. It relies on the SYS_GUID function to generate a new GUID value, but otherwise is devoted to applying the format mask and converting un-formatted GUIDs to strings that contain the correctly-placed hyphens.
Listing 2. The body of the guid_pkg package
CREATE OR REPLACE PACKAGE BODY guid_pkg
IS
FUNCTION is_formatted_guid (string_in IN VARCHAR2)
RETURN BOOLEAN
IS
BEGIN
RETURN string_in LIKE c_mask;
END is_formatted_guid;
FUNCTION formatted_guid (guid_in IN VARCHAR2)
RETURN formatted_guid_t
IS
BEGIN
-- If not already in the 8-4-4-4-rest format, then make it so.
IF is_formatted_guid (guid_in)
THEN
RETURN guid_in;
-- Is it only missing those squiggly brackets?
ELSIF is_formatted_guid ('{' || guid_in || '}')
THEN
RETURN formatted_guid ('{' || guid_in || '}');
ELSE
RETURN '{'
|| SUBSTR (guid_in, 1, 8)
|| '-'
|| SUBSTR (guid_in, 9, 4)
|| '-'
|| SUBSTR (guid_in, 13, 4)
|| '-'
|| SUBSTR (guid_in, 17, 4)
|| '-'
|| SUBSTR (guid_in, 21)
|| '}';
END IF;
END formatted_guid;
FUNCTION formatted_guid
RETURN formatted_guid_t
IS
BEGIN
RETURN formatted_guid (SYS_GUID);
END formatted_guid;
END guid_pkg;
/
GUIDs: a nice addition to the toolbox
I'd heard of GUIDs, but never had reason to work with them before developing Qnxo. I started with standard, sequence-generated primary keys in my script table, but found that this approach was sorely lacking when it came time to distribute that content (reusable scripts and templates) to my user base.
By relying on GUIDs, I was able to greatly simplify the logic needed to upgrade distributed content from a central source. Not only did I avoid the problem of conflicting sequence-generated primary keys, but I was also able to keep intact foreign key references, since they were based on unchanging GUIDs.