Blog do projektu Open Source JavaHotel

wtorek, 30 grudnia 2014

DB2, federation and three-part names

Federation
Federation (comprehensive redbook on that topic can be downloaded here) allows correlating data from different data sources. Although InfoSphere Federation Server requires additional licensing, so called "homogenous" federation (comprising only DB2  databases, local and remote)  is available also in free DB2 Express Edition.
DB2 supports also three-part name referring to remote object. The dbname.schema.tablename notation allows migration from other databases (like Oracle or MS SQL). Although it works nicely unfortunately I found a problem which made me several nervous evenings.
Recreate the problem
Firstly enable DB2 instance for federation
db2 update dbm cfg using FEDERATED yes

db2stop
db2start
Create two databases
db2 create database test
db2 create database feder
Database 'test' will contain our tables and database 'feder' will act as a federated database.
Create two simple tables in 'test'
db2 "CREATE TABLE X1 (A1 INT, A2 INT)"
db2 "CREATE TABLE X2 (B INT)"
Then connect to 'feder' and create federation server
db2 "create wrapper drda"
db2 "create server testserver type db2/udb  version '10.5'  wrapper drda  authid user_name  password \"user_password\"  options(  add dbname 'TEST')"
db2 "CREATE USER MAPPING FOR PUBLIC SERVER testserver  OPTIONS (REMOTE_AUTHID 'user_name', REMOTE_PASSWORD 'user_password')"
Important: pay attention to lack of ' or " in user_name in CREATE SERVER \" in user_password and ' in CREATE USER MAPPING. You can spend several hours trying to discover it on your own !
Create a view (inner join)
db2 "create or replace view XXX as select * from testserver.db2inst1.x1,testserver.db2inst1.x2"
So far so good. But while testing the view there is a surprise.
db2 "select * from xxx"
SQL0158N  Liczba kolumn podana dla tabeli "DB2INST1.XXX" różni się od liczby
kolumn w tabeli wynikowej.  SQLSTATE=42811
There is no way to overcome it. Running this join directly (without passing through view) is successful. It seems that : view on join between remote tables accessed through three-part name is not working.
Solution 
Just come back to old DB2 school and use nicknames.
db2 create nickname testserver_db2inst1_x1 for testserver.db2inst1.x1
create nickname testserver_db2inst1_x2 for testserver.db2inst1.x2
db2 "create or replace view XXX as select * from testserver_db2inst1_x1,testserver_db2inst1_x2"

db2 "select * from xxx"

A1          A2          B          
----------- ----------- -----------

  Wybrano rekordów: 0.

Conclusion 
Hoping to be fixed in next release. Besides, three-part naming convention is very useful.

poniedziałek, 29 grudnia 2014

MS SQL -> DB2 migration, foreign keys

Introduction
During migration from MS SQL Server to DB2  I was facing a problem to generate foreign keys (in DB2 supported format) from MS SQL generated object script without having an access to MSSQL database. It is not a problem to recreate them manually if you have several objects but it could be a problem if you are dealing with hundreds or thousands of them.
So I decided to spend some time on creating a simple program (in Python) to accomplish the task automatically.
The source code is available here (Eclipse PyDev project).
Packages
The solution comprises several packages.
readfiles : read lines from several files (list of files in constructor). It flattens several files to one single reader.
atomizer : transforms input into sequence of atoms. For instance:

CREATE TABLE [dbo].[departments](
 [dept_no] [char](4) NOT NULL,
 [dept_name] [varchar](40) NOT NULL,
PRIMARY KEY CLUSTERED 
Atomizer will output: CREATE TABLE [dbo.department] ( [dept_no ... etc. It simply breaks input  (list of text lines) into sequence of elements ignoring spaces, line breaks etc.
tokenizer : transforms list of atoms into the sequence of recognized keywords ignoring elements out of importance here.
For instance.
Assuming set of constants describing keywords important here:
ALTER=0
SEMICOLON=1
TABLE=2
ADD=3
CONSTRAINT=4
FOREIGN=5
KEY = 6
REFERENCES = 7
BEGCOMMENT=8
ENDCOMMENT=9
CREATE=10
VIEW=11
FUNCTION=12
PROCEDURE=13
GO=14
The output will be the sequence: CREATE (constant 10) TABLE [dbo.department] (as single tekst) ( [dept_no ... (etc). Tokenizer makes further analysis more easier.
foreign : selects foreign key definition and prepares data structure: base table, constraint name, list of columns, reference table name and reference column list. Example:
ALTER TABLE [dbo].[dept_emp]  WITH CHECK ADD FOREIGN KEY([dept_no])
REFERENCES [dbo].[departments] ([dept_no])
ON DELETE CASCADE
or
ALTER TABLE [dbo].[dept_emp]  WITH CHECK ADD CONSTRAINT DEPT_NO_DEPARTMENT_FK FOREIGN KEY([dept_no])
REFERENCES [dbo].[departments] ([dept_no])
ON DELETE CASCADE
publish : takes data structure (describing foreign key definition as describe above) and prepares DDL in DB2 format. For instance:

ALTER TABLE dbo.dept_emp ADD CONSTRAINT "FK_dept_emp_departments" FOREIGN KEY
   (dept_no)
   REFERENCES dbo.departments
   (dept_no)
@
The main program

def test4():    
    R = readfiles.ReadFiles(INF)
    A = atomizer.Atomizer(R)
    T = tokenizer.TOKENIZER(A)
    F = foreign.ForeignSearcher(T)
    a = F.nextForeign()
    f = open("output/foreign_keys.db2","w")
    while a != None :
        s =  foreignDB2.foreignDB2(a)
        print s
        print ""
        print ""
        f.write(s)
        f.write("\n")
        f.write("\n")

        a = F.nextForeign()
    f.close()
The first four statements (objects construction) can be fused into a single statement.
Example input and output.
Conclusion
I found this approach useful. I also reused it in resolving several other problems.

  • Migrate only a subset foreign keys definition. Read firstly list of tables (without foreign keys) already migrated and emits only foreign keys related to them.
  • Prepare list of all objects (tables, view, UDF and SP) in MS SQL object script. 

niedziela, 14 grudnia 2014

Byliśmy na koncercie

22 listopada 2014 roku byliśmy na przedstawieniu opery Richarda Straussa "Ariadna na Naksos" w Filharmonii Narodowej, występ podobał się bardzo, chociaż nie wszystkim byliśmy zachwyceni.
"Ariadna na Naksos" to jedna z tych oper, za którą tak bardzo lubimy Richarda Straussa. W Polsce rzadko wystawiana, na scenie Filharmonii po raz pierwszy. Przyczyną są najprawdopodobniej trudności realizacyjne, wymaga zaangażowania aż 17 solistów i niezbyt licznej, ale za to lubiącej wyzwania orkiestry, zdolnej sprostać skomplikowanej partyturze. Na szczęście w Warszawie w zupełności się to udało, i to nawet w całości krajowymi siłami z pomocą tylko czterech śpiewaków z importu. Szczególnie się podobała Anna Simińska w roli żywiołowej Zerbinetty, po brawurowym wykonaniu niezwykle efektownej arii "Großmächtige Prinzessin" artystka zebrała długie i zasłużone oklaski. Znakomicie także śpiewała Meagan Miller jako Primadonna. Potężny głos tenora Andreasa Schagera zdawał się rozsadzać salę Filharmonii, jakby artysta zapomniał, że nie śpiewa roli boga wojny Marsa czy władcy piorunów Jowisza, a boga winorośli Bachusa.
Wadą była niestety sama forma przedstawienia, gdyż było to przedstawienie koncertowe, bez akcji scenicznej. Brak scenicznego ruchu nadrabiał ekran na którym był wyświetlany polski przekład. Ale pomimo tego prolog, którego znaczną część wypełniają monologi i recytatywy zwyczajnie nużył. W drugim akcie znacznie lepiej było nawet zrezygnować z śledzenia napisów, a po prostu wsłuchać się w muzykę, która jest wspaniała i niezwykła.
Akcja opery jest statyczna, są tutaj dwa akty i na scenie nie musi się wiele dziać. Jednak zgubił się sam zamysł opery, która jest przecież zestawieniem kontrastów. Przeszłości i teraźniejszości (prolog i opera), świata rzeczywistego i mitycznego, wzniosłości i trywialności (Kompozytor i Baletmistrz), tragedii i komedii. Sztuki przez duże S, ale pozbawionej pieniędzy kontra duże pieniądze szukające sztuki przez małe s czy nawet śmiesznych sztuczek.
Muzyka Straussa, zwłaszcza w tak znakomitym wykonaniu, na szczęście zawsze brzmi i zachwyca tak samo, jednak brak scenicznej inscenizacji wyraźnie ubożył odbiór tego dzieła. Trzeba mieć nadzieję, że to wystawienie nie zakończy kariery "Ariadny na Naksos" na warszawskich scenach i będziemy mieć okazję poznać dzieło Straussa w kompletnej formie.