1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Oracle PL/SQL Language Pocket Reference- P19 docx

50 436 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 50
Dung lượng 168,8 KB

Nội dung

ORA-06571: Function TOTAL_COMP does not guarantee not to update database As discussed in Section 17.7, "Realities: Calling PL/SQL Functions in SQL", it can be very difficult at times (and sometimes impossible) to avoid this error. In other situations, however, there is an easy resolution (certainly do check the above list of restrictions). Previous: 17.3 Requirements for Stored Functions in SQL Oracle PL/SQL Programming, 2nd Edition Next: 17.5 Calling Packaged Functions in SQL 17.3 Requirements for Stored Functions in SQL Book Index 17.5 Calling Packaged Functions in SQL The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates. All rights reserved. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Previous: 17.4 Restrictions on PL/SQL Functions in SQL Chapter 17 Calling PL/SQL Functions in SQL Next: 17.6 Column/ Function Name Precedence 17.5 Calling Packaged Functions in SQL As I describe in Chapter 16, Packages, the specification and body of a package are distinct; a specification can (and must) exist before its body has been defined. This feature of packages makes life complicated when it comes to calling functions in SQL. When a SELECT statement calls a packaged function, the only information available to it is the package specification. Yet it is the contents of the package body which determine whether that function is valid for execution in SQL. The consequence of this structure is that you will have to add code to your package specification in order to enable a packaged function for calling in SQL. To use the official lingo, you must explicitly "assert" the purity level (the extent to which a function is free of side effects) of a stored function in a package specification. The Oracle Server can then determine when the package body is compiled whether the function violates that purity level. If so, an error will be raised and you then face the sometimes daunting task of figuring out where and how the violation occurs. You assert a purity level for a function with the RESTRICT_REFERENCES pragma, explored in the next section. 17.5.1 The RESTRICT_REFERENCES Pragma As I've mentioned, a pragma is a special directive to the PL/SQL compiler. If you have ever created a programmer-defined, named exception, you have already encountered your first pragma. In the case of the RESTRICT_REFERENCES pragma, you are telling the compiler the purity level you believe your function meets or exceeds. You need a separate pragma statement for each packaged function you wish to use in a SQL statement, and it must come after the function declaration in the package specification (you do not specify the pragma in the package body). To assert a purity level with the pragma, use the following syntax: Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. PRAGMA RESTRICT_REFERENCES (function_name, WNDS [, WNPS] [, RNDS] [, RNPS]) where function_name is the name of the function whose purity level you wish to assert, and the four different codes have the following meanings: WNDS Writes No Database State. Asserts that the function does not modify any database tables. WNPS Writes No Package State. Asserts that the function does not modify any package variables. RNDS Reads No Database State. Asserts that the function does not read any database tables. RNPS Reads No Package State. Asserts that the function does not read any package variables. Notice that only the WNDS level is mandatory in the pragma. That is consistent with the restriction that stored functions in SQL may not execute an UPDATE, INSERT, or DELETE statement. All other states are optional. You can list them in any order, but you must include the WNDS argument. No one argument implies another argument. I can write to the database without reading from it. I can read a package variable without writing to a package variable. Here is an example of two different purity level assertions for functions in the company_financials package: PACKAGE company_financials IS FUNCTION company_type (type_code_in IN VARCHAR2) RETURN VARCHAR2; FUNCTION company_name (company_id_in IN company. company_id%TYPE) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES (company_type, WNDS, RNDS, WNPS, RNPS); PRAGMA RESTRICT_REFERENCES (company_name, WNDS, WNPS, RNPS); END company_financials; In this package, the company_name function reads from the database to obtain the name for the specified company. Notice that I placed both pragmas together at the bottom of the package Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. specification -- the pragma does not need to immediately follow the function specification. I also went to the trouble of specifying the WNPS and RNPS arguments for both of the functions. Oracle Corporation recommends that you assert the highest possible purity levels so that the compiler will never reject the function unnecessarily. NOTE: If a function you want to call in SQL calls a procedure in a package, you must also provide a RESTRICT_REFERENCES pragma for that procedure. You can't call the procedure directly in SQL, but if it is going to be executed indirectly from within SQL, it still must follow the rules. 17.5.1.1 Pragma violation errors If your function violates its pragma, you will receive the PLS-00452 error. Suppose, for example, that the body of the company_financials package looks like this: CREATE OR REPLACE PACKAGE BODY company_financials IS FUNCTION company_type (type_code_in IN VARCHAR2) RETURN VARCHAR2 IS v_sal NUMBER; BEGIN SELECT sal INTO v_sal FROM emp WHERE empno = 1; RETURN 'bigone'; END; FUNCTION company_name (company_id_in IN company. company_id%TYPE) RETURN VARCHAR2 IS BEGIN UPDATE emp SET sal = 0; RETURN 'bigone'; END; END company_financials; / When I attempt to compile this package body I will get the following error: 3/4 PLS-00452: Subprogram 'COMPANY_TYPE' violates its associated pragma because the company_type function reads from the database and I have asserted the RNDS purity level. If I remove that silly SELECT statement, I will then receive this error: Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 11/4 PLS-00452: Subprogram 'COMPANY_NAME' violates its associated pragma because the company_name function updates the database and I have asserted the WNDS level. You will sometimes look at your function and say: "Hey, I absolutely do not violate my purity level. There is no UPDATE, DELETE, or UPDATE around." Maybe not. But there is a good chance that you are calling a built-in package or in some other way breaking the rules. 17.5.2 Asserting Purity Level with Package Initialization Section If your package contains an initialization section (executable statements after a BEGIN statement in the package body), you must also assert the purity level of that section. The initialization section is executed automatically the first time any package object is referenced. So if a packaged function is used in a SQL statement, it will trigger execution of that code. If the initialization section modifies package variables or database information, the compiler needs to know about that through the pragma. You can assert the purity level of the initialization section either explicitly or implicitly. To make an explicit assertion, use the following variation of the pragma RESTRICT_REFERENCES: PRAGMA RESTRICT_REFERENCES (package_name, WNDS, [, WNPS] [, RNDS] [, RNPS]) Instead of specifying the name of the function, you include the name of the package itself, followed by all the applicable state arguments. In the following argument I assert only WNDS and WNPS because the initialization section reads data from the configuration table and also reads the value of a global variable from another package (session_pkg.user_id). PACKAGE configure IS PRAGMA RESTRICT_REFERENCES (configure, WNDS, WNPS); user_name VARCHAR2(100); END configure; PACKAGE BODY configure IS BEGIN SELECT lname || ', ' || fname INTO user_name FROM user_table WHERE user_id = session_pkg.user_id; END configure; Why can I assert the WNPS even though I do write to the user_name package variable? The answer is that it's a variable from this same package, so the action is not considered a side effect. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. You can also implicitly assert the purity level of the package's initialization section by allowing the compiler to infer that level from the purity level(s) of all the pragmas for individual functions in the package. In the following version of the company package, the two pragmas for the functions allow the Oracle Server to infer a combined purity level of RNDS and WNPS for the initialization section. This means that the initialization section cannot read from the database and cannot write to a package variable. PACKAGE company IS FUNCTION get_company (company_id_in IN VARCHAR2) RETURN company%ROWTYPE; FUNCTION deactivate_company (company_id_in IN company. company_id%TYPE) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES (get_company, RNDS, WNPS); PRAGMA RESTRICT_REFERENCES (deactivate_name, WNPS); END company; Generally, you are probably better off providing an explicit purity level assertion for the initialization section. This makes it easier for those responsible for maintaining the package to understand both your intentions and your understanding of the package. Previous: 17.4 Restrictions on PL/SQL Functions in SQL Oracle PL/SQL Programming, 2nd Edition Next: 17.6 Column/ Function Name Precedence 17.4 Restrictions on PL/SQL Functions in SQL Book Index 17.6 Column/Function Name Precedence The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates. All rights reserved. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Previous: 17.5 Calling Packaged Functions in SQL Chapter 17 Calling PL/SQL Functions in SQL Next: 17.7 Realities: Calling PL/SQL Functions in SQL 17.6 Column/Function Name Precedence If your function has the same name as a table column in your SELECT statement and it has no parameters, then the column takes precedence over the function. The employee table has a column named "salary." Suppose you create a function named salary as well: CREATE TABLE employee (employee_id NUMBER, . , salary NUMBER, .); FUNCTION salary RETURN NUMBER; Then a SELECT statement referencing salary always refers to the column and not the function: SELECT salary INTO calculated_salary FROM employee; If you want to override the column precedence, you must qualify the name of the function with the name of the schema that owns the function, as follows: SELECT scott.salary INTO calculated_salary FROM employee; This now executes the function instead of retrieving the column value. Previous: 17.5 Calling Packaged Functions in SQL Oracle PL/SQL Programming, 2nd Edition Next: 17.7 Realities: Calling PL/SQL Functions in SQL 17.5 Calling Packaged Functions in SQL Book Index 17.7 Realities: Calling PL/ SQL Functions in SQL Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates. All rights reserved. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Previous: 17.6 Column/ Function Name Precedence Chapter 17 Calling PL/SQL Functions in SQL Next: 17.8 Examples of Embedded PL/SQL 17.7 Realities: Calling PL/SQL Functions in SQL The ability to call PL/SQL functions in SQL has been around since Release 2.1, but in many ways (at least until Oracle8) it can still be considered "bleeding edge" technology. Why? ● You must manually apply RESTRICT_REFERENCES pragmas to all of your code -- and you have to figure out where all those pragmas need to go. This process is described in a subsection below. ● Functions execute outside of the read consistency model of the Oracle database (!). This issue is also explored below in a subsection below. ● The overhead of calling a function from SQL remains high. The exact price you pay to call a function from within SQL (compared to, say, executing in-line SQL code) can be hard to pin down. It varies from computer to computer and even by instance or by the function being called; I have heard reports that range from an extra half-second to an astonishing additional 50 seconds (in that case, I suggested that they do some more analysis and debugging). Whatever the specific amount of time, the delay can be noticeable and you need to factor it into your design and test plans. ● Tuning mechanisms such as EXPLAIN PLAN do not take into account the SQL that may be called inside functions called in your SQL statement. PL/SQL functions are ignored by the EXPLAIN PLAN facility. This makes it very difficult to come up with a comprehensive understanding of performance bottlenecks and tuning needs. ● So much Oracle technology, especially that found in built-in packages, is declared "off limits" to functions in SQL. Just consider DBMS_OUTPUT. You can't use it in functions called in SQL. But ideally you will want to use those same functions in SQL and PL/SQL. Another issue may be that your standard debugging technique is to insert calls to a trace program at the beginning of each of your functions and procedures. Chances are that the trace program relies on DBMS_OUTPUT (or UTL_FILE or DBMS_PIPE or take your pick, they're all -- at least until Oracle8 -- off limits). Sorry! You will not be able to use that function in SQL. So you have to pull out some of the code from the function. As a result, you can end up with two versions of your code: one for PL/SQL and one for SQL. That is one nasty scenario for software developers. Let's examine two of these issues in more detail. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 17.7.1 Manual Application of Pragmas You must manually apply RESTRICT_REFERENCES pragmas to all of your code -- and you have to figure out where all those pragmas need to go. This process is often similar to a Sherlock Holmes plot. You compile a package and get a pragma violation error. This can happen because your program breaks a rule (like trying to change data) or because it calls other programs which break a rule. You notice in this case that your function calls five or six other functions or procedures, so you must apply pragmas to each of these. By doing so, you assert purity levels where none had been asserted before, raising more errors and in some cases significant architectural issues. For example, suppose that you suddenly have to apply a pragma to a procedure in package X and that package has an initialization section; you must then also pragma-tize the initialization section. A common practice in this section is to set up a PL/SQL table for in-memory manipulation of data. If you use any PL/SQL table methods to do this initialization, your pragma will fail. This can be a very frustrating exercise, at times leading to abandoning the effort to enable your function for execution in SQL. In my experience, you will want to identify in advance (as much as possible) those areas of your application which you will want to call in SQL. You will then strive to keep this code very "clean" and focused, with limited entanglements with other packages, and with an absolutely minimal use of built-in packaged functionality. Neither an easy nor a particularly desirable task. 17.7.2 Read Consistency Model Complications Yes, it is hard to believe, but quite true: unless you take special precautions, it is quite possible that your SQL query will violate the read consistency model of the Oracle RDBMS, which has been sacrosanct territory for years at Oracle. To understand this issue, consider the following query and the function it calls: SELECT name, total_sales (account_id) FROM account WHERE status = 'ACTIVE'; FUNCTION total_sales (id_in IN account.account_id%TYPE) RETURN NUMBER IS CURSOR tot_cur IS SELECT SUM (sales) total FROM orders WHERE account_id = id_in AND year = TO_NUMBER (TO_CHAR (SYSDATE, 'YYYY')); tot_rec tot_cur%ROWTYPE; BEGIN OPEN tot_cur; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... Column/Function Name Precedence Oracle PL/SQL Programming, 2nd Edition Book Index Next: 17.8 Examples of Embedded PL/SQL 17.8 Examples of Embedded PL/SQL The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates All rights reserved Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Previous: 17.7 Realities: Calling PL/SQL Functions in SQL Chapter 17 Calling PL/SQL Functions... Realities: Calling PL/SQL Functions in SQL 17.7 Realities: Calling PL/ SQL Functions in SQL Oracle PL/SQL Programming, 2nd Edition Next: V New PL/SQL8 Features Book Index V New PL/SQL8 Features The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates All rights reserved Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Previous: 17.8 Examples of Embedded PL/SQL Part... conventional relational tables Chapter 21, External Procedures, discusses how you can call out to non -PL/SQL programs from within Oracle Previous: 17.8 Examples of Embedded PL/SQL 17.8 Examples of Embedded PL/SQL Oracle PL/SQL Programming, 2nd Edition Book Index Next: 18 Object Types 18 Object Types The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates All rights reserved Please purchase... Next: 18 Object Types Part V: New PL/SQL8 Features Part V of this book contains the main discussion of the new features of Oracle8 that are relevant to PL/SQL q q q q Chapter 18, Object Types, describes the Oracle "object-relational model" and how the object features work Chapter 19, Nested Tables and VARRAYs, examines the two types of "collection" structures introduced in Oracle8 Chapter 20, Object Views,... Introduction to Oracle8 Objects When a mainstream vendor like Oracle Corporation ventures into new technology waters, it is virtually certain that the change will be evolutionary rather than revolutionary True to form, Oracle8 's relational capabilities are still the mainstay of Oracle Corporation's flagship database server, and these capabilities satisfy the need for compatibility with older Oracle versions... Comparison: Oracle8 Objects and Earlier Features In practical terms, object types live inside the Oracle database rather than inside PL/SQL programs That is, you must issue the SQL DDL statement, CREATE TYPE AS OBJECT in order to create a type; only then can you use the type within PL/SQL Once created, an object type defines an interface to a set of data There is no good analogy for this behavior in Oracle7 ... include constants, exceptions, cursors, or datatypes Table 18.1 compares the new object features with features of tables and packages Table 18.1: Comparing Oracle8 Objects to Earlier Oracle Features Characteristic Oracle7 Table Oracle7 Package Oracle8 Object Stores data Yes Temporary only; package variables exist for duration of session Object instance data may be persistent (stored in tables) or transient... Although this chapter covers all aspects of using objects in PL/SQL, we don't have space to cover every possible aspect of using objects in the server Some of the things we don't discuss in detail include: triggers on object tables (since objects do not alter what you already know about triggers from Oracle7 ); ways of using PL/SQL objects with the Oracle Call Interface (OCI) for C or C++; and some of the... version You can, however, put PL/SQL to use, along with some of its more interesting features like recursion, global data, and PL/SQL tables, to provide a very elegant solution The package below offers a checks package to provide this conversion capability.[2] [2] This implementation of "number-to-words" was first presented by Mike Burnside of Oracle Australia at the International Oracle User's Week in San... programmer, object types in Oracle, properly implemented, can be the cornerstone of an overall object strategy (And at least they don't use alien punctuation!) 18.1.1 Terminology The first big hurdle to cross is the nomenclature; object technology in general, and Oracle8 in particular, seem to litter us with terms that seem familiar but aren't For example, even prior to Oracle8 , Oracle did have objects . Restrictions on PL/SQL Functions in SQL Oracle PL/SQL Programming, 2nd Edition Next: 17.6 Column/ Function Name Precedence 17.4 Restrictions on PL/SQL Functions. 17 Calling PL/SQL Functions in SQL Next: 17.8 Examples of Embedded PL/SQL 17.7 Realities: Calling PL/SQL Functions in SQL The ability to call PL/SQL functions

Ngày đăng: 15/12/2013, 04:15

TỪ KHÓA LIÊN QUAN