Oracle Advanced Dml
-
Upload
ssunka01 -
Category
Technology
-
view
875 -
download
3
Transcript of Oracle Advanced Dml
Oracle Advanced DMLOracle Advanced DML
Alan BeaulieuAlan BeaulieuBeaulieu ConsultingBeaulieu Consulting
July 2008July 2008
AgendaAgenda
What is Advanced DML?What is Advanced DML? Conditional InsertsConditional Inserts Multi-table InsertsMulti-table Inserts Upserts (Update/Insert)Upserts (Update/Insert) Updating via JoinsUpdating via Joins
What is Advanced DML?What is Advanced DML?
Non-standard ways to insert, update, deleteNon-standard ways to insert, update, delete Includes variations on existing statements along Includes variations on existing statements along
with new statementswith new statements Reduces need for procedural code (i.e. PL/SQL)Reduces need for procedural code (i.e. PL/SQL) Especially pertinent to data-warehouse Especially pertinent to data-warehouse
environmentsenvironments
InsertsInserts
New (since 9i) variations allow you to: New (since 9i) variations allow you to: Insert rows into one of several tablesInsert rows into one of several tables Insert rows into multiple tablesInsert rows into multiple tables Insert different flavors of the same row multiple Insert different flavors of the same row multiple
timestimes
Insert FirstInsert FirstAllows each row to be placed into one of several Allows each row to be placed into one of several
tables using conditional logic.tables using conditional logic.
Example: Insert into either current or history table depending on dateExample: Insert into either current or history table depending on date
INSERT FIRSTINSERT FIRST WHEN cal_dt = trunc(sysdate) THEN INTO pos_sum_dlyWHEN cal_dt = trunc(sysdate) THEN INTO pos_sum_dly VALUES (fund_id, cal_dt, security_id, …)VALUES (fund_id, cal_dt, security_id, …) WHEN cal_dt < trunc(sysdate) THEN INTO pos_sum_dly_histWHEN cal_dt < trunc(sysdate) THEN INTO pos_sum_dly_hist VALUES (fund_id, cal_dt, security_id, …)VALUES (fund_id, cal_dt, security_id, …)SELECT fund_id, cal_dt, asset_id security_id, …SELECT fund_id, cal_dt, asset_id security_id, …FROM cus_pos_extrnlFROM cus_pos_extrnl
Insert today’s data into pos_sum_dly
Insert old data into pos_sum_dly_hist
Insert AllInsert AllAllows each row to be placed into 0, 1, …N tables Allows each row to be placed into 0, 1, …N tables
using conditional logic. using conditional logic.
Example: Insert data into pos_sum_dly, along with optional warningsExample: Insert data into pos_sum_dly, along with optional warnings
INSERT ALLINSERT ALL
WHEN mtrty_dt IS NULL THEN INTO WHEN mtrty_dt IS NULL THEN INTO di_exception_rpt
VALUES (VALUES ('INFO:INVALID RSM_MATURITY_DATE in CUSPOS', …), …)
WHEN 1 = 1 THEN INTO pos_sum_dlyWHEN 1 = 1 THEN INTO pos_sum_dly
VALUES (fund_id, cal_dt, security_id, …)VALUES (fund_id, cal_dt, security_id, …)
SELECT fund_id, cal_dt, asset_id security_id, …SELECT fund_id, cal_dt, asset_id security_id, …
FROM cus_pos_extrnlFROM cus_pos_extrnl
Insert warning record if maturity date is NULL
Always insert into pos_sum_dly
Insert All (cntd)Insert All (cntd)Allows different flavors of each row to be inserted into the Allows different flavors of each row to be inserted into the
same table.same table.
Example: Add pricing data going out 7 daysExample: Add pricing data going out 7 days
INSERT ALLINSERT ALL
INTO pricing_master INTO pricing_master
VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt, …)VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt, …)
INTO pricing_master INTO pricing_master
VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt + 1, …)VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt + 1, …)
… …
INTO pricing_master INTO pricing_master
VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt + 6, …)VALUES (sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt + 6, …)
SELECT sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt, …SELECT sec_id, src_cd, prc_typ_cd, crncy_cd, effect_dt, …
FROM pricing_extrnlFROM pricing_extrnl
INSERT/UPDATEINSERT/UPDATE
Pre-9i implementation of INSERT/UPDATE logic…Pre-9i implementation of INSERT/UPDATE logic…
BEGINBEGIN INSERT INTO table_x (a, b, c, …)INSERT INTO table_x (a, b, c, …) VALUES (v_1, v_2, v_3, …);VALUES (v_1, v_2, v_3, …);EXCEPTIONEXCEPTION WHEN DUP_VAL_ON_INDEX WHEN DUP_VAL_ON_INDEX UPDATE table_xUPDATE table_x SET b = v_2, c = v_3SET b = v_2, c = v_3 WHERE a = v_1;WHERE a = v_1;END;END;
INSERT/UPDATE (cntd)INSERT/UPDATE (cntd)
New (9i) SQL command : MERGENew (9i) SQL command : MERGE Allows you to both update and insert with a Allows you to both update and insert with a
single statementsingle statement If a row already exists, data is updated; If a row already exists, data is updated;
otherwise, data is insertedotherwise, data is inserted Also includes the ability to do conditional Also includes the ability to do conditional
DELETE’sDELETE’s
MergeMergeAllows data to be either updated or inserted using Allows data to be either updated or inserted using
a single SQL statement.a single SQL statement.
Example:Example:
MERGE INTO pos_sum_dly trg USING MERGE INTO pos_sum_dly trg USING
(SELECT fund_id, cal_dt, asset_id security_id, …(SELECT fund_id, cal_dt, asset_id security_id, …
FROM cus_pos_extrnl) srcFROM cus_pos_extrnl) src
ON (trg.fund_id = src.fund_id, trg.cal_dt = src.cal_dt, …)ON (trg.fund_id = src.fund_id, trg.cal_dt = src.cal_dt, …)
WHEN MATCHED THEN UPDATEWHEN MATCHED THEN UPDATE
SET trg.mtrty_dt = src.pos_mtrty_dt, …SET trg.mtrty_dt = src.pos_mtrty_dt, …
WHEN NOT MATCHED THEN INSERTWHEN NOT MATCHED THEN INSERT
VALUES (src.fund_id, src.cal_dt, src.security_id, …)VALUES (src.fund_id, src.cal_dt, src.security_id, …)
Row exists - Update
No row exists - Insert
Merge (cntd)Merge (cntd)Don’t need to specify both WHEN MATCHED and WHEN NOT MATCHEDDon’t need to specify both WHEN MATCHED and WHEN NOT MATCHED
Example: Fill in values for denormalized columnExample: Fill in values for denormalized column
MERGE /*+ PARALLEL(trg, 8) */ INTO income_recv_asof trgUSING (SELECT /*+ FULL(ira) PARALLEL(ira, 8) USE_NL_WITH_INDEX(iraf, income_recv_asof_fin_key) */ ira.ssb_fund, ira.period_indicator, ira.income_instance, ira.asof_date, iraf.fin_currency FROM income_recv_asof ira, income_recv_asof_fin iraf WHERE ira.ssb_fund = iraf.ssb_fund AND ira.period_indicator = iraf.period_indicator AND ira.income_instance = iraf.income_instance AND ira.asof_date = iraf.asof_date AND ira.income_currency <> iraf.fin_currency ) srcON (src.ssb_fund = trg.ssb_fund AND src.period_indicator = trg.period_indicator AND src.income_instance = trg.income_instance AND src.asof_date = trg.asof_date)WHEN MATCHED THEN UPDATE SET trg.income_currency = src.fin_currency;
Same table being updated…
Updating Using JoinsUpdating Using Joins
SQL Server lets you do the following:SQL Server lets you do the following:
UPDATE Sales.SalesPerson UPDATE Sales.SalesPerson SET SalesYTD = SalesYTD + SubTotal SET SalesYTD = SalesYTD + SubTotal FROM Sales.SalesPerson AS sp FROM Sales.SalesPerson AS sp JOINJOIN Sales.SalesOrderHeader AS so Sales.SalesOrderHeader AS so ON sp.SalesPersonID = so.SalesPersonID ON sp.SalesPersonID = so.SalesPersonID AND so.OrderDate = AND so.OrderDate = (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader
WHERE SalesPersonID = sp.SalesPersonID);WHERE SalesPersonID = sp.SalesPersonID);
Updating Using Joins (cntd)Updating Using Joins (cntd)
Doesn’t work with Oracle unless you update Doesn’t work with Oracle unless you update through an inline view:through an inline view:
UPDATE (SELECT hdr.fund_type, dhr.fund_type new_typ FROM fund_header hdr INNER JOIN dhr_t dhr ON dhr.ssb_fund = hdr.ssb_fund ) SET fund_type = new_typ;
Updating Using Joins (cntd)Updating Using Joins (cntd)
However, opposite statement doesn’t work:However, opposite statement doesn’t work:
UPDATE (SELECT dhr.fund_type, hdr.fund_type new_typ FROM dhr_t dhr INNER JOIN fund_header hdr ON dhr.ssb_fund = hdr.ssb_fund AND hdr.eval_ind = '0' ) SET fund_type = new_typ;Error at line 1ORA-01779: cannot modify a column which maps to a non key-
preserved table
Deleting Using JoinsDeleting Using Joins
Again, only through an inline view:Again, only through an inline view:
DELETE (SELECT hdr.ssb_fund FROM fund_header hdr INNER JOIN dhr_t dhr ON dhr.ssb_fund = hdr.ssb_fund WHERE hdr.tot_mkt_value < 1 AND dhr.max_bal < 100 );
Does it matter which columns are selected?