Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 52 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
52
Dung lượng
176,66 KB
Nội dung
Lexical Units Fundamentals of the PL/SQL Language 2-7 t2 TIMESTAMP WITH TIME ZONE := TIMESTAMP ’1997-01-31 09:26:56.66 +02:00’; Three years and two months (For greater precision, we would use the day-to-second interval) i1 INTERVAL YEAR TO MONTH := INTERVAL ’3-2’ YEAR TO MONTH; Five days, four hours, three minutes, two and 1/100 seconds i2 INTERVAL DAY TO SECOND := INTERVAL ’5 04:03:02.01’ DAY TO SECOND; You can also specify whether a given interval value is YEAR TO MONTH or DAY TO SECOND. For example, current_timestamp - current_timestamp produces a value of type INTERVAL DAY TO SECOND by default. You can specify the type of the interval using the formats: ■ (interval_expression) DAY TO SECOND ■ (interval_expression) YEAR TO MONTH For details on the syntax for the date and time types, see the Oracle Database SQL Reference. For examples of performing date/time arithmetic, see Oracle Database Application Developer's Guide - Fundamentals. Comments The PL/SQL compiler ignores comments, but you should not. Adding comments to your program promotes readability and aids understanding. Generally, you use comments to describe the purpose and use of each code segment. PL/SQL supports two comment styles: single-line and multi-line. Single-Line Comments Single-line comments begin with a double hyphen ( ) anywhere on a line and extend to the end of the line. A few examples follow: DECLARE howmany NUMBER; BEGIN begin processing SELECT count(*) INTO howmany FROM user_objects WHERE object_type = 'TABLE'; Check number of tables howmany := howmany * 2; Compute some other value END; / Notice that comments can appear within a statement at the end of a line. While testing or debugging a program, you might want to disable a line of code. The following example shows how you can "comment-out" the line: DELETE FROM employees WHERE comm_pct IS NULL; Multi-line Comments Multi-line comments begin with a slash-asterisk (/*), end with an asterisk-slash (*/), and can span multiple lines. Some examples follow: DECLARE some_condition BOOLEAN; pi NUMBER := 3.1415926; radius NUMBER := 15; area NUMBER; BEGIN /* Perform some simple tests and assignments */ IF 2 + 2 = 4 THEN some_condition := TRUE; /* We expect this THEN to always be done */ Declarations 2-8 PL/SQL User's Guide and Reference END IF; /* The following line computes the area of a circle using pi, which is the ratio between the circumference and diameter. */ area := pi * radius**2; END; / You can use multi-line comment delimiters to comment-out whole sections of code: /* LOOP FETCH c1 INTO emp_rec; EXIT WHEN c1%NOTFOUND; END LOOP; */ Restrictions on Comments You cannot nest comments. You cannot use single-line comments in a PL/SQL block that will be processed by an Oracle Precompiler program because end-of-line characters are ignored. As a result, single-line comments extend to the end of the block, not just to the end of a line. In this case, use the /* */ notation instead. Declarations Your program stores values in variables and constants. As the program executes, the values of variables can change, but the values of constants cannot. You can declare variables and constants in the declarative part of any PL/SQL block, subprogram, or package. Declarations allocate storage space for a value, specify its datatype, and name the storage location so that you can reference it. A couple of examples follow: DECLARE birthday DATE; emp_count SMALLINT := 0; The first declaration names a variable of type DATE. The second declaration names a variable of type SMALLINT and uses the assignment operator to assign an initial value of zero to the variable. The next examples show that the expression following the assignment operator can be arbitrarily complex and can refer to previously initialized variables: DECLARE pi REAL := 3.14159; radius REAL := 1; area REAL := pi * radius**2; BEGIN NULL; END; / Declarations Fundamentals of the PL/SQL Language 2-9 By default, variables are initialized to NULL, so it is redundant to include ":= NULL" in a variable declaration. To declare a constant, put the keyword CONSTANT before the type specifier: DECLARE credit_limit CONSTANT REAL := 5000.00; max_days_in_year CONSTANT INTEGER := 366; urban_legend CONSTANT BOOLEAN := FALSE; BEGIN NULL; END; / This declaration names a constant of type REAL and assigns an unchangeable value of 5000 to the constant. A constant must be initialized in its declaration. Otherwise, you get a compilation error. Using DEFAULT You can use the keyword DEFAULT instead of the assignment operator to initialize variables. For example, the declaration blood_type CHAR := 'O'; can be rewritten as follows: blood_type CHAR DEFAULT 'O'; Use DEFAULT for variables that have a typical value. Use the assignment operator for variables (such as counters and accumulators) that have no typical value. For example: hours_worked INTEGER DEFAULT 40; employee_count INTEGER := 0; You can also use DEFAULT to initialize subprogram parameters, cursor parameters, and fields in a user-defined record. Using NOT NULL Besides assigning an initial value, declarations can impose the NOT NULL constraint: DECLARE acct_id INTEGER(4) NOT NULL := 9999; You cannot assign nulls to a variable defined as NOT NULL. If you try, PL/SQL raises the predefined exception VALUE_ERROR. The NOT NULL constraint must be followed by an initialization clause. PL/SQL provide subtypes NATURALN and POSITIVEN that are predefined as NOT NULL. You can omit the NOT NULL constraint when declaring variables of these types, and you must include an initialization clause. Using the %TYPE Attribute The %TYPE attribute provides the datatype of a variable or database column. In the following example, %TYPE provides the datatype of a variable: DECLARE credit NUMBER(7,2); debit credit%TYPE; Declarations 2-10 PL/SQL User's Guide and Reference name VARCHAR2(20) := 'JoHn SmItH'; If we increase the length of NAME, the other variables become longer too. upper_name name%TYPE := UPPER(name); lower_name name%TYPE := LOWER(name); init_name name%TYPE := INITCAP(name); BEGIN NULL; END; / Variables declared using %TYPE are treated like those declared using a datatype specifier. For example, given the previous declarations, PL/SQL treats debit like a REAL(7,2) variable. A %TYPE declaration can also include an initialization clause. The %TYPE attribute is particularly useful when declaring variables that refer to database columns. You can reference a table and column, or you can reference an owner, table, and column, as in DECLARE If the length of the column ever changes, this code will use the new length automatically. the_trigger user_triggers.trigger_name%TYPE; BEGIN NULL; END; / When you use table_name.column_name.TYPE to declare a variable, you do not need to know the actual datatype, and attributes such as precision, scale, and length. If the database definition of the column changes, the datatype of the variable changes accordingly at run time. %TYPE variables do not inherit the NOT NULL column constraint. In the next example, even though the database column employee_id is defined as NOT NULL, you can assign a null to the variable my_empno: DECLARE my_empno employees.employee_id%TYPE; BEGIN my_empno := NULL; this works END; / Using the %ROWTYPE Attribute The %ROWTYPE attribute provides a record type that represents a row in a table (or view). The record can store an entire row of data selected from the table, or fetched from a cursor or strongly typed cursor variable: DECLARE %ROWTYPE can include all the columns in a table emp_rec employees%ROWTYPE; or a subset of the columns, based on a cursor. CURSOR c1 IS SELECT department_id, department_name FROM departments; dept_rec c1%ROWTYPE; Could even make a %ROWTYPE with columns from multiple tables. CURSOR c2 IS SELECT employee_id, email, employees.manager_id, location_id Declarations Fundamentals of the PL/SQL Language 2-11 FROM employees, departments WHERE employees.department_id = departments.department_id; join_rec c2%ROWTYPE; BEGIN We know EMP_REC can hold a row from the EMPLOYEES table. SELECT * INTO emp_rec FROM employees WHERE ROWNUM < 2; We can refer to the fields of EMP_REC using column names from the EMPLOYEES table. IF emp_rec.department_id = 20 AND emp_rec.last_name = 'JOHNSON' THEN emp_rec.salary := emp_rec.salary * 1.15; END IF; END; / Columns in a row and corresponding fields in a record have the same names and datatypes. However, fields in a %ROWTYPE record do not inherit the NOT NULL column constraint. Aggregate Assignment Although a %ROWTYPE declaration cannot include an initialization clause, there are ways to assign values to all fields in a record at once. You can assign one record to another if their declarations refer to the same table or cursor. For example, the following assignment is allowed: DECLARE dept_rec1 departments%ROWTYPE; dept_rec2 departments%ROWTYPE; CURSOR c1 IS SELECT department_id, location_id FROM departments; dept_rec3 c1%ROWTYPE; BEGIN dept_rec1 := dept_rec2; allowed dept_rec2 refers to a table, dept_rec3 refers to a cursor dept_rec2 := dept_rec3; not allowed END; / You can assign a list of column values to a record by using the SELECT or FETCH statement, as the following example shows. The column names must appear in the order in which they were defined by the CREATE TABLE or CREATE VIEW statement. DECLARE dept_rec departments%ROWTYPE; BEGIN SELECT * INTO dept_rec FROM departments WHERE department_id = 30 and ROWNUM < 2; END; / However, there is no constructor for a record type, so you cannot assign a list of column values to a record by using an assignment statement. Using Aliases Select-list items fetched from a cursor associated with %ROWTYPE must have simple names or, if they are expressions, must have aliases. The following example uses an alias called complete_name to represent the concatenation of two columns: BEGIN We assign an alias (COMPLETE_NAME) to the expression value, because it has no column name. PL/SQL Naming Conventions 2-12 PL/SQL User's Guide and Reference FOR item IN ( SELECT first_name || ' ' || last_name complete_name FROM employees WHERE ROWNUM < 11 ) LOOP Now we can refer to the field in the record using this alias. dbms_output.put_line('Employee name: ' || item.complete_name); END LOOP; END; / Restrictions on Declarations PL/SQL does not allow forward references. You must declare a variable or constant before referencing it in other statements, including other declarative statements. PL/SQL does allow the forward declaration of subprograms. For more information, see "Declaring Nested PL/SQL Subprograms" on page 8-5. Some languages allow you to declare a list of variables that have the same datatype. PL/SQL does not allow this. You must declare each variable separately: DECLARE Multiple declarations not allowed. i, j, k, l SMALLINT; Instead, declare each separately. i SMALLINT; j SMALLINT; To save space, you can declare more than one on a line. k SMALLINT; l SMALLINT; BEGIN NULL; END; / PL/SQL Naming Conventions The same naming conventions apply to all PL/SQL program items and units including constants, variables, cursors, cursor variables, exceptions, procedures, functions, and packages. Names can be simple, qualified, remote, or both qualified and remote. For example, you might use the procedure name raise_salary in any of the following ways: raise_salary( ); simple emp_actions.raise_salary( ); qualified raise_salary@newyork( ); remote emp_actions.raise_salary@newyork( ); qualified and remote In the first case, you simply use the procedure name. In the second case, you must qualify the name using dot notation because the procedure is stored in a package called emp_actions. In the third case, using the remote access indicator (@), you reference the database link newyork because the procedure is stored in a remote database. In the fourth case, you qualify the procedure name and reference a database link. PL/SQL Naming Conventions Fundamentals of the PL/SQL Language 2-13 Synonyms You can create synonyms to provide location transparency for remote schema objects such as tables, sequences, views, standalone subprograms, packages, and object types. However, you cannot create synonyms for items declared within subprograms or packages. That includes constants, variables, cursors, cursor variables, exceptions, and packaged subprograms. Scoping Within the same scope, all declared identifiers must be unique; even if their datatypes differ, variables and parameters cannot share the same name. In the following example, the second declaration is not allowed: DECLARE valid_id BOOLEAN; valid_id VARCHAR2(5); not allowed, duplicate identifier BEGIN The error occurs when the identifier is referenced, not in the declaration part. valid_id := FALSE; END; / For the scoping rules that apply to identifiers, see "Scope and Visibility of PL/SQL Identifiers" on page 2-14. Case Sensitivity Like all identifiers, the names of constants, variables, and parameters are not case sensitive. For instance, PL/SQL considers the following names to be the same: DECLARE zip_code INTEGER; Zip_Code INTEGER; duplicate identifier, despite Z/z case difference BEGIN zip_code := 90120; causes error because of duplicate identifiers END; / Name Resolution In potentially ambiguous SQL statements, the names of database columns take precedence over the names of local variables and formal parameters. For example, if a variable and a column with the same name are both used in a WHERE clause, SQL considers that both cases refer to the column. To avoid ambiguity, add a prefix to the names of local variables and formal parameters, or use a block label to qualify references. CREATE TABLE employees2 AS SELECT last_name FROM employees; <<MAIN>> DECLARE last_name VARCHAR2(10) := 'King'; my_last_name VARCHAR2(10) := 'King'; BEGIN Deletes everyone, because both LAST_NAMEs refer to the column DELETE FROM employees2 WHERE last_name = last_name; dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.'); ROLLBACK; Scope and Visibility of PL/SQL Identifiers 2-14 PL/SQL User's Guide and Reference OK, column and variable have different names DELETE FROM employees2 WHERE last_name = my_last_name; dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.'); ROLLBACK; OK, block name specifies that 2nd LAST_NAME is a variable DELETE FROM employees2 WHERE last_name = main.last_name; dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows.'); ROLLBACK; END; / DROP TABLE employees2; The next example shows that you can use a subprogram name to qualify references to local variables and formal parameters: DECLARE FUNCTION dept_name (department_id IN NUMBER) RETURN departments.department_name%TYPE IS department_name departments.department_name%TYPE; BEGIN DEPT_NAME.DEPARTMENT_NAME specifies the local variable instead of the table column SELECT department_name INTO dept_name.department_name FROM departments WHERE department_id = dept_name.department_id; RETURN department_name; END; BEGIN FOR item IN (SELECT department_id FROM departments) LOOP dbms_output.put_line('Department: ' || dept_name(item.department_id)); END LOOP; END; / For a full discussion of name resolution, see Appendix D. Scope and Visibility of PL/SQL Identifiers References to an identifier are resolved according to its scope and visibility. The scope of an identifier is that region of a program unit (block, subprogram, or package) from which you can reference the identifier. An identifier is visible only in the regions from which you can reference the identifier using an unqualified name. Figure 2–1 shows the scope and visibility of a variable named x, which is declared in an enclosing block, then redeclared in a sub-block. Identifiers declared in a PL/SQL block are considered local to that block and global to all its sub-blocks. If a global identifier is redeclared in a sub-block, both identifiers remain in scope. Within the sub-block, however, only the local identifier is visible because you must use a qualified name to reference the global identifier. Although you cannot declare an identifier twice in the same block, you can declare the same identifier in two different blocks. The two items represented by the identifier are distinct, and any change in one does not affect the other. However, a block cannot reference identifiers declared in other blocks at the same level because those identifiers are neither local nor global to the block. Scope and Visibility of PL/SQL Identifiers Fundamentals of the PL/SQL Language 2-15 Figure 2–1 Scope and Visibility The example below illustrates the scope rules. Notice that the identifiers declared in one sub-block cannot be referenced in the other sub-block. That is because a block cannot reference identifiers declared in other blocks nested at the same level. DECLARE a CHAR; b REAL; BEGIN identifiers available here: a (CHAR), b DECLARE a INTEGER; c REAL; BEGIN identifiers available here: a (INTEGER), b, c END; DECLARE d REAL; BEGIN identifiers available here: a (CHAR), b, d END; identifiers available here: a (CHAR), b END; / Recall that global identifiers can be redeclared in a sub-block, in which case the local declaration prevails and the sub-block cannot reference the global identifier unless you use a qualified name. The qualifier can be the label of an enclosing block: <<outer>> DECLARE birthdate DATE; BEGIN DECLARE birthdate DATE; Scope Visibility Outer x Inner x DECLARE X REAL; BEGIN DECLARE X REAL; BEGIN END; DECLARE X REAL; BEGIN DECLARE X REAL; BEGIN END; END;END; DECLARE X REAL; BEGIN DECLARE X REAL; BEGIN END; END; DECLARE X REAL; BEGIN DECLARE X REAL; BEGIN END; END; Assigning Values to Variables 2-16 PL/SQL User's Guide and Reference BEGIN IF birthdate = outer.birthdate THEN END; END; / As the next example shows, the qualifier can also be the name of an enclosing subprogram: PROCEDURE check_credit ( ) IS rating NUMBER; FUNCTION valid ( ) RETURN BOOLEAN IS rating NUMBER; BEGIN IF check_credit.rating < 3 THEN END; BEGIN END; / However, within the same scope, a label and a subprogram cannot have the same name. Assigning Values to Variables You can use assignment statements to assign values to variables. For example, the following statement assigns a new value to the variable bonus, overwriting its old value: bonus := salary * 0.15; Unless you expressly initialize a variable, its value is undefined (NULL). Variables and constants are initialized every time a block or subprogram is entered. By default, variables are initialized to NULL: DECLARE counter INTEGER; BEGIN COUNTER is initially NULL, so 'COUNTER + 1' is also null. counter := counter + 1; IF counter IS NULL THEN dbms_output.put_line('Sure enough, COUNTER is NULL not 1.'); END IF; END; / To avoid unexpected results, never reference a variable before you assign it a value. The expression following the assignment operator can be arbitrarily complex, but it must yield a datatype that is the same as or convertible to the datatype of the variable. [...]... the tri-state logic shown in Table 2 2 AND and OR are binary operators; NOT is a unary operator Table 2 2 Logic Truth Table x x AND y x OR y NOT x TRUE TRUE TRUE TRUE FALSE TRUE FALSE FALSE TRUE FALSE TRUE NULL NULL TRUE FALSE FALSE 2- 18 y TRUE FALSE TRUE TRUE PL/SQL User's Guide and Reference PL/SQL Expressions and Comparisons Table 2 2 (Cont.) Logic Truth Table x y x AND y x OR y NOT x FALSE FALSE FALSE... high NULLs and Zero-Length Strings PL/SQL treats any zero-length string like a null This includes values returned by character functions and Boolean expressions For example, the following statements assign nulls to the target variables: DECLARE 2- 26 PL/SQL User's Guide and Reference PL/SQL Expressions and Comparisons null_string VARCHAR2(80) := TO_CHAR(''); address VARCHAR2(80); zip_code VARCHAR2(80) :=... functions SQLCODE and SQLERRM, you can use all the functions in SQL statements Also, except for the object -reference functions DEREF, REF, and VALUE and the miscellaneous functions DECODE, DUMP, and VSIZE, you can use all the functions in procedural statements 2- 28 PL/SQL User's Guide and Reference Summary of PL/SQL Built-In Functions Although the SQL aggregate functions (such as AVG and COUNT) and the SQL... see Appendix B Many types can be converted to character types For example, you can compare, assign, and do other character operations using CLOB variables For details on the possible conversions, see "PL/SQL Character and String Types" on page 3-4 2- 22 PL/SQL User's Guide and Reference PL/SQL Expressions and Comparisons Boolean Date Expressions You can also compare dates Comparisons are chronological;... range 1 327 67 Small VARCHAR2 variables are optimized for performance, and larger ones are optimized for efficient memory use The cutoff point is 20 00 bytes For a VARCHAR2 that is 20 00 bytes or longer, PL/SQL dynamically allocates only enough memory to hold the actual value For a VARCHAR2 variable that is shorter than 20 00 bytes, PL/SQL Datatypes 3-7 Overview of Predefined PL/SQL Datatypes PL/SQL preallocates... unlike VARCHAR2 which can be specified in either characters or bytes my_string NVARCHAR2 (20 0); maximum size is 20 0 characters The maximum width of a NVARCHAR2 database column is 4000 bytes Therefore, you cannot insert NVARCHAR2 values longer than 4000 bytes into a NVARCHAR2 column You can interchange VARCHAR2 and NVARCHAR2 values in statements and expressions It is always safe to turn a VARCHAR2 value into... dbms_output.put_line('There are no more widgets left!'); END IF; END; / Fundamentals of the PL/SQL Language 2- 19 PL/SQL Expressions and Comparisons When the value of on_hand is zero, the left operand yields TRUE, so PL/SQL does not evaluate the right operand If PL/SQL evaluated both operands before applying the OR operator, the right operand would cause a division by zero error Comparison Operators Comparison operators... length in characters, the 3-4 PL/SQL User's Guide and Reference Overview of Predefined PL/SQL Datatypes upper limit is still 327 67 bytes So for double-byte and multibyte character sets, you can only specify 1 /2 or 1/3 as many characters as with a single-byte character set Although PL/SQL character variables can be relatively long, you cannot insert CHAR values longer than 20 00 bytes into a CHAR database... which lets you test different conditions instead of comparing a single expression to various values It has the form: CASE 2- 24 PL/SQL User's Guide and Reference PL/SQL Expressions and Comparisons WHEN WHEN WHEN [ELSE END; search_condition1 THEN result1 search_condition2 THEN result2 search_conditionN THEN resultN resultN+1] A searched CASE expression has no selector Each WHEN clause contains a search... NATURAL and POSITIVE let you restrict an integer variable to non-negative or positive values, respectively NATURALN and POSITIVEN prevent the assigning of nulls to an integer variable SIGNTYPE lets you restrict an integer variable to the values -1, 0, and 1, which is useful in programming tri-state logic 3 -2 PL/SQL User's Guide and Reference Overview of Predefined PL/SQL Datatypes BINARY_FLOAT and BINARY_DOUBLE . NULL Table 2 2 (Cont.) Logic Truth Table x y x AND y x OR y NOT x PL/SQL Expressions and Comparisons 2- 20 PL/SQL User's Guide and Reference When the value of on_hand is zero, the left operand. rows.'); ROLLBACK; Scope and Visibility of PL/SQL Identifiers 2- 14 PL/SQL User's Guide and Reference OK, column and variable have different names DELETE FROM employees2 WHERE last_name = my_last_name; . comparisons, called Boolean expressions, consist of simple or complex PL/SQL Expressions and Comparisons 2- 22 PL/SQL User's Guide and Reference expressions separated by relational operators. Often,