doing sql from pl/sql - · pdf filedoing sql from pl/sql: best and worst practices • an...
TRANSCRIPT
![Page 1: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/1.jpg)
<Insert Picture Here>
Doing SQL from PL/SQL: Best and Worst Practices
Bryn Llewellyn Distinguished Product Manager Database Server Technologies Division, Oracle HQ
![Page 2: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/2.jpg)
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remain at the sole discretion of Oracle.
![Page 3: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/3.jpg)
Caveat…
Doing SQL from PL/SQL: Best and Worst Practices
![Page 4: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/4.jpg)
Doing SQL from PL/SQL: Best and Worst Practices
• An unattributed programmers’ axiom has it that rules exists to serve, not to enslave. “All rules were meant to be broken — including this one.”
• Here’s a more sensible suggestion, given as the first (meta) best practice principle.
![Page 5: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/5.jpg)
Seek approval from an experienced colleague before disobeying any of the following best practice principles
![Page 6: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/6.jpg)
Agenda
• State 22 principles in turn
• For each, explain some background
• Take the chance to explain aspects of PL/SQL that not everyone finds obvious
• Motivate studying the whitepaper
![Page 7: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/7.jpg)
we’re off…
![Page 8: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/8.jpg)
Learn the terms of art: session cursor, implicit cursor, explicit cursor, cursor variable, and DBMS_Sql numeric cursor.
Use them carefully and don’t abbreviate them.
#1
![Page 9: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/9.jpg)
Why ?
• When discussing a PL/SQL program, and this includes discussing it with oneself, commenting it, and writing its external documentation, …aim to avoid the unqualified use of “cursor”.
• Rather, use the appropriate term of art.
• The discipline will improve the quality of your thought …and will probably, therefore,improve the quality of your programs.
![Page 10: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/10.jpg)
Embedded SQL
• Allows SQL syntax directly within a PL/SQL statement
• Therefore very easy to use
• Supports only the following kinds of SQL statement: • select
• insert, update, delete, merge [ “DML” ]
• lock table
• commit, rollback, savepoint
• set transaction
![Page 11: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/11.jpg)
How does embedded SQL work ?
• You say this at compile time:
insert into t(PK, v1) values(j, b.v1); ... select a.* into b.The_Result from t a where a.PK = b.Some_Value; ... update t a set row = b.The_Result where a.PK = b.The_Result.PK;
![Page 12: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/12.jpg)
How does embedded SQL work ?
• Your program says this at run time:
INSERT INTO T(PK, V1) VALUES(:B2 , :B1 ) ... SELECT A.* FROM T A WHERE A.PK = :B1 ... UPDATE T A SET "PK" = :B1 ,"N1" = :B2 ,"N2" = :B3 , "V1" = :B4 ,"V2" = :B5 WHERE A.PK = :B1
![Page 13: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/13.jpg)
In embedded SQL, dot-qualify each column name with the table alias.
Dot-qualify each PL/SQL identifier with the name of the name of the block that declares it.
#2
![Page 14: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/14.jpg)
<<b>>declare Some_Value t.PK%type := ... begin for r in ( select a.PK, a.v1 from t a where a.PK > b.Some_Value order by a.PK) loop Process_One_Record(r); end loop; end;
![Page 15: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/15.jpg)
Why ?
• To avoid the risk of the addition of a column to the table capturing a PL/SQL identifier
• Maximize the benefits of fine-grained dependency tracking (the compiler can’t trust your naming convention)
![Page 16: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/16.jpg)
Declare every PL/SQL variable with the constant keyword unless the block intends to change it.
#3
![Page 17: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/17.jpg)
Why ?
• Self-evident correctness w.r.t. injection risk
• Generic readability
• Occasional performance benefit
• ER asks for new warning
![Page 18: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/18.jpg)
Always specify the authid property explicitly.
Choose deliberately between Current_User and Definer.
Neither is “best”.
#4
![Page 19: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/19.jpg)
Why ?
• DR: protect access to tables via PL/SQL API
• IR: Avoid the risk of privilege escalation
• You will be warned
![Page 20: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/20.jpg)
Use the Owner to dot-qualify the names of objects that ship with Oracle Database.
#5
![Page 21: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/21.jpg)
Why ?
• Avoid the risk of subversion by a local object
![Page 22: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/22.jpg)
Strive to use SQL statements whose text is fixed at compile time.
When you cannot, use a fixed template.
Bind to placeholders. Use DBMS_Assert to make concatenated SQL identifiers safe.
#6
![Page 23: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/23.jpg)
Why ?
• Avoid the risk of injection
• Avoid avoidable hard parse
![Page 24: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/24.jpg)
For dynamic SQL, aim to use native dynamic SQL. Only when you cannot, use the DBMS_Sql API.
#7
![Page 25: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/25.jpg)
Why ?
• native dynamic SQL is easier to write
• And it’s faster
![Page 26: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/26.jpg)
When using dynamic SQL, avoid literals in the SQL statement. Instead, bind the intended values to placeholders.
#8
![Page 27: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/27.jpg)
Why ?
• You can’t say this one too often!
![Page 28: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/28.jpg)
Always open a DBMS_Sql numeric cursor with Security_Level => 2
#9
Cur := DBMS_Sql.Open_Cursor( Security_Level=>2)
![Page 29: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/29.jpg)
Why ?
• (New in 11.1.)
• Inoculate against "cursor snarfing“ (David Litchfield)
• ER asks for new warning
![Page 30: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/30.jpg)
The only explicit cursor attribute you need to use is Cur%IsOpen. The only implicit cursor attributes you need are Sql%RowCount, Sql%Bulk_RowCount, and Sql%Bulk_Exceptions.
#10
![Page 31: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/31.jpg)
Why ?
• Cur%IsOpen – to close ‘em in a catch all handler
• Sql%RowCount – how many rows did my DML affect?
• Sql%Bulk_RowCount – same for forall
• Observe at the earliest opportunity
• Sql%Bulk_Exceptions – in the ORA-24381 handler (don’t forget the save exceptions keyword)
![Page 32: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/32.jpg)
selecting
![Page 33: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/33.jpg)
This one is contentious! When you don’t know how many rows your query might get,use fetch... bulk collect into with the limit clause inside an infinite loop.
#11
![Page 34: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/34.jpg)
Why ?
• Bulk constructs are faster!
• But the target collections mustn’t get arbitrarily big
• ER asks for new warning (requires the use of an identified cursor)
![Page 35: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/35.jpg)
When you do know how the maximum number of rows your query might get, use select... bulk collect into or execute immediate... bulk collect into to fetch all the rows in a single step.
#12
![Page 36: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/36.jpg)
Why ?
• One step is better than many
• select… into is functionally complete
• Fetch into a varray declared with the maximum size that you are prepared to handle.
• Implement an exception handler for ORA-22165 (index outside the range of existing elements) to help bug diagnosis.
![Page 37: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/37.jpg)
Use the the DBMS_Sql API when you don’t know the binding requirement or what the select list is until run time.
If you do, at least, know the select list, use To_Refcursor() and then batched bulk fetch..
#13
![Page 38: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/38.jpg)
Why ?
• You have no choice. Method 4 is what it is – and the DBMS_Sql API is here to stay for that, and only that, use case
• But there’s no virtue in masochism so twizzle to a ref cursor when you can
![Page 39: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/39.jpg)
select Count(*) from All_Objects where 1 = 1 and Object_Name = :b1 and (1=1 or :b2 is null)
select Count(*) from All_Objects where Object_Name = :b1
Well, you do have a choice…
• This:
• is simplified by SQL compilation to this:
![Page 40: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/40.jpg)
To get exactly one row, use select... into or execute immediate... into.
Take advantage of No_Data_Found and Too_Many_Rows.
#14
![Page 41: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/41.jpg)
Why ?
• The construct says what you mean
• The exceptions are what you need for the regrettable and the unexpected cases
• It’s fewer steps and so it’s quicker
![Page 42: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/42.jpg)
religion
![Page 43: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/43.jpg)
Expose your database application through a dedicated schema that has only private synonyms for the objects that define its API.
#15
![Page 44: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/44.jpg)
Why ?
• How else can you enforce an API ?
![Page 45: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/45.jpg)
Expose your database application through a PL/SQL API. Hide all the tables in schemas that the client to the database cannot reach.
#16
![Page 46: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/46.jpg)
OK, this one is contentious…
• Universal best practice principle of software engineering:
• Decompose your system into modules
• Expose each module’s functionality, at a carefully designed level of abstraction, with a clean API
• Hide the module’s implementation behind that API
• PL/SQL subprograms define an API
• Tables and SQL statements are part of a module’s implementation – to be hidden from clients
![Page 47: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/47.jpg)
Define the producer/consumer API as a function whose return datatype represents the desired data.
Hide all the SQL processing in the producer module.
Parameterize the producer function as you would parameterize the query.
#17
![Page 48: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/48.jpg)
Why ?
• This way, the consumer is immune to an implementation change that a requirements change might cause.
• Approach accommodates getting the rows in batches or getting all the rows in one call — where this might be a slice.
![Page 49: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/49.jpg)
insert, update, delete -ing
![Page 50: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/50.jpg)
For each application table, maintain a template record type that defines the same constraints and defaults.
#18
![Page 51: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/51.jpg)
Why ?
• Lets you implement the insert of a new row where the caller mentions only some of many optional columns
![Page 52: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/52.jpg)
New_Row Tmplt.T_Rowtype; begin New_Row.PK := PK; if n1_Specified then New_Row.n1 := n1; end if; ... insert into t values New_Row;
![Page 53: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/53.jpg)
Use merge for an “upsert” requirement. Don’t use update... set row... together with insert in an exception handler.
#19
![Page 54: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/54.jpg)
Why ?
• merge says what you mean in a single statement
• So it’s quicker
![Page 55: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/55.jpg)
Result t%rowtype; begin ... merge into t Dest using (select Result.PK PK, Result.n1 n1, ..., Result.v1 v1, ... from Dual d) Source on (Dest.PK = Source.PK) when matched then update set Dest.n1 = Source.n1, ..., Dest.v1 = Source.v1, ... when not matched then insert values ( Source.PK, Source.n1, ..., Source.v1, ...);
![Page 56: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/56.jpg)
Use the forall statement rather than repeating a single-row statement. Handle ORA-24381 when it’s safe to skip over a failed iteration. For bulk merge, use the table operator with a collection of objects.
#20
![Page 57: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/57.jpg)
Why ?
• It’s quicker
![Page 58: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/58.jpg)
Results Results_t; begin ... merge into t Dest using (select * from table(Results))
Source on (Dest.PK = Source.PK) when matched then update set Dest.n1 = Source.n1, ..., Dest.v1 = Source.v1, ... when not matched then insert values ( Source.PK, Source.n1, ..., Source.v1, ...);
![Page 59: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/59.jpg)
Don’t be afraid to get rows with batched bulk fetch, process them in PL/SQL, and to put each batch back with a forall statement. The approach carries no noticeable performance cost compared to using a PL/SQL function directly in a SQL statement.
#21
![Page 60: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/60.jpg)
Why ?
• You have a data transformation that you need to solve
• Beyond a certain level of complexity, procedural code is easier to write and understand than declarative code
• Therefore the chances of its being correct are increased
![Page 61: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/61.jpg)
cursor Cur is select Rowid, a.v1 from t a for update; type Rowids_t is varray(1000) of Rowid; Rowids Rowids_t; type vs_t is varray(1000) of t.v1%type; vs vs_t; Batchsize constant pls_integer := 1000; begin ... loop fetch Cur bulk collect into Rowids, vs
limit Batchsize; for j in 1..Rowids.Count() loop -- This is a trivial example. vs(j) := f(vs(j)); end loop; forall j in 1..Rowids.Count() update t a set a.v1 = b.vs(j) where Rowid = Rowids(j); exit when Rowids.Count() < Batchsize; end loop;
![Page 62: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/62.jpg)
11.1 lifts a notorious restriction
• q PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
![Page 63: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/63.jpg)
loop fetch Cur bulk collect into Results limit Batchsize; for j in 1..Results.Count() loop -- This is a trivial example. Results(j).v1 := f(Results(j).v1); end loop; forall j in 1..Results.Count() update t a set a.v1 = b.Results(j).v1 where Rowid = b.Results(j).Rowid; exit when Results.Count() < Batchsize; end loop;
![Page 64: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/64.jpg)
Note…
• There are no special considerations for doing DML with native dynamic SQL except: • You can’t use the “whole row” syntax
![Page 65: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/65.jpg)
a straggler…
![Page 66: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/66.jpg)
Use this:
#22
for the functionality of an in list whose element count you don’t know until run time.
select ...
from ...
Where x in (select Column_Value from table(The_Values))
![Page 67: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/67.jpg)
Why ?
• Avoid native dynamic SQL with concatenated literals
• Avoid method 4 DBMS_Sql
![Page 68: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/68.jpg)
create type Strings_t is table of varchar2(30) / ... ps Strings_t; begin select a.PK, a.v1 bulk collect into b.Results from t a where a.v1 in (select Column_Value from table(b.ps));
![Page 69: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/69.jpg)
finally…
![Page 70: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/70.jpg)
Search for:
Doing SQL from PL/SQL
search.oracle.com
Technology Network
In the section:
• Read the detailed technical whitepaper
• It’s listed on the PL/SQL Homepage www.oracle.com/technetwork/database/features/plsql/
• Or…
![Page 71: Doing SQL from PL/SQL - · PDF fileDoing SQL from PL/SQL: Best and Worst Practices • An unattributed programmers’ axiom has it that rules exists to serve, not to enslave](https://reader034.vdocument.in/reader034/viewer/2022052607/5a72fbf97f8b9a93538e5570/html5/thumbnails/71.jpg)
<Insert Picture Here>
A Q &