Here are some examples of the ways in which the sample can be extended:
This scenario presents the following challenges:
The following SQL is for DB2 Universal Database. if you are running Oracle, you may need to modify it accordingly (and remember to set @ as the statement terminator):
CREATE TABLE "ADAPTER_ITEM" ( "PKEY" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 NO CYCLE NO CACHE), "NAME" VARCHAR(20) NOT NULL, "INVOICE_KEY" VARCHAR(10) NOT NULL, "PRICE" FLOAT(53) DEFAULT 0 ) DATA CAPTURE NONE@ ALTER TABLE "ADAPTER_ITEM" ADD CONSTRAINT "ADAPTER_ITEM_PK" PRIMARY KEY ("PKEY")@
The SQL creates a new table, ADAPTER_ITEM, with four columns: an auto-generated primary key, the name of the item, a reference to the invoice it belongs to, and the price of the item. The new table uses the INVOICE_KEY as a foreign key to the ADAPTER_ITEM table.
You need to update only the part of the flow that creates ADAPTERINVOICE messages. Double-click the DatabaseInput node in the MigratedAdapter flow to open the ESQL, navigate to the Source view, and scroll down to the portion that creates the ADAPTERINVOICE message:
SET Root.MRM = THE( SELECT DispatchedEvent.Usr.OBJECT_VERB AS verb, INVOICE.PKEY AS Inv:PKEY, INVOICE.ITEM AS Inv:"Item", INVOICE.QUANTITY AS Inv:QUANTITY, INVOICE.CUSTOMER AS Inv:CUSTOMER, 'Retrieve' AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.verb, CUSTOMER.PKEY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:PKEY, CUSTOMER.FIRSTNAME AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:FIRSTNAME, CUSTOMER.LASTNAME AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:LASTNAME, CUSTOMER.ADDRESS AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADDRESS, 'Retrieve' AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.verb, ADDRESS.PKEY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:PKEY, ADDRESS.FIRSTLINE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:FIRSTLINE, ADDRESS.SECONDLINE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:SECONDLINE, ADDRESS.CODE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:CODE, ADDRESS.CITY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:CITY, ADDRESS.COUNTRY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:COUNTRY, CUSTOMER.CCODE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:CCODE , 'JDBCConnector_' ||CAST(DispatchedEvent.Usr.EVENT_ID AS CHARACTER) ||'ibm_events' ||CAST(DispatchedEvent.Usr.EVENT_TIME AS CHARACTER FORMAT 'yyyyMMddhhmmss.SSS') AS Inv:ObjectEventId FROM Database.ADAPTER_INVOICE AS INVOICE, Database.ADAPTER_CUSTOMER AS CUSTOMER, Database.ADAPTER_ADDRESS AS ADDRESS WHERE INVOICE.PKEY = DispatchedEvent.Usr.OBJECT_KEY AND CUSTOMER.PKEY = INVOICE.CUSTOMER AND ADDRESS.PKEY = CUSTOMER.ADDRESS);
Add the nested items and set the size attribute to the number of retrieved items.
(SELECT ADAPTER_ITEM.PKEY, ADAPTER_ITEM.NAME, ADAPTER_ITEM.INVOICE_KEY, ADAPTER_ITEM.PRICE FROM Database.ADAPTER_ITEM WHERE ADAPTER_ITEM.INVOICE_KEY = INVOICE.PKEY) AS Inv:ITEMS.Ite:ADAPTERITEM[],
Now populate the new attribute with the number of ADAPTERITEM rows retrieved. Add the following after the SELECT:
CREATE FIRSTCHILD OF Root.MRM.Inv:ITEMS TYPE NameValue NAME 'size' VALUE CARDINALITY(Root.MRM.Inv:ITEMS.Ite:ADAPTERITEM[]);
Normally, you could write:
SET Root.MRM.Inv:ITEMS.size = CARDINALITY(Root.MRM.Inv:ITEMS.Ite:ADAPTERITEM[])But, because the message is an ordered sequence, you need to ensure the attribute is the first child.
SET Root.MRM = THE( SELECT DispatchedEvent.Usr.OBJECT_VERB AS verb, INVOICE.PKEY AS Inv:PKEY, (SELECT ADAPTER_ITEM.PKEY, ADAPTER_ITEM.NAME, ADAPTER_ITEM.INVOICE_KEY, ADAPTER_ITEM.PRICE FROM Database.ADAPTER_ITEM WHERE ADAPTER_ITEM.INVOICE_KEY = INVOICE.PKEY) AS Inv:ITEMS.Ite:ADAPTERITEM[], INVOICE.QUANTITY AS Inv:QUANTITY, INVOICE.CUSTOMER AS Inv:CUSTOMER, 'Retrieve' AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.verb, CUSTOMER.PKEY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:PKEY, CUSTOMER.FIRSTNAME AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:FIRSTNAME, CUSTOMER.LASTNAME AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:LASTNAME, CUSTOMER.ADDRESS AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADDRESS, 'Retrieve' AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.verb, ADDRESS.PKEY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:PKEY, ADDRESS.FIRSTLINE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:FIRSTLINE, ADDRESS.SECONDLINE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:SECONDLINE, ADDRESS.CODE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:CODE, ADDRESS.CITY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:CITY, ADDRESS.COUNTRY AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:ADAPTERADDRESS.Add:ADAPTERADDRESS.Add:COUNTRY, CUSTOMER.CCODE AS Inv:ADAPTERCUSTOMER.Cus:ADAPTERCUSTOMER.Cus:CCODE , 'JDBCConnector_' ||CAST(DispatchedEvent.Usr.EVENT_ID AS CHARACTER) ||'ibm_events' ||CAST(DispatchedEvent.Usr.EVENT_TIME AS CHARACTER FORMAT 'yyyyMMddhhmmss.SSS') AS Inv:ObjectEventId FROM Database.ADAPTER_INVOICE AS INVOICE, Database.ADAPTER_CUSTOMER AS CUSTOMER, Database.ADAPTER_ADDRESS AS ADDRESS WHERE INVOICE.PKEY = DispatchedEvent.Usr.OBJECT_KEY AND CUSTOMER.PKEY = INVOICE.CUSTOMER AND ADDRESS.PKEY = CUSTOMER.ADDRESS); CREATE FIRSTCHILD OF Root.MRM.Inv:ITEMS TYPE NameValue NAME 'size' VALUE CARDINALITY(Root.MRM.Inv:ITEMS.Ite:ADAPTERITEM[]);
Test the new functionality by adding a couple of items to the ITEM table, and adding or modifying an invoice that uses these items:
--<ScriptOptions statementTerminator="@"/> INSERT INTO ADAPTER_ITEM (NAME,INVOICE_KEY,PRICE) VALUES ('Trousers', 'inv10', 2.17)@ INSERT INTO ADAPTER_ITEM (NAME,INVOICE_KEY,PRICE) VALUES ('Jumpers', 'inv10', 12.00)@ INSERT INTO ADAPTER_INVOICE VALUES ('inv10', '', 10, 'cust1')@
Insert the above SQL in to a new SQL script in the AdapterMigration Data Design project in the Data Project Explorer. Then right-click the project inside the Data Project Explorer view and choose "Run SQL". This will cause the flow to be executed and the following message to appear on the ADAPTERMIGRATION.INVOICE queue:
<?xml version="1.0"?> <Q1:ADAPTERINVOICE xmlns:Q1="http://www.ibm.com/websphere/crossworlds/2002/BOSchema/ADAPTERINVOICE" xmlns:Q4="http://dbinput/amartens" xmlns:Q3="http://www.ibm.com/websphere/crossworlds/2002/BOSchema/ADAPTERADDRESS" xmlns:Q2="http://www.ibm.com/websphere/crossworlds/2002/BOSchema/ADAPTERCUSTOMER" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" verb="Create"> <Q1:PKEY>inv10</Q1:PKEY> <Q1:ITEMS size="2"> <Q4:ADAPTERITEM> <PKEY>9</PKEY> <NAME>Trousers</NAME> <INVOICE_KEY>inv10</INVOICE_KEY> <PRICE>2.17E+0</PRICE> </Q4:ADAPTERITEM> <Q4:ADAPTERITEM> <PKEY>10</PKEY> <NAME>Jumpers</NAME> <INVOICE_KEY>inv10</INVOICE_KEY> <PRICE>1.2E+1</PRICE> </Q4:ADAPTERITEM> </Q1:ITEMS> <Q1:QUANTITY>10</Q1:QUANTITY> <Q1:CUSTOMER>cust1</Q1:CUSTOMER> <Q1:ADAPTERCUSTOMER> <Q2:ADAPTERCUSTOMER verb="Retrieve"> <Q2:PKEY>cust1</Q2:PKEY> <Q2:FIRSTNAME>Barney</Q2:FIRSTNAME> <Q2:LASTNAME>Rubble</Q2:LASTNAME> <Q2:ADDRESS>add1</Q2:ADDRESS> <Q2:ADAPTERADDRESS> <Q3:ADAPTERADDRESS verb="Retrieve"> <Q3:PKEY>add1</Q3:PKEY> <Q3:FIRSTLINE>MP211</Q3:FIRSTLINE> <Q3:SECONDLINE>IBM Hursley Park</Q3:SECONDLINE> <Q3:CODE>SO21 2JN</Q3:CODE> <Q3:CITY>Winchester</Q3:CITY> <Q3:COUNTRY>GB</Q3:COUNTRY> </Q3:ADAPTERADDRESS> </Q2:ADAPTERADDRESS> <Q2:CCODE>Dev</Q2:CCODE> </Q2:ADAPTERCUSTOMER> </Q1:ADAPTERCUSTOMER> <Q1:ObjectEventId>JDBCConnector_160ibm_events20101108020022.046</Q1:ObjectEventId> </Q1:ADAPTERINVOICE>