Main menu:

Site search

Categories

Tags

intern

Oracle und SQL

Perl

Oracle 11.2:IGNORE_ROW_ON_DUPKEY_INDEX – Please No!

Oracle hat mit 11.2 neue optimizer hints “erfunden” und zwar auch IGNORE_ROW_ON_DUPKEY_INDEX.

Er dient dazu (wie der Name schon sagt) bei einem INSERT  (und nicht bei einem UPDATE!) auf einen Unique Key die Exception zu ignorieren und das statement tut dann einfach nichts. Es würde dann also zb funktionieren (ohne unique key violation):

insert into testtable (id, text) values (1, 'testtext der erste');
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(testtable(id))*/ into testtable (id, text) values (1, 'testtext der zweite');

Dieser Hint ist eigentlich kein Hint sondern eine Option (…), und außerdem aus mehreren Gründen keine gute Idee:

  • andere Oracle Hints (zb für den Optimizer) verändern das Verhalten des Statments nicht, und sind somit kompatibel mit anderen Datenbanken
  • es gibt schon ein statment mit dem man den gleichen Effekt erreichen kann und zwar MERGE, welches man mittelfristig sicher auch in anderen Datenbanken wie Postgres erwarten kann

Und gleich der Vollständigkeit halber das MERGE-Statement:

merge into testtable
using (select 1 from dual)
on (id = :b_id)
when not matched then
insert (id, text) values (:b_id, :b_text);

ich verwende deswegen bind Variablen weil man ansonsten den Wert :b_id zweimal einsetzen müßte. Entgegen anderslautenden Gerüchten muß es keinen “when matched … where 2=1” (oder Ähnliches) Abschnitt geben. Das “select 1 from dual” dient dazu um genau ein Zeile zum bekommen und somit die Zahl der zu behandelnden Zeilen zu determinieren.

Die Relevanz der Inflationsrate

Zend, Oracle, perl, php

Oracle XE on Suse 11 64bit

Oracle XE (Express Edition) uses libaio 32bit. So if you want to install it on 64bit system you have to install the 32bit version. For example from here

nic.at epp client on github (written in php)

I decided that from now on the source code for the  epp client for domain registries (templates specifically for the austrian top level domain .at) will reside on github

The giturl you’ll find the code at is

http://github.com/MarkHofstetter/php-epp-client

remarks/comments/suggestion are very welcome

The Zend Guestbook demo with Oracle 11g

The Zend Guestbook demo implemented with Zend 1.95, Oracle 11g and the xampp package

download the complete example here

First things first. Don’t, *again* don’t, use Zend 1.9 which seems to have some bugs, use at least 1.91.
What I’ve done I changed as few things as possible to get the guestbook quickstart demo running on Oracle.
Only some minor yak shaving had to take place:

  • You cannot easily user the Zend .ini style configuration  because you need some Db_Zend constansts, so you either have to use XML style config or hardcode the constants (and the credentials) directly in the Bootstrap.php file (the easy route which I have taken)
  • In Oracle its not possible to name a column “COMMENT” so I have chosen “COMMENTS” instead which is equally bad but at least working
  • Use at least Zend 1.91, have I already mentioned that?
  • I haven’t came around to get “Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER” working quickly, so all the column names used have to be upper case as they are stored in the Oracle data dictonary views

Installation

  • Be careful, if you break something it’s your fault not mine
  • Everything is you need is in the zip file which should be unpacked in a directory accessable by your webserver, in the many cases (also with the XAMPP and LAMPP packages) this folder is named “htdocs”

Database (Oracle) Side

  • if you have user create privileges (usually SYSTEM or SYS user), you may execute the questbook.sql script found in the INSTALL folder
  • if you don’t have user create privileges, but a database user (the name doesn’t matter) login as the user and start with line 6 (the create sequence command) of the guestbook.sql file

PHP Side

  • in application/Bootstrap.php change the dbname, username and password to your settings

You are ready

  • navigate your web browser to http://<yourhostname>/quickstart/public/guestbook and everything should work out fine

20 Jahre Mauerfall im Lichte von RDBMS

In jedem meiner Datenbankkurse predige ich ein paar Stehsätze einer davon lautet

jede Tabelle muß eine “abstrake” ID haben, und es ist sehr schlecht “scheinbar” eindeutige numerische Felder wie zum Beispiel Kontonummer, Personalnummer oder auch die Postleitzahl als ID zu mißbrauchen.

Ich bringe immer das Beispiel das eine Personentabelle mit einer Orte Tabellen über die Postleitzahl verknüpft ist. Was von den meisten Teilnehmer mit einem begeisterten Kopfnicken quittiert wird “ist ja eh eindeutig und wird sich sicher NIE ändern”.

Dann kommt mein großer Moment und ich sage: “Und dann kommt die Wiedervereinigung und das ganze Datenmodell bricht zusammen!”. Das ist sehr deutlich und einprägsam – nur sind mittlerweile auch so junge Teilnehmer dabei bei denen das große Ereignis eben nicht mehr so präsent ist. Hm ich werde alt. Meine Hoffnungen ruhen auf Nord- und Südkorea für neue Beispiele.

In diesem Sinne ist der positive Beitrag des Mauerfalls zum Thema “Datenbankdidaktik” gar nicht hoch genug einzuschätzen!

New Feature for collections in Oracle 11

Starting with Oracle 11 it is now possible to use set operators on “some” collection types (ie varrays and nested tables, NOT index by Tables).

A simple example:

PROCEDURE COLL_SET_OP
IS
cursor c_emp(c_p_salary number) is
select first_name, last_name, salary from employees
where salary > c_p_salary;

type t_emp is table of varchar2(50);

a1_emp t_emp := t_emp();
a2_emp t_emp := t_emp();

a_emp_op t_emp := t_emp();
i number := 0;
BEGIN
for r in c_emp(5000) loop
i := i+1;
a1_emp.extend;
a1_emp(i) := r.last_name;
end loop;

i:=0;
for r in c_emp(10000) loop
i := i+1;
a2_emp.extend;
a2_emp(i) := r.last_name;
end loop;

dbms_output.put_line(cardinality(a1_emp));
dbms_output.put_line(cardinality(a2_emp));

a_emp_op := a1_emp multiset except a2_emp;
i:=a_emp_op.first;
while (i is not null) loop
dbms_output.put_line(i ||' '||
a_emp_op(i));

i:=a_emp_op.next(i);
end loop;
END;

there are operators to mimic all SQL-set operators (union, minus, intersect). Its not exaclty a feature in PLSQL I’ve been anxiously waiting for, but there may be some uses for it. Please keep in mind that it won’t work for “index by varchar2” tables which would make it a lot more usefull.

Compare available Objects on two Oracle Instances

Compare available Objects on two Oracle Instances

For this snippet to work you need a functioning database link


select object_name, object_type from user_objects@;
minus
select object_name, object_type from user_objects

to get the actual DDL (for a package body in this example) statments you have to issue


select referenced_name, dbms_metadata.get_ddl(referenced_type, referenced_name) from (
select name, type, referenced_name, referenced_type from
user_dependencies where name='' and type='PACKAGE BODY'
minus
select name, type, referenced_name, referenced_type from user_dependencies@;
) where referenced_name not in ('STANDARD', 'DBMS_OUTPUT', 'DUAL')
and referenced_name not in (select object_name from user_objects@)

nic.at epp client 0.26 – feature complete

new Version of the nic.at epp client to be found here

hopefully I did not forget any features/request types. The most interessting new feature is the web client, which is in my oppion easy to use and really usefull for small scale registrars

so the new feature for this release are

  • web client
  • all request types (hopefully)

what is still lacking is reasonable error handling, support of severel registrars and possibly multi client capabiltiy, when installing please be carefull that your php.ini(s) include openssl/ssl support

nic.at epp client 0.10

newest version of the php client for nic.at epp registry system
php-epp-client

for more information please go to  the php-epp-client main page

new feature(s);

  • a command line client
shell> php client.php epp-config.xml domain-info
domain : bla.at
trid : 123

<?xml version="1.0" encoding="UTF-8" standalone="no" ?><epp xmlns="urn:i
e" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result><msgQ count="1" id="296463033"/>
<resData>
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" x
<domain:name>bla.at</domain:name>
<domain:roid>bla.at</domain:roid>
<domain:status s="ok"/>
<domain:registrant>FS1533880</domain:registrant>
<domain:contact type="admin">FS1533880</domain:contact>
<domain:contact type="tech">NIS1494123</domain:contact>
<domain:ns>
<domain:hostAttr>
<domain:hostName>ns1.nessus.at</domain:hostName>
</domain:hostAttr>
<domain:hostAttr>
<domain:hostName>ns2.nessus.at</domain:hostName>
</domain:hostAttr>
<domain:hostAttr>
<domain:hostName>ns3.nessus.at</domain:hostName>
</domain:hostAttr>
</domain:ns>
<domain:clID>Reg326</domain:clID>
<domain:upDate>2006-05-23T08:52:53.00Z</domain:upDate>
</domain:infData>
</resData>
<trID>
<clTRID>123</clTRID>
<svTRID>2009012811122133516239-992-nicat</svTRID>
</trID>
</response>

</epp>

1000
Command completed successfully

shell>