Every column in a table has a name and a data type. The data type tells Oracle how much physical storage to set aside for the column and the form in which the data is stored. This section includes information about Oracle data types, nulls, default values, and data conversions.
Here are the data types that the Oracle engine supports.
| CHAR (n) | NVARCHAR(n) |
| CLOB (character large object) | VARCHAR2(n) |
| NCHAR(n) |
| BINARY_DOUBLE | NUMBER(p) |
| BINARY_FLOAT | NUMBER(p,s) |
| NUMBER |
| DATE, TIMESTAMP | INTERVAL YEAR TO MONTH |
| TIMESTAMP WITH TIME ZONE | INTERVAL DAY TO SECOND |
| TIMESTAMP WITH LOCAL TIME ZONE |
| RAW(n) | BLOB |
SAS/ACCESS Interface to Oracle does not support the Oracle MLSLABEL data type.
For compatibility with other DBMSs, Oracle supports the syntax for a wide variety of numeric data types, including DECIMAL, INTEGER, REAL, DOUBLE-PRECISION, and SMALLINT. All forms of numeric data types are actually stored in the same internal Oracle NUMBER format. The additional numeric data types are variations of precision and scale. A null scale implies a floating-point number, and a non-null scale implies a fixed-point number.
For detailed information about Oracle data types, see your Oracle documentation.
%let PTCONN= %str(user=myusr1 pw=mypwd1 path=mysrv1);
%let MYCONN= %str(user=myusr1 pw=mypwd1 path=mysrv1);
options sastrace=",,," sastraceloc=saslog nostsuffix;
proc sql;
connect to oracle ( &PTCONN);
/* Execute ( drop table EMP_ATTENDANCE) by oracle;*/
execute ( create table EMP_ATTENDANCE ( EMP_NAME VARCHAR2(10),
arrival_timestamp TIMESTAMP, departure_timestamp TIMESTAMP ) ) by oracle;
execute ( insert into EMP_ATTENDANCE values
('John Doe', systimestamp, systimestamp+.2) ) by oracle;
execute ( insert into EMP_ATTENDANCE values
('Sue Day', TIMESTAMP'1980-1-12 10:13:23.33',
TIMESTAMP'1980-1-12 17:13:23.33' )) by oracle;
quit;
libname ora oracle &MYCONN;
proc contents data=ora.EMP_ATTENDANCE; run;
proc sql;
/* Read TIMESTAMP data type */
select * from ora.EMP_ATTENDANCE;
quit;
/* Append to TIMESTAMP data type */
data work.new;
EMP_NAME='New Bee1';
ARRIVAL_TIMESTAMP='30sep1998:14:00:35.00'dt;
DEPARTURE_TIMESTAMP='30sep1998:17:00:14.44'dt; output;
EMP_NAME='New Bee2';
ARRIVAL_TIMESTAMP='30sep1998:11:00:25.11'dt;
DEPARTURE_TIMESTAMP='30sep1998:14:00:35.27'dt; output;
EMP_NAME='New Bee3';
ARRIVAL_TIMESTAMP='30sep1998:08:00:35.33'dt;
DEPARTURE_TIMESTAMP='30sep1998:17:00:35.10'dt; output;
format ARRIVAL_TIMESTAMP datetime23.2;
format DEPARTURE_TIMESTAMP datetime23.2;
run;
title2 'After append';
proc append data=work.new base=ora.EMP_ATTENDANCE ; run;
proc print data=ora.EMP_ATTENDANCE ; run;
/* Uupdate TIMESTAMP data type */
proc sql;
update ora.EMP_ATTENDANCE set ARRIVAL_TIMESTAMP=.
where EMP_NAME like '%Bee2%' ;
select * from ora.EMP_ATTENDANCE ;
delete from ora.EMP_ATTENDANCE where EMP_NAME like '%Bee2%' ;
select * from ora.EMP_ATTENDANCE ;
/* OUTPUT: Creating a brand new table using Data Step*/
data work.sasdsfsec; c_ts='30sep1998:14:00:35.16'dt; k=1; output;
c_ts='.'dt; k=2; output;
format c_ts datetime23.2; run;
/* picks default TIMESTAMP type */
options sastrace=",,,d" sastraceloc=saslog nostsuffix;
data ora.tab_tsfsec; set work.sasdsfsec; run;
options sastrace=",,," sastraceloc=saslog nostsuffix;
proc datasets library=ora;
delete tab_tsfsec;run;
/* Override the default data type */
options sastrace=",,,d" sastraceloc=saslog nostsuffix;
data ora.tab_tsfsec (dbtype=(c_ts='timestamp(3)'));
c_ts='30sep1998:14:00:35'dt;
format c_ts datetime23.; run;
options sastrace=",,," sastraceloc=saslog nostsuffix;
proc datasets library=ora;
delete tab_tsfsec;run;
proc print data=ora.tab_tsfsec; run;
/* Output: Create a new table with bulkload=yes */
title2 'Test OUTPUT with bulkloader';
proc datasets library=ora;
delete tab_tsfsec;run;
/* Select default TIMESTAMP type */
data ora.tab_tsfsec (bulkload=yes); set work.sasdsfsec; run;
proc print data=ora.tab_tsfsec;run;
proc sql;
connect to oracle ( &PTCONN);
execute ( drop table PRODUCT_INFO) by oracle;
execute (
create table PRODUCT_INFO ( PRODUCT VARCHAR2(20),
LIST_PRICE number(8,2),
WARRANTY_PERIOD INTERVAL YEAR(2) TO MONTH ))by oracle;
execute (
insert into PRODUCT_INFO values ('Dish Washer', 4000, '02-00')
)by Oracle;
execute (
insert into PRODUCT_INFO values ('TV', 6000, '03-06'))by Oracle;
quit;
proc contents data=ora.PRODUCT_INFO;run;
/* Show WARRANTY_PERIOD as number of months */
proc print data=ora.PRODUCT_INFO; run;
/* Show WARRANTY_PERIOD in a format as in Oracle*/
proc print
data=ora.PRODUCT_INFO(dbsastype=(WARRANTY_PERIOD='CHAR(6)')); run;
/* Add a new product */
data new_prods;
PRODUCT='Dryer'; LIST_PRICE=2000;WARRANTY_PERIOD=12;
run;
proc sql;
insert into ora.PRODUCT_INFO select * from new_prods;
select * from ora.PRODUCT_INFO;
select * from ora.PRODUCT_INFO where WARRANTY_PERIOD > 24;
quit;
proc sql;
connect to oracle ( &PTCONN);
execute ( drop table PERF_TESTS) by oracle;
execute (
create table PERF_TESTS ( TEST_NUMBER number(4) primary key,
TIME_TAKEN INTERVAL DAY TO SECOND ))by oracle;
execute (
insert into PERF_TESTS
values (1, '0 00:01:05.000200000'))by Oracle;
execute (
insert into PERF_TESTS values (2, '0 00:01:03.400000000'))by Oracle;
quit;
proc contents data=ora.PERF_TESTS; run;
/* Show TIME_TAKEN as number of seconds */
proc print data=ora.PERF_TESTS; run;
/* Show TIME_TAKEN in a format just like in Oracle*/
proc print
data=ora.PERF_TESTS(dbsastype=(TIME_TAKEN='CHAR(25)')); run;
/* Add a new test*/
data new_tests;
TEST_NUMBER=3; TIME_TAKEN=50;
run;
proc sql;
insert into ora.PERF_TESTS select * from new_tests;
select * from ora.PERF_TESTS;
select * from ora.PERF_TESTS where TIME_TAKEN < 60;
quit;
Oracle has a special value called NULL. An Oracle NULL value means an absence of information and is analogous to a SAS missing value. When SAS/ACCESS reads an Oracle NULL value, it interprets it as a SAS missing value.
By default, Oracle columns accept NULL values. However, you can specify columns so that they cannot contain NULL data. NOT NULL tells Oracle not to add a row to the table unless the row has a value for that column. When creating an Oracle table with SAS/ACCESS, you can use the DBNULL= data set option to indicate whether NULL is a valid value for specified columns.
To control how SAS missing character values are handled, use the NULLCHAR= and NULLCHARVAL= data set options.
For more information about how SAS handles NULL values, see Potential Result Set Differences When Processing Null Data.
The table below shows the default data types for SAS character variables based on the length of the variable and the Oracle version.
|
Oracle Server |
Character Variable Length |
Data Type |
|---|---|---|
|
Prior to 12c |
less than or equal to 4000 |
VARCHAR2 |
|
greater than 4000 |
CLOB |
|
|
12c and later |
less than or equal to 32767 |
VARCHAR2 |
|
greater than 32767 |
CLOB |
The table below shows the default data types for SAS character variables when the NOTRANSCODE attribute is specified.
|
Oracle Server |
Character Variable Length |
Data Type |
|---|---|---|
|
Prior to 12c |
less than or equal to 2000 |
RAW |
|
greater than 2000 |
BLOB |
|
|
12c and later |
less than or equal to 32767 |
RAW |
|
greater than 32767 |
BLOB |
This table shows the default formats that SAS/ACCESS Interface to Oracle assigns to SAS variables when using the LIBNAME statement to read from an Oracle table. These default formats are based on Oracle column attributes.
|
Oracle Data Type |
Default SAS Format |
|
|---|---|---|
|
CHAR(n) 1 |
$w. |
|
|
NCHAR(n) 1 |
$w. |
|
|
NVARCHAR(n) 1 |
$w. |
|
|
VARCHAR2(n) |
$w. |
|
|
LONG |
$w. (where w is the minimum of 32767 and the value of the DBMAX_TEXT= option) |
|
|
CLOB |
$w.1 (where w is the minimum of 32767 and the value of the DBMAX_TEXT= option) |
|
|
RAW(n) |
$HEXw.1 (where w is 2*n) |
|
|
LONG RAW |
$HEXw. (where w/2 is the minimum of 32767 and the value of the DBMAX_TEXT= option) |
|
|
BLOB RAW |
$HEXw. (where w/2 is the minimum of 32767 and the value of the DBMAX_TEXT= option) |
|
|
BINARY_DOUBLE |
none |
|
|
BINARY_FLOAT |
none |
|
|
NUMBER |
none |
|
|
NUMBER(p) |
w. |
|
|
NUMBER(p,s) |
w.d |
|
|
DATE |
DATETIME20. |
|
|
TIMESTAMP |
DATETIMEw.d (where d is derived from the fractional-second precision) |
|
|
TIMESTAMP WITH LOCAL TIMEZONE |
DATETIMEw.d (where d is derived from the fractional-second precision) |
|
|
TIMESTAMP WITH TIMEZONE |
$w. |
|
|
INTERVAL YEAR TO MONTH |
w. (where w is derived from the year precision) |
|
|
INTERVAL DAY TO SECOND |
w.d (where w is derived from the fractional-second precision) |
|
| 1 The value of the DBMAX_TEXT= LIBNAME Statement Option option can override these values. | ||
SAS/ACCESS does not support Oracle data types that do not appear in this table.
If Oracle data falls outside valid SAS data ranges, the values are usually counted as missing.
SAS automatically converts Oracle NUMBER types to SAS number formats by using an algorithm that determines the correct scale and precision. When the scale and precision cannot be determined, SAS/ACCESS allows the procedure or application to determine the format. You can also convert numeric data to character data by using the SQL pass-through facility with the Oracle TO_CHAR function. See your Oracle documentation for more details.
The table below shows the default Oracle data types that SAS/ACCESS assigns to SAS variable formats during output operations when you use the LIBNAME statement.
|
SAS Variable Format |
Oracle Data Type |
|
|---|---|---|
|
$w. |
VARCHAR2(w) |
|
|
$w. (where w > 4000) |
CLOB |
|
|
w.d |
NUMBER(p,s) |
|
|
any date, time, or datetime format without fractional parts of a second |
DATE |
|
|
any date, time, or datetime format without fractional parts of a second |
TIMESTAMP |
|
To override these data types, use the DBTYPE= data set option during output processing.
This table shows the default SAS variable formats that SAS/ACCESS assigns to Oracle data types when you use the ACCESS procedure.
|
Oracle Data Type |
Default SAS Format |
|
|---|---|---|
|
CHAR(n) |
$n. (n <= 200) $200. (n > 200) |
|
|
VARCHAR2(n) |
$n. (n <= 200) $200. (n > 200) |
|
|
FLOAT |
BEST22. |
|
|
NUMBER |
BEST22. |
|
|
NUMBER(p) |
w. |
|
|
NUMBER(p, s) |
w.d |
|
|
DATE |
DATETIME16. |
|
|
CLOB |
$200. |
|
|
RAW(n) |
$n. (n < 200) $200. (n > 200) |
|
|
BLOB RAW |
$200. |
|
Oracle data types that are omitted from this table are not supported by SAS/ACCESS. If Oracle data falls outside valid SAS data ranges, the values are usually counted as missing.
This table shows the correlation between the Oracle NUMBER data types and the default SAS formats that are created from that data type.
|
Oracle NUMBER Data Type |
Rules |
Default SAS Format |
|
|---|---|---|---|
|
NUMBER(p) |
0 < p <= 32 |
(p + 1).0 |
|
|
NUMBER(p,s) |
p > 0, s < 0, |s| < p |
(p + |s| + 1).0 |
|
|
NUMBER(p,s) |
p > 0, s < 0, |s| >= p |
(p + |s| + 1).0 |
|
|
NUMBER(p,s) |
p > 0, s > 0, s < p |
(p + 2).s |
|
|
NUMBER(p,s) |
p > 0, s > 0, s >= p |
(s + 3).s |
|
|
NUMBER(p) |
p > 32 |
BEST22. SAS selects format |
|
|
NUMBER |
p, s unspecified |
BEST22. SAS selects format |
|
The general form of an Oracle number is NUMBER(p,s) where p is the precision and s is the scale of the number. Oracle specifies precision as the total number of digits, with a valid range of –84 to 127. However, a negative scale means that the number is rounded to the specified number of places to the left of the decimal. For example, if the number 1,234.56 is specified as data type NUMBER(8,–2), it is rounded to the nearest hundred and stored as 1,200.
This table shows the default Oracle data types that SAS/ACCESS assigns to SAS variable formats when you use the DBLOAD procedure.
|
SAS Variable Format |
Oracle Data Type |
|
|---|---|---|
|
$w. |
CHAR(n) |
|
|
w. |
NUMBER(p) |
|
|
w.d |
NUMBER(p,s) |
|
|
all other numerics 1 |
NUMBER |
|
|
datetimew.d |
DATE |
|
|
datew. |
DATE |
|
|
time. 2 |
NUMBER |
|
| 1 Includes all SAS numeric formats, such as BINARY8 and E10.0. | ||
| 2 Includes all SAS time formats, such as TODw,d and HHMMw,d. | ||