Subscribe: Gints Plivna blog
Added By: Feedage Forager Feedage Grade B rated
Language: English
cnt pid  create  data  iteration number  join  loan  mon paym  number  oracle  rem loan  select  sql server  sql  time  tot 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Gints Plivna blog

Gints Plivna blog

These are my thoughts... Mostly about Oracle and related things.

Updated: 2018-03-06T12:50:51.944+02:00




Indexes cannot be used for inequalities?For years and years I thought it was true. Now I'd say it's only partially true. OK it is true for b-tree indexes (at least there isn't any reasonable effect of using an index for "not eaquals to"), but for bitmaps it's a different answer though. And I mean generally YES, they can be used :)OK let's look at examples. I'll create a table and populate with almost all the same values but one. That's to make things more attractive for CBO to get the one and only value.SQL> CREATE TABLE test (2 id NUMBER PRIMARY KEY,3 txt VARCHAR2(10) NOT NULL);Table created.SQL> INSERT INTO test2 SELECT rownum, 'AAA'3 FROM DUAL CONNECT BY LEVEL < 10000;9999 rows created.SQL> INSERT INTO test2 VALUES (10000, 'BBB');1 row created.So now I have 9999 of "AAA" and only one "BBB".I won't explain with examples what one can get with b-tree indexes, the best is INDEX FULL SCAN and the example by Richard Foote is here.OK but what if we try bitmap index? Let's create it:SQL> CREATE BITMAP INDEX txt_idx ON test (txt) COMPUTE STATISTICS;Index created.Now let's see what we get for the query we know should get only 1 row:SQL> SELECT * FROM test 2 WHERE txt 'AAA'; ID TXT---------- ---------- 10000 BBB--------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 7 | 7 (0)| 00:00:01 ||* 1 | TABLE ACCESS FULL| TEST | 1 | 7 | 7 (0)| 00:00:01 |--------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - filter("TXT"'AAA')Statistics---------------------------------------------------------- 23 consistent gets 1 rows processedBang! Full scan. Not very promising. OK what if we try to hint the query?At first let's give a soft hint - how about using an index?SQL> SELECT /*+ index(test) */ * FROM test 2 WHERE txt 'AAA'; ID TXT---------- ---------- 10000 BBB--------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|--------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 7 | 826 (0)||* 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 7 | 826 (0)|| 2 | INDEX FULL SCAN | SYS_C009499 | 10000 | | 26 (0)|--------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - filter("TXT"'AAA')Statistics---------------------------------------------------------- 39 consistent gets 1 rows processedWoW! That's actually annoying. Bad plan, many consistent gets. Oracle is using primary key index, but not my brand new bitmap index! I'm disappointed.OK now let's hammer it with the precise hint!SQL> SELECT /*+ index(test txt_idx) */ * FROM test 2 WHERE txt 'AAA'; ID TXT---------- ---------- 10000 BBB-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 7 | 36 (0)|| 1 | TABLE ACCESS BY INDEX ROWID | TEST | 1 | 7 | 36 (0)|| 2 | BITMAP CONVERSION TO ROWIDS| | | | ||* 3 | BITMAP INDEX FULL SCAN | TXT_IDX | | | |-----------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 3 - filter("TXT"'AAA')Statistics--------------------------------------[...]



Unbreakable Oracle documentation

Yes, that's the fact - everyone knowing the real situation will start Homeric laughter. It is down, down, down and down again. To be true sometimes it is also up and running. Unfortunately "sometimes" seems to be more and more rarely. Just now the popular entry point shows following:

Access Denied
You don't have permission to access "" on this server.
Reference #18.3c55293e.1266419217.19d36a

Interesting - is tooooo much to ask Oracle to provide just static htmls (OK there is advanced thing - search feature, however I could also easily use Google instead, at least it is less unbreakable ;) for its users continuously without interruptions more than not?
Or after the grand results of maintenance income there isn't any single $ left for an admin to monitor the resource? Or probably the last reliable box has gone to super functional and alike working MOS?

Chris Warticki in his blog wrote what to do if MOS is down then what? Unfortunately the blog now is (seems to be censored and) closed and for a little while pages are only accessible from google's cache. Most of the people in oracle-l list say they have downloaded oracle documentation locally in a recent discussion about oracle documentation. However it is bit odd for a company providing leading database of the world having income with nine zeroes being unable to provide simple html files without continued interruptions...

Probably that's the reason I more and more have to do something with SQL Server :)




Time after time I'm doing something different than databases and Oracle :) One of these things is woodwork. So around the New Year I finished the most recent one - a shelf. Requirements, design and implementation fully by me. Here it is just attached to the wall.

And now full with stuff. Most of pottery in this shelf is produced by my cousin and her husband.
The hobby started already in school years when we had special woodwork lessons and this probably is one of the best results from these times - a turned wood vessel with amber decor on the top.
Nowadays there are fantastic possibilities to make something from wood on his own compared to Soviet and early post-Soviet times. Tools, paints, lacquers, various components and semi-finished products in shops are far and away more. For example the shelf above also was created using ground glued board, so actually the creation process is not complicated.
One of the most interesting tasks was to restore a few Soviet style chairs as old as myself (i.e ~30 years). Here is a photo with one old chair and one already restored.




Security through obscurity - object names

This post was inspired by question in one of Latvian forums - can we use only numbers in column names. Of course we can do it using quotes but that's starting point into dangerous path of how to write unmaintainable code. But why stop only with tables like C34 and columns 1, 2, 3? There are ways beyond that!
So let's start with the same table names differing only in upper/lower case.
SQL> create table A (big number);
Table created.
SQL> create table "a" (small number);
Table created.

So what are our tables A and a:
SQL> desc A
Name Null? Type
----------------------- -------- -------
SQL> desc a
Name Null? Type
----------------------- -------- -------

A bit strange, isn't it? But that is because all nonquoted identifiers are converted to uppercase so we have to be precise:
SQL> desc "a"
Name Null? Type
----------------------- -------- ------

But we can make things even more obscure! For example how about table and/or column name as space?
SQL> create table " " (A number, "a" number);
Table created.
SQL> select table_name from user_tables;

3 rows selected.

Previous example with 2 rows instead of reported three and next with lost columns definitely could make some nervous people start searching for Oracle bugs.
SQL> create table b (" " number, "  " date);
Table created.
SQL> desc b
Name Null? Type
----------------------- -------- ------

But we can make things better. Why should we use only symbols on keybord? Remember the nice possibility of ALT key and numeric keypad keys. ALT + these keys gives us symbols according to their ASCII values, so just use your imagination. For example ALT+223 gives me this:
SQL> create table abnormal ("▀" number);
Table created.
SQL> desc abnormal
Name Null? Type
----------------------- -------- -------

Nice little black square.
Next level might be making some columns a bit like hidden.
SQL> create table persons (name varchar2(10), "SYSDATE" date);
Table created.
SQL> insert into persons values ('John', sysdate-1);
1 row created.
SQL> select sysdate from dual;
SQL> select name, sysdate from persons;
---------- ---------
John 31-JAN-09

So where our column sysdate was gone? We inserted value sysdate-1 and got back the same sysdate? Although our column was in upper case, so our query column should be used? Naah, we should enclose it in quotes.
SQL> select name, "SYSDATE" from persons;
---------- ---------
John 30-JAN-09

So next time when you are starting to think about table name like C12, numeric column names, column names in quotes or something like that, don't be shy! Use the complete power of obscurity, so making your db more secure. If you'd try hard enough, you'd reach perfection when obscurity is so great that nobody, even you, won't be able to understand anything ;)
And I wasn't even suggesting to replace DUAL in your schema ;)



About experience

Just a few days ago Ryan Watson mentioned one of my articles in his blog post. It really wouldn't be anything important to write about but the first comment by Kevin really amused me and the comment was "Who is this guy and why is he qualified to comment on databases."

Blahhh... My answer was "[..] why does it matter and isn't better just to make reasonable pros and/or cons about the subject?" and Kevin answered with "Experts carry more weight than a novice; a senior Oracle admin with 20 years of experience has more experience to draw on. This is why a senior DBA will make $100 k and novice $20 k."

This was something so immediate and direct statement that let me started to think more about this subject. How much experience means to me? How much it means to other people (virtually) around me? Probably we all know one of the brightest stars in this area good old Don with one of his latest performances here, but undoubtely for all of us - if we don't know other people and they say something, their experience somehow matters. So how much does it matter for me?

1. I definitely have positive experience with some people and know their knowledge and writing style. They have credit in my eyes and I read each their article/statement/whatever else with more caution than on average. Even if the beginning of the message is somehow blurry or overall quality is not that perfect this time. They have to "apply efforts" to their articles to make me angry and sceptic.
2. I definitely have negative experience with a few people and know their usually blurry and washy posts without any resultant technical value. They have really minus credits in my eyes and even if this time they have written something technically sound I'm quite suspect about that. They have to write something really, really good to attract my attention other than sigh "usual crap".
3. I definitely have neutral experience with quite a lot of people. Let's say "nothing special" :) I read their articles only when they are directly related to my particular current needs.
4. People whom I've met the first time or haven't made any particular impression. These are the most complex part. What is my attitude to them? Analyzing my usual behaviour the conclusion is - I start reading the article with some interest and few starting paragraphs should attract my attention. They must be interesting or suitable for my needs otherwise I jump to next article. BUT. I've never (OK almost never :) read the author's CV, last rows about the author how cool he is or whatever else describing his experience. The content of the article is what matters for me.

So people I don't know win over people with negative credit (whose articles I usually even don't read), but lose to people with positive credit (whose articles I usually try to read until the and to find out something valuable).

And returning to the initial comments - what does 20 years of experience mean to me? Most probably nothing. At least initially. 20 years ago there was Oracle 6, how does it help for today's work? Most probably in almost no way. I'd say that a few years for an inquiring and smart mind is enough to deserve more than a person with 20 years experience stalled in Oracle 8. Actually he wins without any doubt at all.

The (quality of) content is what matters - this is the conclusion. At least for people I don't know :)



Advanced Oracle Troubleshooting by Tanel Poder..

.. is over. His seminar in Riga was real fun for two days. It was different from the big guys' seminars I've attended before (for example, Thomas Kyte and Jonathan Lewis). Not in the way that it was or wasn't somehow better or not, but in the way that Tanel spoke more about:

  • internal memory structures (x$ tables), process stacks, Oracle kernel functions and their mapping to SQL statement execution plan steps;
  • understanding structure of library cache, process state objects, buffer cache;
  • dumping cursors, trace buffers, process stack;
  • systematic troubleshooting a session and finding the root cause of slowness and what it is doing now;
  • and many more subjects.

Lots of live demos, nothing like an Oracle documentation rephrase, narrative explanation of quite advanced technical things - these were the main characteristics of this seminar.

Some previous understanding of Operating systems basic functions, commands and Oracle architecture however is a must, otherwise you simply will be overwhelmed by new information and won't be able to follow the main idea. On the other hand I'm absolutely not a sysadmin and/or true DBA, but I understood let's say 95% of the material provided ;)

So the conclusion is - I definitely recommend it for the people interested in these topics.



Data modelingTime after time it is worth to remember (or learn) basic theory. One of them, which is very important when creating new systems, is data modeling. I'm quite sure most of the DBMS people have seen one or another data model with tables, columns, primary and foreign keys. However the theory of data modeling says that this is only one level out of three. Unfortunately I've seen quite many cases when people have forgotten two another levels. So let's remember what they are.Conceptual data modelConceptual data model contains entities, relationships and attributes. One can draw them using different notations for example ER modeling or UML, but the idea remains the same - this model doesn't know anything about the underlying DBMS. This model is the same for Oracle, SQL Server, DB2, MySQL, whatever else. So why is it important? It speaks in business language and uses terms only from business users, not any programmer's or IT person's hacks.It is normalized, every piece of information is stored only once.It displays common structures and tries to aggregate them, it is easier to find them in such model.It is readable (after a short introduction probably) by every sensible customer.It doesn't contain any reference to any particular DBMS, so one can easily reuse it for ultimately any DBMS.So the question - have you used it? If not - why? Are you aware of possible data waste dangers?Logical data modelThis is the model people usually use. It contains tables, columns, primary keys, foreign keys, unique keys. Some characteristics of it are:It is created on the basis of conceptual data model, but it might not correspond 1:1 to it. For example some entities might be split, some unioned.It may contain some programmer's hacks for example different flag columns for easier data selection.It is aware of used DBMS. For example data types for columns are DBMS specific.It may have denormalized columns (i.e. the same facts stored in more than one column) for performance reasons.Table and column names might not exactly mimic business terms i.e. they might be abbreviated, changed to conform some naming rules and/or DBMS restrictions, although for easier readability it is worth to retain some dependency.It is based on conceptual data model but created keeping performance and most common possible SQL statements in mind.I'm quite sure you have used it, so the only question is - have you created it keeping performance and business critical SQL in mind?Physical data modelWhat's that? Is there anything remaining to model at all? Yes it is. Heap table (i.e. table type which is used by default) is not the only available table type in Oracle. Partitioning is not the only option, which can be used in Oracle. So what is modeled here?Table type - heap, index organized, clustered, sorted hash cluster, single table hash cluster there are many possible options.Partitioning, compression, encryption - do you need it, can you afford it?Indexes - will you use only b-tree or something more?Will you use object tables?What tablespaces will be created and on what devices/files?Here comes the real strength (or weakness) of your chosen DBMS - if it offers all these features - why not at least consider them?If you are DBA you have definitely used some of the features mentioned above, but have you thought about non-default ones? Have you systematically gone through at least the most business critical tables and considered what kind of table type to use, what kind of indexes create?Not that I'm suggesting to enforce anything just for the sake of completeness ;) but I'm sure I've read something like that somewhere "If you have only heap tables and b-tree indexes, most probably your schema is not optimal".ConclusionSometimes conceptual modeling is called logical and logical physical and then of course question remains how should be called the real "physical modeling", but it is not so important. The import[...]



Mortgage calculator using SQL Model clauseRecently we had local Latvian Oracle day conference. This year it was quite big event with 5 parallel sessions and more than 400 participants. I also was one of the presenters telling about analytic functions and SQL Model clause. During the process of understanding deeper and better Oracle SQL Model clause I've tried make also some a bit complex examples myself. Nowadays the actual problem is mortgage and of course the possibility to pay monthly payments (fortunately not for me :) ) on the background of world wide financial crisis.So here is fully functional mortgage calculator using SQL Model clause. There are two variants:Adjustable rate mortgage with variable payment each month andFixed rate mortgage with fixed monthly payment.I've used this site to get formula for fixed monthly payment required to fully amortize a loan over a term of fixed months at a fixed monthly interest rate.OK and now the scripts.set ver off set lines 120 undefine rem_loan year_int_rate term SELECT m+1 month, to_char(rem_loan, '99999999.00') rem_loan, to_char(loan_paid_tot, '99999999.00') loan_paid_tot, to_char(mon_int, '999999.00') mon_int, to_char(tot_int, '99999999.00') tot_int, to_char(mon_paym, '99999999.00') mon_paym, to_char(mon_paym_tot, '99999999.00') mon_paym_tot, to_char(grand_tot, '99999999.00') grand_tot FROM dualMODEL DIMENSION BY (-1 m) MEASURES (&&rem_loan rem_loan, round(&&rem_loan*&&year_int_rate/100/12,2) mon_int, ceil(&&rem_loan/&&term*100)/100 mon_paym, (&&rem_loan/&&term*100)/100 loan_paid_tot, round(&&rem_loan*&&year_int_rate/12/100,2) tot_int, ceil(&&rem_loan/&&term*100)/100 + round(&&rem_loan*&&year_int_rate/100/12,2) mon_paym_tot, ceil(&&rem_loan/&&term*100)/100 + round(&&rem_loan*&&year_int_rate/100/12,2) grand_tot )RULES ITERATE (&&term) UNTIL (round(loan_paid_tot[iteration_number], 2) = &&rem_loan) ( rem_loan[iteration_number] = rem_loan[iteration_number -1] - mon_paym[iteration_number - 1], mon_int[iteration_number] = round(rem_loan[iteration_number]*&&year_int_rate/100/12,2), mon_paym[iteration_number] = least(ceil(&&rem_loan/&&term*100)/100, rem_loan[iteration_number]), loan_paid_tot[iteration_number] = loan_paid_tot[iteration_number - 1] + mon_paym[iteration_number], tot_int[iteration_number] = tot_int[iteration_number - 1] + mon_int[iteration_number], mon_paym_tot[iteration_number] = mon_paym[iteration_number] + mon_int[iteration_number], grand_tot[iteration_number] = grand_tot[iteration_number - 1] + mon_paym_tot[iteration_number]); Result for loan of 1000 money units (lats, euros, dollars, pounds whatever) for 10 % year rate with term of 7 months looks as follows:Enter value for rem_loan: 1000Enter value for year_int_rate: 10Enter value for term: 7 MONTH REM_LOAN LOAN_PAID_TO MON_INT TOT_INT MON_PAYM MON_PAYM_TOT GRAND_TOT---------- ------------ ------------ ---------- ------------ ------------ ------------ ------------ 0 1000.00 142.86 8.33 8.33 142.86 151.19 151.1[...]



One of 364 000 articles

According to google I've written another one of ~364 000 articles about SQL join types. So the question is why anyone should read it?
Here are a few reasons:

  • It is 25 pages long;

  • It contains join types metamodel or at least my attempt to create one;

  • It tries to describe what are different join types and how they relate to each other;

  • It contains visual pictures of cross, inner, and left, right, full outer joins and this time not with Venn diagramms, which I personally think are suitable for absolutely different operations (set operations);

  • To describe theory it contains 44 examples, which are tested on Oracle, SQL Server and MySQL;

  • It contains several links to other resources.

Because it is 25 pages I've decided not to put it here but it is on my website.

I have one wish though - if You are reading this article and have access to another DBMS (than already mentioned in article i.e. Oracle, SQL Server, MySQL) and have a bit free time, please run examples on your DBMS and post results either here or send me to mail Then I will put them in original article along with contributor's name.



Latvian Nationwide Song and Dance Celebration in Riga

Today is the beginning of 24th song festival - unique celebration of choral songs, which started 135 years ago with the first song festival. In these times under the rule of Russian Czar, later they continued during the short freedom period as well as even in Soviet times. This year about 35 000 singers and dancers will come to Riga to sing and dance in various concerts. This means more than 2% of all Latvians are coming together to sing and dance and many many more are coming to see them on the concerts or via TV.

Brief history

The first All Latvian Song Festival took place in Riga, year 1873. There were 1003 singers in these times. Under the Russian Czar there were 5 festivals. During the Latvian independence there were 4 festivals and participant count raised to more than 14 000 people. During the Soviet times these festivals partially become the weapon of Soviet propaganda, however these were like two-edged sword, for example, the 100th anniversary of song festival in 1973 was some kind of emotional uprising against Soviet regime. Since 1990 song festivals are held in independent state again and the participant count has raised to impressive more than 2% of all Latvians. The learning process of songs and dances is continued all the time and it is worth to mention that noone pays a single santīms (centime) to participants both for preparation process lasting a few years and also the very festival, although of course there is governmental material support for the organizational purposes of the festival.


During the festival there are many concerts and other kind of events. I'll mention a few of them. The first is participant parade. In the picture below one can look at one of the best choirs in the world "Kamēr", which has won many international awards and also takes part in this festival.
The second one is main dance concert. In recent times more than 10 000 dancers are taking part in it.
The last and biggest event is the final concert with all the singers in one big choir. It is very impressive moment.

Some links



Trip to EstoniaDuring my holidays I've been in a 4 days trip to Estonia. For Oracle adepts this is the country where Tanel Poder comes from ;)The trip was made up by myself and my wife, during it we drove ~1700 km. The general idea was to drive around all Estonia (it is not very big country) and look at some (hopefully) most interesting places. Here are 26 most interesting photos:A view from Munamagi hill, the highest point in BalticsTartu Dom Cathedral, it is being rebuilt nowInteresting fountain in Tartu, second largest Estonian cityRainbow over Peipsi lakeThere is 8 km long street through the old villages along the Peipsi lake. It looks like that all lengthwaysIvangorod castle over the river in Russia. This castle is just in the opposite side of Narva river from the Narva castleNarva castle. This castle is just in the opposite side of Narva river from the Ivangorod castleAija along with bells in Narva castleNorthern coast (Gulf of Finland) mostly consists of limestone rocks up to 56 metres highSunset over Gulf of FinlandValaste waterfall is the highest waterfall of EstoniaEstonia has some kind of oil shale, this hill is man-made and consists of slag of oil shales. It is 116 metres high. The picture was taken from a bit lower hill of the same origin, just older one.Symbol of Rakvere townBikes at Palmse manor, which is in the very centre of Lahemaa national park, a beautiful sightseeing placeJagala waterfall near from TallinnTallinn has more than 2km long old city wall with many towers and everything in very well preservedTallinn old townThere was a bit rainy when we crossed over to Saaremaa island (actually Muhu island, which is connected to Saaremaa by dam). The sail is very short just ~20 minutes.13th century painting in Liiva church, Muhu islandMaasilinn stronghold in SaaremaaAngla windmills. There were multitude of windmills in Saremaa (~800) these are just a few of forever gone old might.It is very easy to get to this Kaali meteoritic lake, it is just 17 km from Kuressaare, centre of SaaremaaA passage in Kuressaare castle, SaremaaToilett of Middle Ages in Kuressaare castle, SaremaaOrgan of Kihelkonna church, SaremaaKihelkonna church, Saremaa. It was possible to climb up to the tower and look around through the windowsIf you enjoyed these you can look also at some of my photos from Latvia.[...]



New improved price list

Obviously fluctuations of $ is affecting also Oracle ;) and as a result we have new global price list. Changes have affected also all Oracle database editions except Express, which is for free. So now Standard Edition One license is for 5 800 (was 4 995), Standard Edition is for 17 500 (was 15 000) and Enterprise Edition 47 500 (was 40 000) per processor. Personal Edition named user plus licence now is 460 US dollars (was 400). All new prices are here. These are the bad news.

The good news are that Oracle has created very informative Pricing and Licensing Rules, Tools page (at least I was not aware of that), which has many links to other valuable documents regarding Oracle pricing and licensing, for example, Oracle product prices in other currencies using Oracle exchange rates.

So get accustomed to new prices ;) and don't forget that there are other editions than Enterprise as well as there are such thing like term licensing (licenses for 1 till 5 years starting with 20% and ending with 70% of list price)!



SQL Merge and Sequence gapsI hope You my dear reader isn't one of the people cursed by requirement for gapless sequences ;)Yesterday I just found another nail in the coffin for oracle sequence objects used as gapless sequence generators. Of course there are many causes not to do that, just like simple rollback, users changing their minds, network connection error, flushing cache etc. But I didn't know at least till yesterday, that MERGE statements generate gaps with quite big guarantee. It seems that Merge statement is generating the same number of calls for sequence next value as row count of source table or subquery.Let's look at example:CREATE TABLE target (pk number, data varchar2(10));CREATE TABLE source (pk_s number, data_s varchar2(10));INSERT INTO target VALUES (1, 'a');INSERT INTO target VALUES (3, 'c');INSERT INTO source VALUES (1, 'a');INSERT INTO source VALUES (2, 'b');INSERT INTO source VALUES (3, 'c');INSERT INTO source VALUES (4, 'd');COMMIT;CREATE SEQUENCE seq START WITH 5;So now we have 2 rows in target table, and 4 rows in source table. We'll compare them using data and data_s column. We'd insert only two rows, because another 2 already exists and even won't use WHEN MATCHED clause for update.MERGE INTO targetUSING sourceON (data = data_s)WHEN NOT MATCHED THEN INSERT VALUES (seq.nextval, data_s);SQL> SELECT * FROM target; PK DATA---------- ---------- 1 a 3 c 7 d 8 bAlthough the sequence should have started from 5 new pk values are 7 and 8. Let's add another row into source and look what happens:INSERT INTO source VALUES (5, 'e');MERGE INTO targetUSING sourceON (data = data_s)WHEN NOT MATCHED THEN INSERT VALUES (seq.nextval, data_s);SQL> SELECT * FROM target; PK DATA---------- ---------- 1 a 3 c 7 d 8 b 13 eSo now the value is 13 i.e. 8 + count of rows from source table (5). Now let's add another row and delete all previous.INSERT INTO source VALUES (6, 'f');DELETE source WHERE pk_s SELECT * FROM target; PK DATA---------- ---------- 1 a 3 c 7 d 8 b 13 e 14 fAs we can see pk is incremented only by 1.After my experiments I found also metalink note "Merge Increments SEQUENCE.NEXTVAL for Both Insert and Update" (Note:554656.1), which also assures this as expected situation and not bug. So another reason not to worry about sequence values, just uniqueness of them ;)[...]



Minus All and Intersect All

Today I rediscovered Oracle Mix ideas and remembered my surprise that there are also Minus all and Intersect all operators in SQL standard just like Union and Union all. I'll briefly remind You what exactly they were. Let's imagine we have two sets:

T1: 1, 2, 2, 2, 3, 4, 4
T2: 2, 3, 4, 4, 4, 5

Then T1 INTERSECT T2 is 2, 3, 4
T1 INTERSECT ALL T2 would be 2, 3, 4, 4

T1 MINUS T2 is 1
T1 MINUS ALL T2 would be 1, 2, 2

So by default Intersect and Minus have DISTINCT operator removing all non-unique values. But in case we add keyword ALL then all values and their cardinalities are counted as well. I think these operators could be quite handy in process of analysing two data sets and finding what exactly the difference is. So if You are thinking the same way then I kindly ask you to support my idea about intersect all and minus all with your voice in Oracle Mix.

Thank You in advance for any decision :) and I hope sooner or later (better sooner of course ;) to find that in New features guide.



DBMSes are different...

Recently had to do some work with SQL Server. As my experience with it is quite limited I've got a few interesting impressions, which probably are absolutely trivial for SQL Server adepts :)

Do you know that SELECT query can create new tables?

OK in SQL Server it can. So I had to create backup of a table and firstly was quite frustrated not finding anything like CTAS (CREATE TABLE ... AS SELECT). I was on a wrong track however. The right syntax is SELECT INTO as in following example:

CREATE TABLE persons (
prs_name VARCHAR(30) NOT NULL) ;

INSERT INTO persons (prs_name) VALUES ('GINTS');
INSERT INTO persons (prs_name) VALUES ('JOE');

INTO persons_bkp
FROM persons;

SELECT * FROM persons_bkp;

So till now I was under the impression that SELECT is DML statement however obviously that's not true at least for SQL Server.

Do you know that SQL Server can handle recursive queries?

At least since version 2005 it can. Long ago I have heard that SQL Server has nothing similar to START WITH CONNECT BY. This site comparing SQL Server and Oracle seemed to approve my thoughts. However DBMSes are different and one has to look for different ways accomplishing the same goals. And in SQL Server one can use Common table expressions (aka query factoring clause or with clause in Oracle world) to get hierarchical results. And BTW here SQL Server "outfunctions" Oracle because it allows to recursively reference the same common table in its definition, which is not allowed by Oracle. Here are two articles if you are interested in how exactly it is done:

So in conclusion these two features which are possible in both DBMSes, but are implemented in completely different ways supports my previous article that all databases are different :)



The year has gone..

..since I started blogging. Actually I started it because of real anger against Oracle. The reason was one of the most famous problems in OTN history - inability to change e-mails ;) However about a month or two later it was resolved.
It seems the last year Oracle has made advances towards the community and:
1) listened to it (above mentioned case) as well as for example the case with AWR and ASH licensing. Probably all these steps were already on their way but I'm quite sure blog entries accelerated the result.
2) created public resources (oracle wiki) probably not veeeeery actively used until now.
3) granted free access for active members of public community to Oracle open world.
4) most probably made other positive steps I cannot remember or simply haven't heard about.

Last year was also big improvement in so called Oracle blogosphere - was founded along with some other aggregators, which can be found on oracle wiki.

For me it was a year of realizing the fact that there are tremendous resources about databases and Oracle in English, but just few in my mother tongue Latvian. So as I don't think English is the only language in the world even for databases :) I started to blog about databases in Latvian. Quite a bit of free time goes there.

So in my little anniversary I wish Oracle remember and support its community (probably sponsor a trip to Open world next year for bloggers khe khe :))) and myself to continue work about databases and Oracle resources especially in Latvian!



SQL Join TypesNew enhanced 25 pages long article with 44 examples and visual pictures describing SQL join types can be found here.I'm studying a bit SQL joins and trying to make clear at least for me what they are and what the relationships among them are. As I've always thought that picture is worth hundred words I've tried to create ER diagram describing metainfo about joins. So the question for everyone is - is this diagram OK? And aren't there obvious bugs? :)Probably from the strict viewpoint of Set theory and relational algebra it is not OK, but I'm more concerned of practical SQL usage and understanding. In case you know similar diagramm or whatever else visual explanation of relationships among join types please leave comment with link.So the diagram is as follows (please click on it to get bigger):Now for those that aren’t familiar with all these join types and terms in diagram above I'll try to give SQL examples (without data and results) for each one of them. If you'd like to have also examples with data cehck one of the links at the very end of this post.Assume we have 2 tables - TableA (id, title) and TableB (id, description).What the result are for each one of them you can find in other places for example: Cross join:SELECT * FROM TableA CROSS JOIN TableB Join with restriction:It is either natural join or qualified join. Each join with restriction has one cross join which is the degraded case of it. Natural join:Natural joins can be Inner or one of Outer joins, but they always are equi joins. Without explicitly specified inner or outer it is inner join. More about natural joins in my previous blog post. SELECT * FROM TableA NATURAL JOIN TableB Qualified join:Qualified joins can be written either specifying join columns (named columns join) or explicitly writing join condition. Join type: Could not find anything better to somehow unite inner and various outer joins under one roof. Inner join:SELECT * FROM TableA NATURAL INNER JOIN TableBSELECT * FROM TableA INNER JOIN TableB USING (id)SELECT * FROM TableA INNER JOIN TableB ON ( = Outer join:Outer join is one of left, right or full outer join. Left outer join:SELECT * FROM TableA NATURAL LEFT OUTER JOIN TableBSELECT * FROM TableA LEFT OUTER JOIN TableB USING (id)SELECT * FROM TableA LEFT OUTER JOIN TableB ON ( = Right outer join and Full outer join:Take the same examples as from left outer join and just replace left with right or outer. Qualified join expression:There are two ways how more explicitly write join condition either specifying join columns or explicitly writing join condition. Named columns join:This join is written with "USING" clause. Named columns join always is equi join. SELECT * FROM TableA INNER JOIN TableB USING (id) Conditional join:This join is the real one that I'd like to suggest using. With explicitly specifying what the join condition is. This also is the only join where one can use not only equi join but also another predicate operator than "=". SELECT * FROM TableA INNER JOIN TableB ON ( = Predicate operator type:Based on predicate operator type joins can be classified as either equi or theta (nonequi) joins. Equi join:Equi join is join where operator used in join condition is equivalence ("=").Both natural joins and Named columns joins are always equi joins. Examples: SELECT * FROM TableA NATURAL LEFT OUTER JOIN TableBSELECT * FROM TableA FULL OUTER JOIN TableB USING (id)SELECT * FROM TableA INNER JOIN TableB ON ( = Theta (Nonequi) join:Equi join is join where operator used in join condition is something other than equiva[...]



Some photosI've been tagged by APC. Usually I don't respond to chain letters but this will be a bit of exception. However I won't tag anyone further. Looking at usual curses happening after NOT forwarding chain letters I hope all my Oracle installations won't silently transform to SQL Server ones ;)So I won't tell anything about me, I'll just publish some of my best photos taken in various places in Latvia.Lilacs in Dobele gardenGarden if front of National OperaNest of Lesser Spotted EagleAiring trail in heathA lake in fogSun set view over my country landed propertyOpen air museum in AtteEaster eggs by my wife(colouring of course :)National Opera House in RigaRundale PalaceRiga Dom Cathedral - biggest church in BalticsHouse Of Blackheads and St.Peter churchRailroad bridge at nightArt Noveau in Riga[...]



MINUS ALL and INTERSECT ALL in Oracle RevisitedYesterday I wrote an article explaining that MINUS ALL and INTERSECT ALL is not possible in Oracle.However today after a bit thinking I got insight - multiset operations! Yes these should be the right thing!Since 10g Release 1 Oracle supports MULTISET UNION/EXCEPT/INTERSECT for both ALL/DISTINCT. I have only to make some types, a bit type casting and everything should be ok!So I've started with the simple tables I've shown yesterday.CREATE TABLE t1 AS SELECT mod(rownum, 1000) rnFROM dba_source WHERE rownum [...]




Recently I was a bit studying SQL standard and a lot to my surprise found that there exists not only UNION ALL set operator, but also INTERSECT ALL and EXCEPT ALL (in Oracle version it would be MINUS ALL).

So you'd say Oracle haven't them and it is also (although partially - somehow minus has been forgotten) documented in Oracle Support for Optional Features of SQL/Foundation:2003.

Hmm, yea but a while ago I was doing several data migrations and then such set operators would really helped me. Now a bit what these non-existant (at least for Oracle) set operators are doing?

Imagine we have tables T1 and T2 with data as follows:

T1: 1, 2, 2, 2, 3, 4, 4
T2: 2, 3, 4, 4, 4, 5

So what is the result for SELECT * FROM T1 MINUS SELECT * FROM T2?


What would be the result for SELECT * FROM T1 MINUS ALL SELECT * FROM T2?

1, 2, 2

What is the result for SELECT * FROM T1 INTERSECT SELECT * FROM T2?

2, 3, 4

What would be the result for SELECT * FROM T1 INTERSECT ALL SELECT * FROM T2?

2, 3, 4, 4

As you can see ALL for EXCEPT/MINUS and INTERSECT retains cardinality and doesn't keep only unique records. Let's hope Oracle someday will stop this gap and give us this functionality :)



Oracle wiki

I've thought for a while about creating an article about the resources available in Oracle problem solving process. Meanwhile Oracle wiki was born and already exists for about two months. As it is supposed to be shared and editable resource by everyone in Oracle community I thought that it would be a perfect place for my eventual article for two reasons:
1) more people hopefully will read it and probably get some help;
2) more people can add their suggestions how they solve Oracle related problems.
So my first contribution to Oracle wiki is How to solve Oracle Database related problems. Everyone is invited to correct it and/or add some other resources. As well as for other Oracle wiki pages of course.



How to choose database

Most of us (I mean readers of Oracle related blogs) most probably have already decided which DBMS to use. However the world is changing and sooner or later either you'll have to choose a new DBMS or defend your favourite one.
Quite often we hear such argument like DB X is cheaper than DB Y, therefore we have to take this one. And cheaper usually means only license cost. However license cost is only one part of direct expenses not to speak even about indirect expenses.
So i've written an article trying to explain more than 10 criteria which should be analyzed before final decision. Article contains also a list of more than 30 databases with links to their sites one can choose from.



The curse of gapless sequences

Gapless sequences are one of the best examples of bad requirements. Initially it was thought as an article for my blog but the result was too big and I've put it on my site.



Hints "stronger" than db parameters?Actually I've tested only one parameter so the plural in title is questionable generalization :)Recently battling with ORA-04030: out of process memory errors I found at least for me quite interesting fact.USE_HASH hint is more powerful than parameter _hash_join_enabled = false (for 10g) or hash_join_enabled = false (for 9i).I was quite suprised because without this test case I'd thought completely opposite. Of course neither hash_join_enabled nor _hash_join_enabled should be often altered to different value than default "true", but in case of "false" and your code having hints use_hash, you'll have hash joins regardless of above mentioned db parameter setting. It might be quite nasty surprise in case you have eliminated hash joins because of possible bugs, for example.I've tested this behaviour for SE and EE on Windows as well as SE on AIX and EE on windows, all had the same behaviour.Here is my test case and 10046 event trace execution plan results on SE/Windows (all other tests were similar):SQL> select * from v$version;BANNER----------------------------------------------------------------Oracle Database 10g Release - ProductionPL/SQL Release - ProductionCORE ProductionTNS for 32-bit Windows: Version - ProductionNLSRTL Version - ProductionSQL> create table a as select rownum rn, object_name 2 from all_objects;Table created.SQL> alter session set events '10046 trace name context forever, level 1';Session altered.SQL> select count(*) from ( 2 select * 3 from a a1, a a2 4 where a1.rn = a2.rn); COUNT(*)---------- 60141Execution plan:STAT #24 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=556 pr=73 pw=0 time=212727 us)'STAT #24 id=2 cnt=60141 pid=1 pos=1 obj=0 op='HASH JOIN (cr=556 pr=73 pw=0 time=406508 us)'STAT #24 id=3 cnt=60141 pid=2 pos=1 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=73 pw=0 time=61652 us)'STAT #24 id=4 cnt=60141 pid=2 pos=2 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=0 pw=0 time=60192 us)'SQL> alter session set "_hash_join_enabled" = false;Session altered.SQL> select count(*) cnt from ( 2 select * 3 from a a1, a a2 4 where a1.rn = a2.rn); CNT---------- 60141Execution plan:STAT #12 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=556 pr=0 pw=0 time=374302 us)'STAT #12 id=2 cnt=60141 pid=1 pos=1 obj=0 op='MERGE JOIN (cr=556 pr=0 pw=0 time=470826 us)'STAT #12 id=3 cnt=60141 pid=2 pos=1 obj=0 op='SORT JOIN (cr=278 pr=0 pw=0 time=88667 us)'STAT #12 id=4 cnt=60141 pid=3 pos=1 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=0 pw=0 time=44 us)'STAT #12 id=5 cnt=60141 pid=2 pos=2 obj=0 op='SORT JOIN (cr=278 pr=0 pw=0 time=231092 us)'STAT #12 id=6 cnt=60141 pid=5 pos=1 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=0 pw=0 time=60174 us)'SQL> select count(*) cnt from ( 2 select /*+ full(a1) full(a2) use_hash(a1 a2)*/ * 3 from a a1, a a2 4 where a1.rn = a2.rn); CNT---------- 60141Execution plan:STAT #24 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=556 pr=73 pw=0 time=214116 us)'STAT #24 id=2 cnt=60141 pid=1 pos=1 obj=0 op='HASH JOIN (cr=556 pr=73 pw=0 time=399462 us)'STAT #24 id=3 cnt=60141 pid=2 pos=1 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=73 pw=0 time=60803 us)'STAT #24 id=4 cnt=60141 pid=2 pos=2 obj=176936 op='TABLE ACCESS FULL A (cr=278 pr=0 pw=0 time=60188 us)'[...]



All latvian Oracle (and not only) users - UNITE!

I'd like to announce two resources for people that like relational databases and speak Latvian.
The first one is discussion group for Latvian Oracle User Group. The near future plans are described here (in Latvian).
If you speak Latvian and work with Oracle then it is your duty :) to join it! Of course one can join even if he doesn't speak Latvian, however there will be a small problem - everyone will understand you, but it is doubtful that you will understand anything except some keywords like Oracle, SQL, etc :)

The second resource is mine. And it is more general, it is blog about relational databases (in Latvian).
Recently I've searched Internet and was very unpleasantly surprised - I've found very few resources devoted to relational databases. So not to make only complaints I've started to blog about relational databases in my mother tongue. I'm of course not living in illusions that I can do it only myself and therefore anyone that is at least a little bit eager to help me in this process and has some knowledge either in general SQL, Oracle, MS SQL Server, MySQL, PosgreSQL or another relational db is encouraged to join me and become author in this blog.