This document discusses five things about PL/SQL that you may not know. It begins by introducing the author Thomas Kyte and his background. The five topics covered are:
1. Trigger Trickery - How database triggers can actually fire multiple times and see data differently than expected.
2. Why you need to ignore errors (really) - Error handling is often done incorrectly, and it's better to ignore errors unless expecting them.
3. Elaboration Code - Code can run when a package is first "touched" or initialized without an explicit call.
4. Implicit conversions are beyond evil - Implicit type conversions can cause subtle bugs and should be avoided.
5. What
Sine Wave Generator with controllable frequency displayed on a seven segment ...Karthik Rathinavel
• Designed a Sine Wave Generator Hardware, whose frequency could be controlled using a quadrature encoder.
• Coded the FPGA board in System Verilog to display a count (going from 0 to 9999) on to a seven segment board. This count that was displayed, was same as the frequency of the sine wave generated.
• Incorporated a brightness control feature for all the digits being displayed. This was done by changing the duty cycle using a push button for the PWM control.
• Included an additional feature of increasing the count and the frequency by tens, hundreds or thousands, instead of increasing by just one.
Sine Wave Generator with controllable frequency displayed on a seven segment ...Karthik Rathinavel
• Designed a Sine Wave Generator Hardware, whose frequency could be controlled using a quadrature encoder.
• Coded the FPGA board in System Verilog to display a count (going from 0 to 9999) on to a seven segment board. This count that was displayed, was same as the frequency of the sine wave generated.
• Incorporated a brightness control feature for all the digits being displayed. This was done by changing the duty cycle using a push button for the PWM control.
• Included an additional feature of increasing the count and the frequency by tens, hundreds or thousands, instead of increasing by just one.
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгинodnoklassniki.ru
Crash dump as the block box of crashed JVM by Andrey Pangin. A talk from jokerconf.com.
Виртуальная машина Java способна отловить широкий спектр ошибок программирования. Результат она выдаст в виде исключения со стек-трейсом. Но что делать, если падает сама JVM, оставив лишь предсмертную записку под именем hs_err.log с загадочным содержимым?
В докладе я расскажу, что же зашифровано в аварийном дампе, и как эту информацию можно использовать для анализа проблемы и поиска причины. Мы рассмотрим ситуации, в которых JVM может сломаться, и в режиме живой демонстрации разберем примеры реальных падений, случившихся при разработке высоконагруженных приложений.
I gave a talk in coscup 2011. My topic is about using openframeworks in mobile application. :)
You can download the demo code from github. https://github.com/janetyc/CosBird
Dat testing - An introduction to Java and Android TestingSaúl Díaz González
Testing is a part of software engineering process. You wouldn't promote a code you haven't tested to production, so why don't you use automated testing and actually reduce costs and increase the efficiency?
You can also learn how doing testing can put pressure on your code to improve your architecture.
Dan Towner of ACCU Bristol & Bath, presenting at the Bristol IT MegaMeet 2013
This talk aims to demystify the clever parts of compilers that nobody ever told you about, explaining their inner secrets in simple terms. Come along to find out what induction variables do, what software pipelining is, how vectorisation works, how code scheduling is done, and how the debugger makes sense of it all.
See the video of the presentation here: http://www.youtube.com/watch?v=aeyf6wfxbL4
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгинodnoklassniki.ru
Crash dump as the block box of crashed JVM by Andrey Pangin. A talk from jokerconf.com.
Виртуальная машина Java способна отловить широкий спектр ошибок программирования. Результат она выдаст в виде исключения со стек-трейсом. Но что делать, если падает сама JVM, оставив лишь предсмертную записку под именем hs_err.log с загадочным содержимым?
В докладе я расскажу, что же зашифровано в аварийном дампе, и как эту информацию можно использовать для анализа проблемы и поиска причины. Мы рассмотрим ситуации, в которых JVM может сломаться, и в режиме живой демонстрации разберем примеры реальных падений, случившихся при разработке высоконагруженных приложений.
I gave a talk in coscup 2011. My topic is about using openframeworks in mobile application. :)
You can download the demo code from github. https://github.com/janetyc/CosBird
Dat testing - An introduction to Java and Android TestingSaúl Díaz González
Testing is a part of software engineering process. You wouldn't promote a code you haven't tested to production, so why don't you use automated testing and actually reduce costs and increase the efficiency?
You can also learn how doing testing can put pressure on your code to improve your architecture.
Dan Towner of ACCU Bristol & Bath, presenting at the Bristol IT MegaMeet 2013
This talk aims to demystify the clever parts of compilers that nobody ever told you about, explaining their inner secrets in simple terms. Come along to find out what induction variables do, what software pipelining is, how vectorisation works, how code scheduling is done, and how the debugger makes sense of it all.
See the video of the presentation here: http://www.youtube.com/watch?v=aeyf6wfxbL4
Too many of us have been taught that views are nothing more than stored SQL statements. The goal of this presentation is to challenge this notion. Or, to be precise, to take you one step further, from technicalities to the huge role that well-designed views can play in contemporary database solutions.
Current views are very advanced. They can be built on top of user-defined functions; they can utilize extremely complex INSTEAD-OF triggers (including composite ones), and they can even have indexes! As a result, with all of this added functionality views can serve as an isolation level between UI-driven data representation (heavily denormalized and customized) and DBA-driven data representation (normalized with referential integrity constraints and foreign keys).
Contemporary IT solutions often take this transformation completely out of the database, usually moving it to the middle-tier. This presentation will show that keeping business logic IN the database provides you with much greater flexibility, manageability, and performance. Of course, there are some traps and pitfalls, but these are also avoidable. Real-world examples will be provided to show that the role of views is seriously underestimated.
Slides from the ITOUG events in Rome and Milan 2020.
Most people think of the Flashback features in Oracle as the "In Case of Emergency" switch, to only be used when some catastrophe has occurred on your database. And while it is true that Flashback will definitely help you 3 seconds after you press the Commit button and you realise that you probably needed to have a WHERE clause on that "delete all rows from the SALES table" SQL statement. Or for when you run "drop table" on the Production database, when you were just so sure that you were logged onto the Test system. But Flashback is not only for those "Oh No!" moments. It enables benefits for developers ranging from data consistency to continuous integration and data auditing. Tucked away in Enterprise Edition are six independent and powerful technologies that might just save your career—they will also open up a myriad of other benefits of well.
Another year goes by, and most likely, another data access framework has been invented. It will claim to be the fastest, smartest way to talk to the database, and just like all those that came before it, it will not be. Because the best database access tool has been there for more than 30 years now, and that is PL/SQL. Although we all sometimes fall prey to the mindset of “Oh look, a shiny new tool, we should start using it," the performance and simplicity of PL/SQL remain unmatched. This session looks at the failings of other data access languages, why even a cursory knowledge of PL/SQL will make you a better developer, and how to get the most out of PL/SQL when it comes to database performance.
Analytic SQL functions, or "window functions have been there since 8.1.6, but they are still dramatically underused by application developers. This session looks at the syntax and usage of analytic functions, and how they can supercharge your SQL skillset.
Covers analytics from their inception in 8.1.6 all the through to enhancements in 18 and 19
Sangam 19 - Successful Applications on AutonomousConnor McDonald
The autonomous database offers insane levels of performance, but you won't be able to attain that if you are not constructing your SQL statements in a way that is scalable...and more importantly, secure from hacking
By expanding our knowledge of SQL facilities, we can let all the boring work be handled via SQL rather than a lot of middle-tier code, and we can get performance benefits as an added bonus. Here are some SQL techniques to solve problems that would otherwise require a lot of complex coding, freeing up your time to focus on the delivery of great applications.
APEX tour 2019 - successful development with autonomousConnor McDonald
The autonomous database offers insane levels of performance, but you won't be able to attain that if you are not constructing your SQL statements in a way that is scalable...and more importantly, secure from hacking
Apologies for most pics missing and awful layout...you can thank slideshare for that :-(
Slides from the APAC Groundbreakers Tour from Perth and Melbourne legs. This session covered the features in 18c, 19c and 20c, along with the new free database offerings from Oracle from OpenWorld 2019
Slides from OpenWorld. Flashback has been around for long time yet people assume it should entirely within the realm of the DBA. But with modern development techniques such as continuous integration/continuous deployment, flashback actually is a perfect for *developers*
Slides from the OpenWorld talk on read consistency. It is the feature that makes Oracle such a great database for performance and concurrency. But if misunderstood, it can lead to confusion for developers
Slides from OpenWorld 2019. Want to make sure your applications are slow, burn lots of CPU, and are easily broken into by hackers? Well...in reality, if you know how to do this, then you'll know how to avoid it.
Slides from Openworl 2019. A look at how to safely (and unsafely) kill sessions in the Oracle database, and how to perhaps avoid killing them altogether.
Flashback is not only for those "Oh No!" moments when we make a mistake. It enables benefits for developers ranging from data consistency to continuous integration and data auditing. Tucked away in Enterprise Edition are six independent and powerful technologies that might just save your career—they will also open up a myriad of other benefits of well.
Latin America Tour 2019 - 10 great sql featuresConnor McDonald
By expanding our knowledge of SQL facilities, we can let all the boring work be handled via SQL rather than a lot of middle-tier code, and we can get performance benefits as an added bonus. Here are some SQL techniques to solve problems that would otherwise require a lot of complex coding, freeing up your time to focus on the delivery of great applications.
Latin America Tour 2019 - slow data and sql processingConnor McDonald
Well done! You've come up with the killer idea for 2020. You've got the best UI design anyone has ever seen! Your modern application ticks all the boxes — serverless, functional, Kubernetes, microservices, API-based, the list goes on. It runs on every OS and every type of device. But unfortunately, all of this counts for absolutely NOTHING if your data access is slow or buggy. But an Autonomous database will fix all that right? Only if you understand the fundamentals of how SQL is processed by the database. For novice developers, SQL can be hard to understand and sometimes totally hidden from view under an ORM. Let's peel back the covers to show how SQL is processed, how to avoid getting hacked, and how to get data back to your application in a snappy fashion.
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
Here is something new! In our next Connector Corner webinar, we will demonstrate how you can use a single workflow to:
Create a campaign using Mailchimp with merge tags/fields
Send an interactive Slack channel message (using buttons)
Have the message received by managers and peers along with a test email for review
But there’s more:
In a second workflow supporting the same use case, you’ll see:
Your campaign sent to target colleagues for approval
If the “Approve” button is clicked, a Jira/Zendesk ticket is created for the marketing design team
But—if the “Reject” button is pushed, colleagues will be alerted via Slack message
Join us to learn more about this new, human-in-the-loop capability, brought to you by Integration Service connectors.
And...
Speakers:
Akshay Agnihotri, Product Manager
Charlie Greenberg, Host
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
Are you looking to streamline your workflows and boost your projects’ efficiency? Do you find yourself searching for ways to add flexibility and control over your FME workflows? If so, you’re in the right place.
Join us for an insightful dive into the world of FME parameters, a critical element in optimizing workflow efficiency. This webinar marks the beginning of our three-part “Essentials of Automation” series. This first webinar is designed to equip you with the knowledge and skills to utilize parameters effectively: enhancing the flexibility, maintainability, and user control of your FME projects.
Here’s what you’ll gain:
- Essentials of FME Parameters: Understand the pivotal role of parameters, including Reader/Writer, Transformer, User, and FME Flow categories. Discover how they are the key to unlocking automation and optimization within your workflows.
- Practical Applications in FME Form: Delve into key user parameter types including choice, connections, and file URLs. Allow users to control how a workflow runs, making your workflows more reusable. Learn to import values and deliver the best user experience for your workflows while enhancing accuracy.
- Optimization Strategies in FME Flow: Explore the creation and strategic deployment of parameters in FME Flow, including the use of deployment and geometry parameters, to maximize workflow efficiency.
- Pro Tips for Success: Gain insights on parameterizing connections and leveraging new features like Conditional Visibility for clarity and simplicity.
We’ll wrap up with a glimpse into future webinars, followed by a Q&A session to address your specific questions surrounding this topic.
Don’t miss this opportunity to elevate your FME expertise and drive your projects to new heights of efficiency.
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
Keynote at DIGIT West Expo, Glasgow on 29 May 2024.
Cheryl Hung, ochery.com
Sr Director, Infrastructure Ecosystem, Arm.
The key trends across hardware, cloud and open-source; exploring how these areas are likely to mature and develop over the short and long-term, and then considering how organisations can position themselves to adapt and thrive.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
3. 3
Who am I
• Been with Oracle since 1993
• User of Oracle since 1987
• The “Tom” behind AskTom in
Oracle Magazine
www.oracle.com/oramag
• Expert Oracle Database
Architecture
• Effective Oracle by Design
• Expert One on One Oracle
• Beginning Oracle
4. 4
<Insert Picture Here>
Five things you probably didn’t know about
PL/SQL
• Trigger Trickery
• Why you need to ignore errors (really)
• Elaboration Code
• Implicit conversions are beyond evil
• What About Roles…
6. 6
<Insert Picture Here>
Trigger Trickery
• When do your triggers actually fire?
• What do your triggers actually see?
• How many times can a row level trigger fire?
• Will your trigger actually fire?
• Does your trigger prevent things from happening
as you think they should?
7. 7
<Insert Picture Here>
Trigger Trickery
• When do your triggers actually fire?
• What do your triggers actually see?
– Before trigger sees ‘nothing’
– Before for each row trigger sees what the row might look like
(consistent read) and what that row might become (based on
consistent read
– After trigger sees the row as it was before and after the row
update. This may or may not be what the row looks like after the
modification is done! (because of what is coming)
– After trigger sees ‘nothing’
8. 8
<Insert Picture Here>
Trigger Trickery
• How many times can a trigger fire?
– Before – twice
– Before, for each row – twice per row
– After, for each row – twice per row (except for the last
row to be updated – it can only fire once ;) )
– After - once
9. 9
Trigger Trickery
ops$tkyte%ORA11GR2> create table t ( x int, y int );
Table created.
ops$tkyte%ORA11GR2> insert into t values ( 1, 0 );
1 row created.
ops$tkyte%ORA11GR2> insert into t values ( 2, 0 );
1 row created.
ops$tkyte%ORA11GR2> insert into t values ( 3, 0 );
1 row created.
10. 10
Trigger Trickery
ops$tkyte%ORA11GR2> create or replace trigger t_bu
2 before update on t
3 begin
4 dbms_output.put_line
5 ( 'I am the before trigger firing' );
6 end;
7 /
Trigger created.
11. 11
Trigger Trickery
ops$tkyte%ORA11GR2> create or replace trigger t_bufer
2 before update on t for each row
3 begin
4 dbms_output.put_line
5 ( 'BUFER: changing ' ||
6 :old.x || ', ' || :old.y ||
7 ' to ' || :new.x || ', ' || :new.y );
8 end;
9 /
Trigger created.
12. 12
Trigger Trickery
ops$tkyte%ORA11GR2> create or replace trigger t_aufer
2 after update on t for each row
3 begin
4 dbms_output.put_line
5 ( 'AUFER: changed ' ||
6 :old.x || ', ' || :old.y ||
7 ' to ' || :new.x || ', ' || :new.y );
8 end;
9 /
Trigger created.
13. 13
Trigger Trickery
ops$tkyte%ORA11GR2> create or replace trigger t_au
2 after update on t
3 begin
4 dbms_output.put_line
5 ( 'I am the after trigger firing' );
6 end;
7 /
Trigger created.
14. 14
Trigger Trickery
Session 1> update t set y = 100 where x = 3;
I am the before trigger firing
BUFER: changing 3, 0 to 3, 100
AUFER: changed 3, 0 to 3, 100
I am the after trigger firing
1 row updated.
NOTE: no commit!
15. 15
Trigger Trickery
Session 2> update t set y = 42;
NOTE: this is a second session, this blocks of course
since the first session has row ‘3’ locked already.
16. 16
Trigger Trickery
Session 1> commit;
Commit complete.
NOTE: this is the first session, the one blocking the
second session
17. 17
Trigger Trickery
Session 2> update t set y = 42;
I am the before trigger firing
BUFER: changing 1, 0 to 1, 42
AUFER: changed 1, 0 to 1, 42
BUFER: changing 2, 0 to 2, 42
AUFER: changed 2, 0 to 2, 42
BUFER: changing 3, 0 to 3, 42 <= <= how did that happen?
I am the before trigger firing
BUFER: changing 1, 0 to 1, 42
AUFER: changed 1, 0 to 1, 42
BUFER: changing 2, 0 to 2, 42
AUFER: changed 2, 0 to 2, 42
BUFER: changing 3, 100 to 3, 42
AUFER: changed 3, 100 to 3, 42
I am the after trigger firing
3 rows updated.
18. 18
<Insert Picture Here>
Trigger Trickery
• So, what does that mean?
– Never do anything non-transactional in a trigger
– Pragma autonomous_transaction is a really bad idea
in general
– UTL_ packages – really bad idea. They do not roll
back (utl_file, utl_http, utl_smtp, etc etc etc)
– Even just setting global variables in a trigger can be
tricky
19. 19
<Insert Picture Here>
Trigger Trickery
• Will your trigger actually fire?
– No, not always
• Does your trigger prevent things from happening
as you think they should?
– Yes, sometimes
20. 20
Trigger Trickery
ops$tkyte%ORA11GR2> create table t ( x int, y int );
Table created.
ops$tkyte%ORA11GR2> create or replace trigger t
2 before insert on t for each row
3 begin
4 :new.y := -:new.x;
5 end;
6 /
Trigger created.
21. 21
Trigger Trickery
ops$tkyte%ORA11GR2> insert into t ( x, y ) values ( 100, 200 );
1 row created.
ops$tkyte%ORA11GR2> select * from t;
X Y
---------- ----------
100 -100
ops$tkyte%ORA11GR2> commit;
23. 23
Trigger Trickery
ops$tkyte%ORA11GR2> !sqlldr / t direct=y
SQL*Loader: Release 11.2.0.2.0 - Production on Tue Oct 4
13:13:49 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates.
All rights reserved.
Load completed - logical record count 1.
25. 25
Trigger Trickery
ops$tkyte%ORA11GR2> truncate table t;
Table truncated.
ops$tkyte%ORA11GR2> insert /*+ append */ into t select
100, 200 from dual;
1 row created.
ops$tkyte%ORA11GR2> select * from t;
X Y
---------- ----------
100 -100
The fact we can select from that table tells us direct
pathing did not happen
26. 26
Trigger Trickery
ops$tkyte%ORA11GR2> drop trigger t;
Trigger dropped.
ops$tkyte%ORA11GR2> truncate table t;
Table truncated.
ops$tkyte%ORA11GR2> insert /*+ append */ into t select
100, 200 from dual;
1 row created.
27. 27
Trigger Trickery
ops$tkyte%ORA11GR2> select * from t;
select * from t
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying
it in parallel
That is what you expect after a direct path insert!
Triggers prevent it.
29. 29
<Insert Picture Here>
Please do ignore errors (really)
• In my experience, error handling is done wrong
more often than it is done right
• You don’t want to catch all exceptions
• You want to catch specific exceptions you are
expecting (which means they aren’t exceptions)
• You should ignore all others – or of you do catch
them to clean up a resource, RE-RAISE them
30. 30
Please do ignore errors (really)
Begin p; end;
Is really executed from a client as if it were:
Begin
savepoint X;
p;
Exception
When others then
rollback to X;
RAISE;
End;
31. 31
Please do ignore errors (really)
ops$tkyte%ORA11GR2> create table t ( x int check (x>0) );
Table created.
32. 32
Please do ignore errors (really)
ops$tkyte%ORA11GR2> create or replace procedure noexceptions
2 as
3 begin
4 insert into t values ( 1 );
5 insert into t values ( 0 );
6 end;
7 /
Procedure created.
33. 33
Please do ignore errors (really)
ops$tkyte%ORA11GR2> create or replace procedure exceptions
2 as
3 begin
4 insert into t values ( 1 );
5 insert into t values ( 0 );
6 exception
7 when others
8 then
9 dbms_output.put_line( 'Error!!! ' || sqlerrm );
10 end;
11 /
Procedure created.
34. 34
Please do ignore errors (really)
ops$tkyte%ORA11GR2> exec noexceptions;
BEGIN noexceptions; END;
*
ERROR at line 1:
ORA-02290: check constraint (OPS$TKYTE.SYS_C0022770) violated
ORA-06512: at "OPS$TKYTE.NOEXCEPTIONS", line 5
ORA-06512: at line 1
ops$tkyte%ORA11GR2> select * from t;
no rows selected
35. 35
Please do ignore errors (really)
ops$tkyte%ORA11GR2> exec exceptions
Error!!! ORA-02290: check constraint (OPS$TKYTE.SYS_C0022770)
violated
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> select * from t;
X
----------
1
36. 36
Please do ignore errors (really)
It is ok to catch exceptions you are EXPECTING
Begin
…
begin
select x into y from t where …;
exception
when no_data_found then
y := 42;
end;
…
37. 37
Please do ignore errors (really)
It is ok to catch exceptions at the TOP-LEVEL to log/change them. But
re-raise them!
Begin
p;
Exception
When others then
new_error_message :=
log_error_using_autonomous_transaction;
raise_application_error( -20001, new_error_message );
End;
38. 38
<Insert Picture Here>
Please do ignore errors (really)
• This is the #1 cause of bugs that I see time and
time again
• Do not catch exceptions at lower levels of code
(most – 99.99999999% of code – should not have a
when others)
• Do catch it at the highest level to log it, or to make it
“user friendly”
• When others not followed by
raise/raise_application_error should be a RED flag
39. 39
Please do ignore errors (really)
ops$tkyte%ORA11GR2> alter procedure bad_code compile
2 PLSQL_Warnings = 'enable:all'
3 reuse settings
4 /
SP2-0805: Procedure altered with compilation warnings
ops$tkyte%ORA11GR2> show errors procedure bad_code
Errors for PROCEDURE BAD_CODE:
LINE/COL ERROR
-------- ---------------------------------------------------------------
--
1/1 PLW-05018: unit BAD_CODE omitted optional AUTHID clause;
default value DEFINER used
9/8 PLW-06009: procedure "BAD_CODE" OTHERS handler does not end in
RAISE or RAISE_APPLICATION_ERROR
41. 41
<Insert Picture Here>
Elaboration Code
• Did you know that you can have some code run
when a package is first ‘touched’
• Perform a one time setup operation
• Without having to call an “init” routine, set a flag,
etc
43. 43
Elaboration Code
ops$tkyte%ORA11GR2> create or replace package body my_package
2 as
3 g_some_global varchar2(30);
4
5 procedure p
6 is
7 begin
8 dbms_output.put_line( g_some_global );
9 end;
10
11
12
13 begin
14 g_some_global := 'result of some logic';
15 end;
16 /
Package body created.
45. 45
<Insert Picture Here>
Elaboration Code
• One time initialization
– DBMS_LDAP callout for example
13 begin
14 g_some_global := dbms_ldap…;
15 end;
16 /
– Load a lookup table
– Any sort of complex initialization that cannot be done
in a declare block
47. 47
<Insert Picture Here>
Implicit conversions are evil
• SQL/PLSQL are too ‘user friendly’ – unlike C
which complained about everything
• Implicit conversions of strings to numbers, strings
to dates, raw to string, etc are probably the #2
cause of bugs I see time and time again
• Even worse are the implicit conversions that rely
on default NLS settings!
48. 48
Implicit conversions are evil
ops$tkyte%ORA11GR2> create or replace procedure inj( p_date in date )
2 as
3 l_rec all_users%rowtype;
4 c sys_refcursor;
5 l_query long;
6 begin
7 l_query := '
8 select *
9 from all_users
10 where created = ''' ||p_date ||''''; -- DOUBLE implicit conversion!
11
12 dbms_output.put_line( l_query );
13 open c for l_query;
14
15 for i in 1 .. 5
16 loop
17 fetch c into l_rec;
18 exit when c%notfound;
19 dbms_output.put_line( l_rec.username || '.....' );
20 end loop;
…
49. 49
Implicit conversions are evil
7 l_query := '
8 select *
9 from all_users
10 where created = ''' ||p_date ||'''';
Creates a query that is semantically equivalent to:
Where created = to_date( to_char( date-field ) );
Two implicit conversions – both of which rely on the NLS_DATE
settings!
50. 50
Implicit conversions are evil
ops$tkyte%ORA11GR2> exec inj( sysdate )
select *
from all_users
where created = '04-OCT-11'
PL/SQL procedure successfully completed.
51. 51
Implicit conversions are evil
ops$tkyte%ORA11GR2> alter session set
2 nls_date_format = 'dd-mon-yyyy"'' or ''a'' = ''a"';
Session altered.
52. 52
Implicit conversions are evil
ops$tkyte%ORA11GR2> exec inj( sysdate )
select *
from all_users
where created = '04-oct-2011' or 'a' = 'a'
A.....
EBRAPP.....
EBRTBLS.....
UTIL.....
USER2.....
PL/SQL procedure successfully completed.
53. 53
Implicit conversions are evil
ops$tkyte%ORA11GR2> alter session set
2 nls_date_format = '"''union select tname,0,null from tab--"';
Session altered.
Select *
from all_users
where created = ''union select tname,0,null from tab--'
54. 54
<Insert Picture Here>
Implicit conversions are evil
• What about performance?
– Repeated conversions
– Access path reductions
– Partition elimination eliminated
55. 55
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_date varchar2(30) := '01-jan-2011';
3 l_start number;
4 begin
5 l_start := dbms_utility.get_cpu_time;
6
7 for i in 1 .. 10
8 loop
9 for x in ( select *
10 from big_table.big_table
11 where created = l_date )
12 loop
13 null;
14 end loop;
15 end loop;
16
17 dbms_output.put_line( 'CPU: ' ||
18 to_char( dbms_utility.get_cpu_time-l_start ) );
19 end;
20 /
CPU: 132
56. 56
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_date date := to_date( '01-jan-2011', 'dd-mon-yyyy' );
3 l_start number;
4 begin
5 l_start := dbms_utility.get_cpu_time;
6
7 for i in 1 .. 10
8 loop
9 for x in ( select *
10 from big_table.big_table
11 where created = l_date )
12 loop
13 null;
14 end loop;
15 end loop;
16
17 dbms_output.put_line( 'CPU: ' ||
18 to_char( dbms_utility.get_cpu_time-l_start ) );
19 end;
20 /
CPU: 94 30% less CPU in this case
57. 57
Implicit conversions are evil
ops$tkyte%ORA11GR2> create table t
2 ( x varchar2(20) constraint t_pk primary key,
3 y varchar2(30)
4 );
Table created.
ops$tkyte%ORA11GR2> insert into t
2 select user_id, username
3 from all_users;
47 rows created.
ops$tkyte%ORA11GR2> commit;
Commit complete.
58. 58
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_rec t%rowtype;
3 l_key number := 5;
4 begin
5 select * into l_rec from t where x = l_key;
6
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( x.plan_table_output );
11 end loop;
12 end;
13 /
59. 59
Implicit conversions are evil
SQL_ID 18796jgha0hwz, child number 0
-------------------------------------
SELECT * FROM T WHERE X = :B1
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
|* 1 | TABLE ACCESS FULL| T | 1 | 29 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("X")=:B1)
60. 60
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_rec t%rowtype;
3 l_key varchar2(20) := '5';
4 begin
5 select * into l_rec from t where x = l_key;
6
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( '.'||x.plan_table_output );
11 end loop;
12 end;
13 /
61. 61
Implicit conversions are evil
SQL_ID 18796jgha0hwz, child number 1
-------------------------------------
SELECT * FROM T WHERE X = :B1
Plan hash value: 1303508680
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 29 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | T_PK | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("X"=:B1)
62. 62
Implicit conversions are evil
ops$tkyte%ORA11GR2> CREATE TABLE t
2 (
3 dt date,
4 x int,
5 y varchar2(30)
6 )
7 PARTITION BY RANGE (dt)
8 (
9 PARTITION part1 VALUES LESS THAN(to_date('31-jan-2011', 'dd-mon-yyyy')),
10 PARTITION part2 VALUES LESS THAN(to_date('28-feb-2011', 'dd-mon-yyyy'))
11 )
12 /
Table created.
63. 63
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_date timestamp := timestamp'2011-01-15 00:00:00.000';
3 l_count number;
4 begin
5 select count(*) into l_count from t where dt = l_date;
6
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( '.'||x.plan_table_output );
11 end loop;
12 end;
13 /
64. 64
Implicit conversions are evil
SQL_ID 0t5m83d3m67q7, child number 0
-------------------------------------
SELECT COUNT(*) FROM T WHERE DT = :B1
Plan hash value: 3225603066
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| | | |
| 1 | SORT AGGREGATE | | 1 | 9 | | | | |
| 2 | PARTITION RANGE ALL| | 1 | 9 | 2 (0)| 00:00:01 | 1 | 2 |
|* 3 | TABLE ACCESS FULL | T | 1 | 9 | 2 (0)| 00:00:01 | 1 | 2 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(INTERNAL_FUNCTION("DT")=:B1)
65. 65
Implicit conversions are evil
ops$tkyte%ORA11GR2> declare
2 l_date date := to_date( '15-jan-2011', 'dd-mon-yyyy' );
3 l_count number;
4 begin
5 select count(*) into l_count from t where dt = l_date;
6
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( '.'||x.plan_table_output );
11 end loop;
12 end;
13 /
66. 66
Implicit conversions are evil
.SQL_ID 0t5m83d3m67q7, child number 1
.-------------------------------------
.SELECT COUNT(*) FROM T WHERE DT = :B1
.
.Plan hash value: 3660200434
.
.------------------------------------------------------------------------------------------------
.| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
.------------------------------------------------------------------------------------------------
.| 0 | SELECT STATEMENT | | | | 2 (100)| | | |
.| 1 | SORT AGGREGATE | | 1 | 9 | | | | |
.| 2 | PARTITION RANGE SINGLE| | 1 | 9 | 2 (0)| 00:00:01 | KEY | KEY |
.|* 3 | TABLE ACCESS FULL | T | 1 | 9 | 2 (0)| 00:00:01 | KEY | KEY |
.------------------------------------------------------------------------------------------------
.
.Predicate Information (identified by operation id):
.---------------------------------------------------
.
. 3 - filter("DT"=:B1)
67. 67
<Insert Picture Here>
Implicit conversions are evil
• Lots and lots of bugs
– What is ‘01/02/03’?
– where column = to_char(sysdate) – what does that
mean?
69. 69
<Insert Picture Here>
PL/SQL and roles
• Quote:
– To create without errors (to compile the subprogram or
package successfully) requires these additional
privileges: The owner of the subprogram or package
must be explicitly granted the necessary object
privileges for all objects referenced within the body of
the code.
– The owner cannot obtain required privileges
through roles.
Note by me: Not entirely true, but almost always true
70. 70
<Insert Picture Here>
PL/SQL and roles
• Why is this the case?
– Roles are for the hundreds/thousands of application users.
You have very few application schemas that need to have
compiled stored objects
– Direct GRANTS make monitoring the set of privileges a
schema needs infinitely easier than a massive hierarchy of
roles (least privilege)
– What should the effect of non-default, password protected,
application enabled roles?
71. 71
<Insert Picture Here>
PL/SQL and roles – Two Modes
• Definers Rights
– Default method for stored compiled code
– All code is compiled with base (no roles) privileges
granted directly to the owner of the procedure.
72. 72
<Insert Picture Here>
PL/SQL and roles – Two Modes
• Invokers Rights
– Default method for anonymous blocks
– Using authid current_user – All code is compiled with base
privileges granted directly to the owner of the procedure. Nothing
changes there – owner still needs direct access.
– SQL rights are re-evaluated at runtime using the current set of
privileges in place in the current session running the code.
• Tables accessed at runtime might be different than tables
checked against at compile time.
– PL/SQL bindings are fixed at compile time.
90. 90
<Insert Picture Here>
PL/SQL and roles – Two Modes
• Definers Rights comes first, it is the default, it should be
the default. It is correct 99.99999999% of the time
• Invokers Rights are good for
– Routines that need to run “as caller”. Running as the owner
would/could cause security issues (think SYS owned code)
– It is infrequently executed or doesn’t use SQL
– It uses dynamic SQL (typically). It is not bound to a fixed set
of tables. It is a utility
• DUMP_CSV()
• PRINT_TABLE()
91. 91
<Insert Picture Here>
PL/SQL and roles – Two Modes
• Invokers Rights will
– Lose the dependency mechanism
• They typically use dynamic SQL and even static is dynamic!
– Reduce the reliability of the stored code
• No compile time security checks for SQL really, short of the owner!
• Everything good about static SQL is lost typically
– Since SQL object references are not known until runtime and could be
different for everyone, you could flood the shared pool
– It is harder to develop and debug
92. 92
<Insert Picture Here>
PL/SQL and roles – Two Modes
• In my opinion
– The loss of roles is not an issue for stored procedures
– You want the concept of LEAST PRIVILEGE
– You want the ability to see exactly what an application
schema can and cannot do
– The ambiguity presented by non-default roles, etc is gone
– The performance hit we would necessarily take is removed
– Invokers rights should be used very sparingly