2.2. Performing Essential PL/SQL TasksLet's turn to the highlights of creating 2.2.1. Creating a Stored ProgramTo build a new stored PL/SQL program, you use one of SQL's CREATE statements. For example, if you want to create a stored function that counts words in a string, you can do so using a CREATE FUNCTION statement
As with the simple BEGIN-END blocks shown earlier, running this statement from SQL*Plus requires a trailing slash on a line by itself. Assuming that the DBA has granted you Oracle's CREATE PROCEDURE privilege (which also gives you the privilege of creating functions), this statement causes Oracle to compile and store this stored function in your schema; if your code compiles, you'll probably see a success message such as:
If a table or stored program named wordcount already exists in your Oracle schema, CREATE FUNCTION will fail with the error message ORA-00955: name is already used by an existing object. That is one reason that Oracle provides the OR REPLACE option, which you will want to use probably 99% of the time.
The OR REPLACE option avoids the side effects of dropping and recreating the program; in other words, it preserves any object privileges you have granted to other users or roles. Fortunately, it replaces only objects of the same type, and it won't automatically drop a table named wordcount just because you decided to create a function by that name. As with anonymous blocks used more than once, programmers generally store these statements in files in the operating system. I could create a file wordcount.fun for this function and use the SQL*Plus @ command to run it:
As mentioned earlier, SQL*Plus does not, by default, echo the contents of scripts. You can SET ECHO ON to see the source code scroll past the screen, including the line numbers that Oracle assigns; this setting can be helpful when troubleshooting. Let's introduce an error into the program by commenting out a variable declaration.
This message tells us that the function was created, but that there were compilation errors that render it inoperable. We've succeeded in storing the source code in the database; now we need to tease the details of the error out of the database. The quickest way to see the full text of the error message is to use SQL*Plus' SHOW ERRORS command, abbreviated as SHOW ERR:
The compiler has detected both occurrences of the variable, reporting the exact line and column numbers. To see more detail about any server-based error, you can look it up by its identifierPLS-00201 in this casein Oracle's Database Error Messages document. Behind the scenes, SHOW ERRORS is really just querying Oracle's USER_ERRORS view
It's common practice to append a SHOW ERRORS command after every scripted CREATE statement that builds a stored PL/SQL program. So, a "good practices" template for building stored programs in SQL*Plus might begin with this form:
(I don't usually include SET ECHO ON in scripts, but rather type it at the command line when needed.) When your program contains an error that the compiler can detect, CREATE will still cause Oracle to store the program in the database, though in an invalid state. If, however, you mistype part of the CREATE syntax, Oracle won't be able to figure out what you are trying to do and won't store the code in the database. 2.2.2. Executing a Stored ProgramWe've already looked at two different ways to invoke a stored program: wrap it in a simple PL/SQL block or use the SQL*Plus EXECUTE command. You can also use stored programs inside other stored programs. For example, you can invoke a function such as wordcount in any location where you could use an integer expression. Here is a short illustration of how I might test the wordcount function with a strange input (CHR(9) is an ASCII "tab" character):
I have embedded wordcount as part of an expression and supplied it as an argument to DBMS_OUTPUT.PUT_LINE. Here, PL/SQL automatically casts the integer to a string so it can concatenate it with two other literal expressions; the result is:
You can also invoke many PL/SQL functions inside SQL statements. Here are several examples of how you can use the wordcount function:
2.2.3. Showing Stored ProgramsSooner or later you will want to get a list of the stored programs you own, and you may also need to view the most recent version of program source that Oracle has saved in its data dictionary. This is one task that you will find far easier if you use some kind of GUI-based navigation assistant (Chapter 1 mentions a few such tools), but if you lack such a tool, it's not too hard to write a few SQL statements that will pull the desired information out of the data dictionary. For example, to see a complete list of your programs (and tables, indexes, etc.), query the USER_OBJECTS view, as in:
This view shows name, type, creation time, latest compile times, status (valid or invalid), and other useful information. If all you need is the summary of a PL/SQL program's callable interface in SQL*Plus, the easiest command to use is DESCRIBE:
DESCRIBE also works on tables, views, object types, procedures, and packages. To see the complete source code of your stored programs, query USER_SOURCE or TRIGGER_SOURCE. (Querying from these data dictionary views is discussed in further detail in Chapter 20.) 2.2.4. Managing Grants and Synonyms for Stored ProgramsWhen you first create a PL/SQL program, normally no one but you or the DBA can execute it. To give another user the authority to execute your program, issue a GRANT statement
To remove the privilege, use REVOKE:
You could also grant the EXECUTE privilege to a role:
Or, if appropriate, you could allow any Oracle user on the current database to run the program:
If you grant a privilege to an individual like Scott, and to a role of which the user is a member, and also grant it to PUBLIC, Oracle remembers all three grants until they are revoked. Any one of the grants is sufficient to permit the individual to run the program, so if you ever decide you don't want Scott to run it, you must revoke the privilege from Scott, and revoke it from PUBLIC, and finally revoke it from the all_mis role (or revoke that role from Scott). To view a list of privileges you have granted to other users and roles, you can query the USER_TAB_PRIVS_MADE data dictionary view. Somewhat counterintuitively, PL/SQL program names appear in the table_name column:
When Scott does have the EXECUTE privilege on wordcount, he will probably want to create a synonym for the program to avoid having to prefix it with the name of the schema that owns it:
Now he can execute the program in his programs by referring only to the synonym:
This is a good thing, because if the owner of the function changes, only the synonym (and not any stored program) needs modification. It's possible to create a synonym for a procedure, function, package, orin the most recent Oracle versionsuser-defined type. Synonyms for procedures, functions, or packages can hide not only the schema but also the actual database; you can create a synonym for remote programs as easily as local programs. However, synonyms can only hide schema and database identifiers; you cannot use a synonym in place of a packaged subprogram. Removing a synonym is easy:
2.2.5. Dropping a Stored ProgramIf you really, truly don't need a particular stored program any more, you can drop it using SQL's DROP statement
You can drop a package, which can be composed of up two elements (a specification and body), in its entirety:
Or you can drop only the body without invalidating the corresponding specification:
Any time you drop a program that other programs call, the callers will be marked invalid. 2.2.6. Hiding the Source Code of a Stored ProgramWhen you create a PL/SQL program as described above, the source code will be available in clear text in the data dictionary, and any DBA can view or even alter it. To protect trade secrets or to prevent tampering with your code, you might want some way to obfuscate your PL/SQL source code before delivering it. Oracle provides a command-line utility called wrap
If you need true encryptionfor example, to deliver information such as a password that really needs to be secureyou should not rely on this facility.[*]
To learn more about the wrap utility, see Chapter 20. |
Friday, October 23, 2009
Section 2.2. Performing Essential PL/SQL Tasks
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment