New PLSQL In 12c - Oracle

Transcription

1Copyright 2012, Oracle and/or its affiliates. All rights reserved.

New PL/SQL CapabilitiesinOracle Database 12cBryn Llewellyn,Distinguished Product Manager,Database Server Technologies DivisionOracle HQ2Copyright 2012, Oracle and/or its affiliates. All rights reserved.

The following is intended to outline our general product direction. It is intendedfor information purposes only, and may not be incorporated into any contract.It is not a commitment to deliver any material, code, or functionality, and shouldnot be relied upon in making purchasing decisions. The development, release,and timing of any features or functionality described for Oracle’s productsremains at the sole discretion of Oracle.3Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Agenda Improved client PL/SQL SQL interoperability A new security capability Improved programmer usability Miscellaneous4Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Performance improvement forPL/SQL functions called from SQL Example: pretty-print an integerselectPrint(n1)Print(n2)Print(n3)from byteKKbytebytebyteK115711121422302Copyright 2012, Oracle and/or its affiliates. All rights reserved.GMGGGGGMGM56641697112201231672GGGTGTTTTG

The “algorithm” Pretty-print an integer as a multiple of anappropriate power of 1024: plain, K, M, B, or Tfunction Print(n in integer) return varchar2 authid Definer isK constant number not null : 1024;M constant number not null : K*K;G constant number not null : M*K;T constant number not null : G*K;beginreturncasewhen n K-1 then To Char(n,'999999') 'byte'when n/K K-1 then To Char(n/K, '999999') 'K'when n/M K-1 then To Char(n/M, '999999') 'M'when n/G K-1 then To Char(n/G, '999999') 'G'elseTo Char(n/T, '999999') 'T'end;end Print;6Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Try it in pure eend"n3"from t7n1n1/1024n1/1048576n1/1073741824 1023102310231023thenthenthenthenTo Char(n1,To Char(n1/1024,To Char(n1/1048576,To Char(n1/1073741824,To Char(n1/1099511627776,'999999') ''999999') ''999999') ''999999') ''999999') 'byte'K'M'G'T'n2n2/1024n2/1048576n2/1073741824 1023102310231023thenthenthenthenTo Char(n2,To Char(n2/1024,To Char(n2/1048576,To Char(n2/1073741824,To Char(n2/1099511627776,'999999') ''999999') ''999999') ''999999') ''999999') 'byte'K'M'G'T'n3n3/1024n3/1048576n3/1073741824 1023102310231023thenthenthenthenTo Char(n3,To Char(n3/1024,To Char(n3/1048576,To Char(n3/1073741824,To Char(n3/1099511627776,'999999') ''999999') ''999999') ''999999') ''999999') 'byte'K'M'G'T'Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Get the performance of SQL with theclarity and reusability of PL/SQLfunction Print(n in integer) return varchar2 authid Definer ispragma UDF;K constant number not null : 1024;M constant number not null : K*K;G constant number not null : M*K;T constant number not null : G*K;beginreturncasewhen n K-1 then To Char(n,when n/K K-1 then To Char(n/K,when n/M K-1 then To Char(n/M,when n/G K-1 then To Char(n/G,elseTo Char(n/T,end;end Print;8Copyright 2012, Oracle and/or its affiliates. All rights reserved.'999999') 'byte''999999') 'K''999999') 'M''999999') 'G''999999') 'T'

Declare the PL/SQL functionin the subquery’s with clausewithfunction Print(n in integer) return varchar2 isK constant number not null : 1024;M constant number not null : K*K;G constant number not null : M*K;T constant number not null : G*K;beginreturncasewhen n K-1 then To Char(n,'999999') 'when n/K K-1 then To Char(n/K, '999999') 'when n/M K-1 then To Char(n/M, '999999') 'when n/G K-1 then To Char(n/G, '999999') 'elseTo Char(n/T, '999999') 'end;end Print;selectPK,Print(n1) "n1",Print(n2) "n2",Print(n3) "n3"from t9Copyright 2012, Oracle and/or its affiliates. All rights reserved.byte'K'M'G'T'

Performance comparison Pure SQL5.0xis fastest Schema-level function with pragma UDF3.9xis close Function in the with clause3.8xis similar Pre-12.1 ordinary schema-level functionis very much the slowest10Copyright 2012, Oracle and/or its affiliates. All rights reserved.1.0 – the baseline

Binding values of PL/SQL-only datatypesinto SQL statements Before 12.1, you could bind only values of SQLdatatypes In 12.1, you can bind PL/SQL index-by-pls integertables (of records) and booleans from client-side programs – OCI or both flavorsof JDBC – and from PL/SQL to anonymous blocks, statements usingfunctions, or statements using the table operator11Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Binding a PL/SQL index-by table to SQL Before 12.1, you could invoke a function with acollection actual, or select from a collection, but The type had to be defined at schema-level Therefore it had to be a nested table or a varray A non-scalar payload had to be an ADT New in 12.1 The type can be defined in a package spec – can beindex by pls integer table The payload can be a record – but the fieldsmust still be SQL datatypes12Copyright 2012, Oracle and/or its affiliates. All rights reserved.

The collectionpackage Pkg authid Definer istype r is record(n integer, v varchar2(10));type t is table of r index by pls integer;x t;end Pkg;13Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example:binding an IBPI to a PL/SQL function in SQLfunction f(x in Pkg.t) return varchar2 authid Definer isr varchar2(80);beginfor j in 1.x.Count() loopr : r .;end loop;return r;end f;procedure Bind IBPI To Fn In SQL authid Definer isv varchar2(80);beginselect f(Pkg.x) into v from Dual;.execute immediate 'select f(:b) from Dual' into vusing Pkg.x;end Bind IBPI To Fn In SQL;14Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example:binding to the operand of the table operatorprocedure Select From IBPI authid Definer isy Pkg.t;beginfor j in (select n, v from table(Pkg.x)) loop.end loop;execute immediate 'select n, v from table(:b)'bulk collect into yusing Pkg.x;for j in 1.y.Count() loop.end loop;end Select From IBPI;15Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example:binding an IBPI to an anonymous blockprocedure p1(x in Pkg.t) authid Definer isbeginfor j in 1.x.Count() loop.;end loop;end p1;procedure Bind IBPI To Anon Block authid Definer isbeginexecute immediate 'begin p1(:b); end;' using Pkg.x;end Bind IBPI To Anon Block;16Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example:binding a boolean to an anonymous blockprocedure p2(b in boolean) authid Definer isbeginDBMS Output.Put Line(case bwhen true then 'True'when false then 'False'else'Null'end);end p2;procedure Bind Boolean To Anon Block authid Definer isNil constant boolean : null; -- workaround for existing bugbeginexecute immediate 'begin p2(:b); end;' using true;execute immediate 'begin p2(:b); end;' using false;execute immediate 'begin p2(:b); end;' using Nil;end Bind Boolean To Anon Block;17Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Binding PL/SQL types in JDBC Before 12.1 Generate a schema level object type to mirror thestructure of the non-SQL package type Populate and bind the object into a custom PL/SQLwrapper around the desired PL/SQL subprogram Convert the object to the package type in the wrapperand call the PL/SQL subprogram with the package type18Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Binding PL/SQL types in JDBC New in 12.1 PL/SQL package types supported as binds in JDBC Can now execute PL/SQL subprograms with non-SQLtypes Supported types include records, index-by tables,nested tables and varrays Table%rowtype, view%rowtype and package definedcursor%rowtype also supported. They’re technicallyrecord types19Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example 1: Bind a single record from Javainto a PL/SQL procedure, modify it,and bind it back out to Javapackage Emp Info istype employee is record(First NameLast NameEmployee IdIs CEOEmployees.First Name%type,Employees.Last Name%type,Employees.Employee Id%type,boolean);procedure Get Emp Name(Emp p in out Employee);end;20Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example 1: Use the EmpinfoEmployee class, generated byJPub, to implement the Employee formal parameter{ EmpinfoEmployee Employee new EmpinfoEmployee();Employee.setEmployeeId(new java.math.BigDecimal(100));// Use Employee ID 100// Call Get Emp Name() with the Employee objectOracleCallableStatement cstmt (OracleCallableStatement)conn.prepareCall("call EmpInfo.Get Emp Name(?)");cstmt.setObject(1, Employee, OracleTypes.STRUCT);// Use "PACKAGE.TYPE NAME" as the type namecstmt.registerOutParameter(1, OracleTypes.STRUCT, "EMPINFO.EMPLOYEE");cstmt.execute();// Get and print the contents of the Employee objectEmpinfoEmployee oraData (EmpinfoEmployee)cstmt.getORAData(1, intln("Employee: " oraData.getFirstName() " " oraData.getLastName());System.out.println("Is the CEO? " oraData.getIsceo());}21Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example 2: populate a collection of table%rowtypeusing a bulk collect statement, and pass the collectionas an out parameter back to the callerpackage EmpRow istype Table of Emp is table of Employees%Rowtype;procedure GetEmps(Out Rows out Table of Emp);end;package Body EmpRow isprocedure GetEmps(Out Rows out Table of Emp) isbeginselect *bulk collect into Out Rowsfrom Employees;end;end;22Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Example 2:{ // Call GetEmps() to get the ARRAY of table row data objectsCallableStatement cstmt conn.prepareCall("call EmpRow.GetEmps(?)");// Use "PACKAGE.COLLECTION NAME" as the type namecstmt.registerOutParameter(1, OracleTypes.ARRAY, "EMPROW.TABLE OF EMP");cstmt.execute();// Print the Employee Table rowsArray a cstmt.getArray(1);String s Debug.printArray ((ARRAY)a, "",((ARRAY)a).getSQLTypeName () "( ", conn);System.out.println(s);}23Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Binding PL/SQL-only datatypes into SQL statements:restrictions The PL/SQL-only datatypes must be declared in apackage spec The record fields of the IBPI must be SQL datatypes Only IBPI, not index-by-varchar2 Cannot bind into insert, update, delete, or merge Cannot bind using DBMS Sql24Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Agenda Improved client PL/SQL SQL interoperability A new security capability Improved programmer usability Miscellaneous25Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unit Consider this best practice Give access to an application’s data only via PL/SQLsubprograms Reinforce this by having end-user sessions authorizeas a different database owner than the one that owns theapplication’s artifacts Arrange this by using definer’s rights units in a single schema ora couple of schemas. Then grant Execute on these to end-users– but don’t grant privileges on the tables to end-users This means that each unit can access very many tablesbecause the owner of the units can26Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unit 12.1 lets us have a fine-grained scheme where each unitwith the same owner can have different privileges on theowner’s tables The end-user is low-privileged, just as in the old scheme The units are invoker’s rights, so “as is” would not allow end-users to access the data The privilege for each unit is elevated for exactly and only thatunit’s purpose by granting a role that has the appropriateprivileges to the unit. Such a role cannot be disabled. The unit’s owner must already have that same role (but it neednot be enabled)27Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unit This scenario lets us illustrate the idea There are two users App and Client There are two tables App.t1 and App.t2 There are two IR procedures App.Show t1 and App.Show t2 torun select statements against the tables Client has Execute on App.Show t1 and App.Show t2 App creates two roles r Show t1 and r Show t2 App grants Select on App.t1 to r Show t1 – and similar for 2 App grants r Show t1 to App.Show t1 – and similar for 228Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unitcreate procedure Show t1 authid Current User isbeginfor j in (select Fact from App.t1 order by 1) loop -- Notice the schema-qualification.end loop;end Show t1;/grant Execute on App.Show t1 to Client/-- this has the side-effect of granting the role to App with Admin option-- other non-schema object types like directories and editions behave the samecreate role r Show t1/grant select on t1 to r Show t1/grant r Show t1 to procedure Show t1/select Object Name, Object Type, Rolefrom User Code Role Privs/.SHOW T129.PROCEDURE.R SHOW T1Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unit When Client invokes App.Show t1, then no matter whatcareless mistakes the programmer of the procedure mightlater make, its power is limited to just what the role confers.30Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Granting a role to a PL/SQL unit This new feature has no effect on static referencesat PL/SQL compilation time31Copyright 2012, Oracle and/or its affiliates. All rights reserved.

The “inherit privileges” privilege Functional requirement Reduce the risk that would be caused should Oracle-shipped code owned bya highly privileged user (esp. e.g. Sys) have a SQL injection vulnerability. An IR unit executes with the security regime of the invoker. So if a DR unitowned by Sys has an injection vulnerability, then an unscrupulous person whocan authorize a session as a Scott-like user could write an IR unit and exploitthe injection vulnerability to get it invoked with Sys's security regime. The new feature closes this loophole because, as shipped, Sys has granted"inherit privileges" only to a small number of other Oracle-maintained users.The same holds for about 30 other Oracle-maintained users.32Copyright 2012, Oracle and/or its affiliates. All rights reserved.

The “inherit privileges” privilege Follow-on requirement Had to cause no change in behavior for customer-created code -- at least tothe extent that this followed Oracle's guidelines Caveat is illustrated by an extant customer-created DR unit owned by Systhat called an IR unit owned by a customer-created user. This would break onupgrade to 12.1. But this is so very much against the rules that we'recomfortable with this.33Copyright 2012, Oracle and/or its affiliates. All rights reserved.

“bequeath Current User” views The Current User who issues the SQL against the view isseen in IR functions invoked in the view’s defining subquery Compare this with the “classic” DR view where the viewowner is seen in IR functions invoked in the view’s definingsubquery34Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Agenda Improved client PL/SQL SQL interoperability A new security capability Improved programmer usability Miscellaneous35Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Whitelist You can declare that a particular unit may bereferenced only by other listed units You cannot list the anonymous block and so awhitelisted unit cannot be called dynamically andcannot be invoked from outside of the database36Copyright 2012, Oracle and/or its affiliates. All rights reserved.

accessible by clausepackage Helper authid Definer accessible by (Good Unit,Bad Unit)isprocedure p;end Helper;package body Good Unit isprocedure p isbeginHelper.p();.end p;end Good Guy;package body Bad Unit isprocedure p isbeginHelper.p();PLS-00904: insufficient privilege to access object HELPER.end p;end Bad Guy;37Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Improved call stack introspection Before 12.1, you used three functions in theDBMS Utility package Format Call Stack() Format Error Stack() Format Error Backtrace() New in 12.1 The package UTL Call Stack solves thesame problem properly38Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Code to be introspectedpackage body Pkg isprocedure p isprocedure q isprocedure r isprocedure p isbeginPrint Call Stack();end p;beginp();end r;beginr();end q;beginq();end p;end Pkg;39Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Pre 12.1 Print Call Stack()procedure Print Call Stack authid Definer isbeginDBMS Output.Put Line(DBMS Utility.Format Call Stack());end;----- PL/SQL Call Stack ----objectline objecthandlenumber name0x631f6e8812 procedure USR.PRINT CALL STACK0x685877007 package body USR.PKG0x6858770010 package body USR.PKG0x6858770013 package body USR.PKG0x6858770016 package body USR.PKG0x69253ca81 anonymous block See bug 2769809 filed by Bryn, Jan 200340Copyright 2012, Oracle and/or its affiliates. All rights reserved.

12.1 Print Call Stack()procedure Print Call Stack authid Definer isDepth pls integer : UTL Call Stack.Dynamic Depth();beginfor j in reverse 2.Depth loopDBMS Output.Put Line((j - 1) To Char(UTL Call Stack.Unit Line(j), '99') UTL Call Stack.Concatenate Subprogram(UTL Call Stack.Subprogram(j)));end loop;end;543214111613107anonymous blockPKG.PPKG.P.QPKG.P.Q.RPKG.P.Q.R.PCopyright 2012, Oracle and/or its affiliates. All rights reserved.

Improved call stack introspection Symmetrical subprograms for error stack andbacktrace Plus Owner(Depth) Current Edition(Depth) Lexical Depth(Depth)42Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Agenda Improved client PL/SQL SQL interoperability A new security capability Improved programmer usability Miscellaneous43Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Other enhancements brought by 12.1 You can now result-cache an invoker’s rights function(the current user becomes part of the cache lookup key) Safe callouts (implemented via extproc) are faster(motivated by Oracle R Enterprise – which saw a 20xspeedup) Edition-based redefinition can now be adopted withoutneeding to change how objects are disposed amongschemas – so no reason at all for you not to use EBR forevery patch that changes only PL/SQL, views, or synonyms44Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Other enhancements brought by 12.1 pga aggregate limit – exceeding, e.g. by allowing acollection to become too big, it causes a fatal error DBMS Scheduler has new Job Types: Sql Script Backup Script Controlled by a new use of a credential encapsulates database username, password,and role – e.g. AS SYSDBA, AS SYSBACKUP45Copyright 2012, Oracle and/or its affiliates. All rights reserved.

46Copyright 2012, Oracle and/or its affiliates. All rights reserved.

47Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Title: New PL/SQL Capabilities in Oracle Database 12c Author: Bryn Llewelyn Subject: Oracle Database 12c; PL/SQL Keywords: Oracle Database; PL/SQL; DevelopmentFile Size: 912KBPage Count: 47