desc_t The PL/SQL table, which contains all of the column information.. The Oracle documentation for DBMS_SQL tells us only that the col_type field of the DBMS_REC record contains the "t
Trang 1desc_t The PL/SQL table, which contains all of the column information This is a table of records of
type DBMS_SQL.DESC_REC (<table_type), which is described later
The following table lists the DBMS_SQL.DESC_REC record type fields
<table_type> Datatype Description
col_type BINARY_INTEGER Type of column described
col_max_len BINARY_INTEGER Maximum length of column value
col_name_len BINARY_INTEGER Length of the column name
col_schema_name VARCHAR2(32) Name of column type schema if an object type
col_schema_name_len BINARY_INTEGER Length of schema name
col_precision BINARY_INTEGER Precision of column if a number
col_scale BINARY_INTEGER Scale of column if a number
col_charsetid BINARY_INTEGER ID of character set
col_charsetform BINARY_INTEGER Character set form
The values for column types are as follows:
Object type (Oracle8) 121
Nested table Type (Oracle8) 122
Variable array (Oracle8) 123
When you call this program, you need to have declared a PL/SQL table based on the DBMS_SQL.DESC_T You can then use PL/SQL table methods to traverse the table and extract the needed information about the
Trang 2cursor The following anonymous block shows the basic steps you will perform when working with this built−in:
DECLARE
cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
cols DBMS_SQL.DESC_T;
ncols PLS_INTEGER;
BEGIN
DBMS_SQL.PARSE
(cur, 'SELECT hiredate, sal FROM emp', DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN (cur, 1, SYSDATE);
DBMS_SQL.DEFINE_COLUMN (cur, 2, 1);
DBMS_SQL.DESCRIBE_COLUMNS (cur, ncols, cols);
FOR colind IN 1 ncols
LOOP
DBMS_OUTPUT.PUT_LINE (cols.col_name);
END LOOP;
DBMS_SQL.CLOSE_CURSOR (cur);
END;
/
If you are going to use this procedure to extract information about a dynamic cursor, you will likely want to build a "wrapper" around it to make it easier for you to get at this data The Section 2.5" section at the end of this chapter offers an example of this wrapper
How'd He Get Those Numbers?
The Oracle documentation for DBMS_SQL tells us only that the col_type field of the DBMS_REC record contains the "type of the column being described" and that the type is an INTEGER Well, what exactly are those integer values? I could have sent email to someone at Oracle Corporation and waited for a response But even then, how would I be sure that those values are correct? And why depend on another person, when I can depend on the software itself?
To figure out the different column type values, I first constructed a table as follows:
CREATE TABLE coltypes
(vc VARCHAR2(10),
nvc NVARCHAR2(10),
ch CHAR(10),
nch NCHAR(10),
d DATE,
n NUMBER,
i INTEGER,
l LONG,
r RAW(100),
rid ROWID,
cl CLOB,
ncl NCLOB,
bl BLOB,
bf BFILE,
msl MLSLABEL
)
/
These columns pretty much cover all of the datatypes through Oracle8 I then built a script which relies on the desccols package to call the DESCRIBE_COLUMNS procedure (see the Section 2.5" section) and display the column information, including the column types
/* Filename on companion disk: desccols.xmn */
DECLARE
cur integer := dbms_sql.open_cursor;
[Appendix A] What's on the Companion Disk?
Trang 3cl CLOB;
bl BLOB;
ncl NCLOB;
bf BFILE;
msl MLSLABEL;
r RAW(100);
rid ROWID;
BEGIN
dbms_sql.PARSE (cur, 'SELECT vc, nvc, ch, nch, d, n, i, l, r, rid, cl, ncl, bl, bf, msl FROM coltypes', DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN (cur, 1, 'a', 10);
DBMS_SQL.DEFINE_COLUMN (cur, 2, 'a', 10);
DBMS_SQL.DEFINE_COLUMN_CHAR (cur, 3, 'a', 10);
DBMS_SQL.DEFINE_COLUMN_CHAR (cur, 4, 'a', 10);
DBMS_SQL.DEFINE_COLUMN (cur, 5, SYSDATE);
DBMS_SQL.DEFINE_COLUMN (cur, 6, 1);
DBMS_SQL.DEFINE_COLUMN (cur, 7, 1);
DBMS_SQL.DEFINE_COLUMN_LONG (cur, 8);
DBMS_SQL.DEFINE_COLUMN_RAW (cur, 9, r, 10);
DBMS_SQL.DEFINE_COLUMN_ROWID (cur, 10, rid);
DBMS_SQL.DEFINE_COLUMN (cur, 11, cl);
DBMS_SQL.DEFINE_COLUMN (cur, 12, ncl);
DBMS_SQL.DEFINE_COLUMN (cur, 13, bl);
DBMS_SQL.DEFINE_COLUMN (cur, 14, bf);
DBMS_SQL.DEFINE_COLUMN (cur, 15, msl);
dyncur.desccols (cur);
dyncur.show;
DBMS_SQL.CLOSE_CURSOR (cur);
END;
/
and I got this output:
Column 1
VC
1
Column 2
NVC
1
Column 3
CH
96
Column 4
NCH
96
Column 5
D
12
Column 6
N
2
Column 7
I
2
Column 8
L
8
Column 9
R
23
Column 10
RID
11
Column 11
CL
112
Column 12
Trang 4112
Column 13
BL
113
Column 14
BF
114
Column 15
MSL
106
I could then document those values with confidence in this book I wanted to show you this so that you
understand that even when a person knows an awful lot about PL/SQL, he doesn't necessarily know
everything In fact, knowing everything is completely impossible and anyone claiming to "know it all" should not be trusted Recognize your areas of ignorance and then search out the answers, preferably by going to the source −− the source code, that is
2.2 Getting Started with
DBMS_SQL
2.4 Tips on Using Dynamic
SQL
Copyright (c) 2000 O'Reilly & Associates All rights reserved.
[Appendix A] What's on the Companion Disk?
Trang 5and PL/SQL
2.4 Tips on Using Dynamic SQL
This section offers advice about how best to take advantage of dynamic SQL and the DBMS_SQL package Following this section is a series of detailed examples of putting DBMS_SQL to use
2.4.1 Some Restrictions
You can do a lot of awfully interesting stuff with DBMS_SQL, but some things are offưlimits:
•
You cannot manipulate cursor variables from within dynamic SQL Cursor variables are a relatively
new, advanced, and littleưused feature of PL/SQL (see Chapter 6 of Oracle PL/SQL Programming
for more information) But if you want to use them, you'll have to do it in static PL/SQL code
•
Unless otherwise noted, DBMS_SQL does not support many of the new data structures in Oracle8 For example, you cannot bind an object or a nested table or a variable array
2.4.2 Privileges and Execution Authority with DBMS_SQL
There are two basic rules to remember when working with DBMS_SQL:
•
Stored programs execute under the privileges of the owner of that program So if you parse and execute dynamic SQL from within a program, references to database objects in that SQL statement are resolved according to the schema of the program, not the schema of the person running the
program
•
Roles are disabled when compiling and executing PL/SQL code Privileges must be granted directly
in order to be used with PL/SQL code So when you execute dynamic SQL from within a PL/SQL program, you must have directly granted privileges to any database objects referenced in the
dynamically constructed string
The following anecdotes demonstrate the kinds of problems you can face with dynamic SQL
2.4.2.1 The tale of Jan
Jan is a sharp DBA She keeps up on the latest in Oracle technology, both within her discipline and in the wider array of Oracle software When Oracle Server Release 7.1 hit the street, she checked for new features and came across the builtưin DBMS_SQL package DBMS_SQL, she discovered, allows you to execute dynamic SQL and PL/SQL from within PL/SQL programs
Jan immediately saw the possibilities and built herself a suite of procedures to perform DBA tasks, all inside