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

Oracle SQL Plus The Definitive Guide- P26 potx

10 282 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 102,92 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

In addition to substitution variables, SQL*Plus supports another type of variable called a bind variable.. Here's a simple example showing how a bind variable can be used: --Bind variab

Trang 1

The SHOW_SECURITY.SQL script

The following script shows you the grants that have been made on any table you own You can also see grants made on tables owned by other users, so long as those grants apply to you The two queries you saw previously have been

unioned together, and the columns have been concatenated together to produce readable output The table name and grantee are shown in the header, which changes each time the grantee changes

DESCRIPTION

This script displays information about security on a table

USAGE

@SHOW_SECURITY [owner.] table_name

SET ECHO OFF

SET VERIFY OFF

SET FEEDBACK OFF

SET PAGESIZE 9999

SET HEADING OFF

Dissect the input argument, and get the owner name and

table name into two separate substitution variables

The owner name defaults to the current user

SET TERMOUT OFF

DEFINE s_owner_name =

DEFINE s_synonym_name =

COLUMN owner_name NOPRINT NEW_VALUE s_owner_name

COLUMN table_name NOPRINT NEW_VALUE s_table_name

SELECT

DECODE(INSTR(&&1, ),

0,USER, /*Default to current user.*/

UPPER(SUBSTR(&&1,1,INSTR(&&1,.)-1))) owner_name,

DECODE (INSTR( &&1,.),

UPPER(&&1), /*Only the table name was passed in.*/

UPPER(SUBSTR(&&1,INSTR(&&1,.)+1))) table_name

FROM dual;

SET TERMOUT ON

COLUMN grantee NOPRINT NEW_VALUE s_grantee

BREAK ON grantee SKIP PAGE

TTITLE LEFT PRIVILEGES GRANTED TO s_grantee -

ON s_owner_name s_table_name

Execute a query to show privileges granted at the table level

SELECT grantee,

¦¦ privilege ¦¦

DECODE(grantable, YES, with grant option, ) privilege

FROM all_tab_privs

WHERE table_schema = &&s_owner_name

AND table_name = &&s_table_name

UNION

SELECT grantee,

Trang 2

¦¦ privilege ¦¦ of column ¦¦ column_name

¦¦ DECODE(grantable, YES, with grant option, ) privilege

FROM all_col_privs

WHERE table_schema = &&s_owner_name

AND table_name = &&s_table_name

ORDER BY grantee, privilege;

Reset everything back to its default

CLEAR COLUMNS

CLEAR BREAK

UNDEFINE s_owner_name

UNDEFINE s_table_name

SET VERIFY ON

SET FEEDBACK ON

SET HEADING ON

SET PAGESIZE 24

Running the SHOW_SECURITY script

The following example shows the results of running SHOW_SECURITY against the EMPLOYEE table, after first granting some access to other users:

SQL> @show_security employee

PRIVILEGES GRANTED TO PUBLIC ON JEFF.EMPLOYEE

SELECT

UPDATE of column EMPLOYEE_TERMINATION_DATE

PRIVILEGES GRANTED TO USER_A ON JEFF.EMPLOYEE

DELETE

INSERT of column EMPLOYEE_BILLING_RATE with grant option

INSERT of column EMPLOYEE_HIRE_DATE with grant option

INSERT of column EMPLOYEE_ID with grant option

INSERT of column EMPLOYEE_NAME with grant option

SELECT

PRIVILEGES GRANTED TO USER_B ON JEFF.EMPLOYEE

UPDATE of column EMPLOYEE_NAME

UPDATE of column EMPLOYEE_TERMINATION_DATE

PRIVILEGES GRANTED TO USER_C ON JEFF.EMPLOYEE

INSERT

INSERT of column EMPLOYEE_ID

SELECT

UPDATE

Finding More Information

It's well worth your time to learn more about Oracle's data dictionary views Anything you want to know about the structure of your database and the objects within it can be found by querying the appropriate view The definitive

reference for these views is the Oracle8 Server Reference manual However, if you don't

Trang 3

have that manual close by, you can get a quick list of useful views by executing the following query:

SELECT *

FROM dictionary

ORDER By table_name;

Use the DESCRIBE command on any views of interest The column names tend to be reasonably self-explanatory

Trang 4

7

Advanced Scripting

In this chapter

Bind Variables

Branching in SQL*Plus

Looping in SQL*Plus

Validating and Parsing User Input

Error Handling

SQL*Plus was not designed to be a tool used for writing complex scripts Its capabilities cannot compare to those of your typical Unix shell, such as the Kom shell or the Bourne shell Nor does it have anywhere near the capabilities of an advanced scripting tool such as Perl Most noticeably, SQL*Plus suffers from the following limitations:

It lacks an IF statement

There are no looping constructs

It has very limited error handling

There is only marginal support for validating user input

Because of these limitations, SQL*Plus is best suited to executing top-down scripts that don't require any branching, looping, or error handling Most of the scripts you have seen so far in this book fall into this category Many are reports that simply set up some column and page formatting, then execute a query If something goes wrong, you either don't see any data in the report or may see some SQL or SQL*Plus error messages

This limited scripting support is fine when it comes to producing a report After all, if a report fails, you can simply fix the problem and return the report But what if you are performing a more complex and critical task? What if you are summarizing some data, posting the summary results to a summary table, and then deleting the underlying detail? In that case, you certainly wouldn't want to delete the data if the summarization failed You would need some sort of error-handling mechanism

Trang 5

If you need to write scripts of any significant complexity, I strongly encourage you

to investigate the use of PL/SQL in your script PL/SQL is a powerful programming language

in its own right, and includes support for error handling, branching, and loopingthe very items

that SQL*Plus lacks Steven Feuerstein's and Bill Pribyl's book, Oracle PL/SQL

Programming, 2nd edition (O'Reilly, 1997), is an excellent resource.

This chapter will show you some specific ways to work around these limitations of SQL*Plus Believe it or not, it is possible, using just SQL*Plus, to implement branching and to validate user input There are even ways to deal with repetitive tasks without resorting to a loop You will learn about bind variables and see how they better enable you to mix PL/SQL code into your SQL*Plus scripts You will also see how bind variables can make the job of developing queries for application programs a little bit easier

Bind Variables

Back in Chapter 4, Writing SQL*Plus Scripts, you learned about substitution variables In addition to substitution

variables, SQL*Plus supports another type of variable called a bind variable Unlike substitution variables, bind

variables are real variables, having both a datatype and a size

Bind variables were created to support the use of PL/SQL in a SQL*Plus script They provide a mechanism for

returning data from a PL/SQL block back to SQLlus, where it can be used in subsequent queries or by other PL/SQL blocks Here's a simple example showing how a bind variable can be used:

Bind variables can be declared in your SQL*Plus script

VARIABLE s_table_name varchar2(30)

Preface a bind variable with a colon to reference it

in a PL/SQL block

BEGIN

:s_table_name := EMPLOYEE;

END;

/

Bind variables can even be referenced by SQL queries

SELECT index_name

FROM user_indexes

WHERE table_name = :s_table_name;

Bind variables persist until you exit SQL*Plus, so

they can be referenced by more than one PL/SQL block

SET SERVEROUTPUT ON

Trang 6

BEGIN

DBMS_OUTPUT PUT_LIKE(: s_table_name) ;

END;

/

The scope of a bind variable is the SQL*Plus session in which it was defined Variables defined within a PL/SQL block,

on the other hand, cease to exist once that block has finished executing Bind variables are defined one level higher (at the SQL*Plus level), so they can be referenced by many PL/SQL blocks and queries

Declaring Bind Variables

The SQLlus VARIABLE command is used to declare bind variables The syntax looks like this:

VAR[IABLE] var_name data_type

where:

VAR[IABLE]

Is the command, which can be abbreviated to VAR

var_name

Is whatever name you want to give the variable A variable name must start with a letter, but after that, the name may contain any combination of letters, digits, underscores, pound signs, and dollar signs 30 characters is the maximum length for a variable name

data_type

Is the datatype of the variable The following datatypes are allowed:

NUMBER

Results in a floating-point number, and is the same as a NUMBER variable in PL/SQL or a NUMBER column in a table Unlike PL/SQL, SQL*Plus does not let you specify a length or a precision, so a declaration like NUMBER (9,2) would not be allowed

CHAR[(length)]

Results in a fixed-length character string Length is optional If it's omitted, you get a one-character string

NCHAR[(length)]

Results in a fixed-length character string in the national character set Length is optional If it's omitted, you get a one-character string

VARCHAR2(length)

Results in a variable-length character string

Trang 7

NVARCHAR2(length)

Results in a variable-length character string using the national language character set

CLOB

Results in a character large object variable

NCLOB

Results in a character large object variable using the national language character set

REFCURSOR

Gives you a cursor variable that you can use to return the results of a SQL query from PL/SQL to SQL*Plus

In addition to declaring variables, you can also use the VARIABLE command to list all the variables you have defined

To do that, simply issue the command VARIABLE, with no arguments, as shown in the following example:

SQL>VARIABLE

variable jenny

datatype NUMBER

variable jeff

datatype CHAR

variable sharon

datatype VARCHAR2(30)

If you are interested in one specific variable, you can specify that variable's name as an argument to the VARIABLE command, for example:

SQL> VARIABLE SHARON

variable sharon

datatype VARCHAR2(30)

There is no way to get rid of a variable once you've defined it

Using Bind Variables and Substitution Variables Together

Bind variables and substitution variables don't mesh together too well in SQL*Plus Each was created for a different purpose, and the two types cannot be used interchangeably For example, bind variables cannot be used with the

ACCEPT command, while substitution variables can Substitution variables can be used with the TTITLE and BTITLE commands that set up page headers and footers, while bind variables cannot Bind variables are true variables, and can

be passed as

Trang 8

ments to PL/SQL functions and procedures, while substitution variables cannot Table 7-1 summarizes the best uses and capabilities of each type of variable.

Table 7-1 Bind Variables versus Substitution Variables

Task Bind Variable Substitution Variable Comments

Display information to the userthe

PROMPT command.

X

Accept input from the userthe ACCEPT

command.

X

Place information from a query into

page headers and footersthe TITTLE

and BTITLE commands.

X

Run a query with user-specified criteria

in the WHERE clause.

X X User input must come through a

substitution variable, but you can store the resulting value in a bind variable.

Pass values to a PL/SQL function or

procedure.

X X Substitution variables may be used to

pass input arguments as literals.

Return information back from a PL/

SQL function or procedure.

X Bind variables must be used for OUT

and IN OUT arguments.

As you can see, each variable type pretty much exists in its own world, completely separate from the other In fact, you cannot even directly assign values from a bind variable to a substitution variable, or vice versa The following lines of script, though appearing

perfectly reasonable on the surface, simply will not work:

DEFINE my_sub_var =

VARIABLE my_bind_var VARCHAR2(30)

EXECUTE :my_bind_var := Donna Gennick

my_sub_var = my_bind_var

This lack of interoperability between variable types can be a real frustration when writing scripts As Table 7-1 shows, there are some tasks for which you can only use a bind variable, and others for which you can only use a substitution variable Yet SQL*Plus does not let you easily move values back and forth between the two types Fortunately, there are some relatively straightforward incantations that let you work around this problem.

From substitution to bind

Putting the value of a substitution variable into a bind variable is actually the easier of the two tasks Remember that as SQL*Plus

executes your script, any

Trang 9

tion variables are simply replaced by their contents as each line of code is executed You can easily take advantage of this in order to place a value into a bind variable Take a look at the following short script:

DEFINE my_sub_var = Raymond

VARIABLE my_bind_var VARCHAR2(30)

EXECUTE :my_bind_var := &my_sub_var;

EXECUTE is a command that executes one line of PL/SQL code When SQL*Plus encounters the EXECUTE

command, it replaces the reference to the substitution variable with the value of that variable The command after

substitution, the one that is actually executed, looks like this:

EXECUTE :my_bind_var := Raymond;

Since the assignment involves a character string, the substitution variable must be contained in quotes; otherwise, you would not have a valid string If you are working with numeric values, you shouldn't quote them The following

example declares a variable of type NUMBER and assigns a value to it:

DEFINE imy_sub_num = 9

VARIABLE my_bind_num NUMBER

EXECUTE :my_bind_num := &&my_sub_num;

So quote your strings, don't quote your numbers, and remember that substitution is occurring

From bind to substitution

Taking a value from a bind variable and placing it into a substitution variable is a more difficult task What you need to

do is take advantage of SQL*Plus's ability to store the results of a SELECT statement into a substitution variable Let's say you have the following in your script:

DEFINE my_sub_var =

VARIABLE my_bind_var VARCHAR2(30)

EXECUTE :my_bind_var := This is a test.;

In order to get the value of the bind variable into the substitution variable, you need to go through the following steps:

1 Think up a column name

2 Execute a COLUMN command for the column name you thought up Use the NEW_VALUE clause and specify the substitution variable as the target

3 Turn off terminal output by executing a SET TERMOUT OFF command This is optional

4 Issue a SELECT statement that selects the bind variable from Oracle's DUAL table Use the column name you

thought up in step 1 as the column alias

5 Turn terminal output back on

Trang 10

The SELECT statement will, of course, only return one value, but that value will be a new value for the column in question The COLUMN command, with its NEW_VALUE clause, causes this value to be stored in the specified

substitution variable It's a roundabout solution to the problem, but when it's all over the substitution variable will

contain the value from the bind variable The important thing is to be sure that the column alias matches the column name used in the COLUMN command Here's a code sample that demonstrates this technique:

Declare one bind variable and one substitution variable

Initialize the bind variable to a value

DEFINE my_sub_var =

VARIABLE my_bind_var VARCHAR2(30)

EXECUTE :my_bind_var := This is a test.;

Store the new value of the my_alias column in my_sub_var

COLUMN my_alias NEW_VALUE my_sub_var

SELECT the value of the bind variable SQL*Plus

will store that value in my_sub_var because of the

previous COLUMN command

SET TERMOUT OFF

SELECT :my_bind_var my_alias

FROM dual;

SET TERMOUT ON

Notice that a column alias is used in the SELECT statement to give the column a name This same name must be used

in the COLUMN command issued prior to the SELECT If these two don't match, then the assignment won't be made, and my_sub_var will still be blank

Strictly speaking, it's not necessary to turn the terminal output off for the SELECT statement The variable assignment will still be made, even with the output on However, if you are writing a script, you probably won't want the results of this SELECT to clutter up the display

Displaying the Contents of a Bind Variable

There are two ways to display the contents of a bind variable to a user You can use the PRINT command, or you can list the variable in a SELECT statement

The PRINT command

The format for the PRINT command looks like this:

PRI[NT] [bind_variable_name]

where:

PRI[NT]

Is the command, which can be abbreviated to PRI

Ngày đăng: 05/07/2014, 04:20

TỪ KHÓA LIÊN QUAN