Oracle Tips of the Week_part3

 

Akadia Information Technology


CREATE TABLE AS and LONG RAW
Sizing of Locally Managed Tablespaces
Oracle8i: How to migrate LONG RAW to BLOB
Net8 access trough a firewall with port forwarding using SSH
Automatically Calculating Percentages in Queries
Show Table and System Privileges
How to switch Oracle in Single User Mode
How to store data DES encrypted in Oracle
Dynamic SQL queries that return multirow result sets
Formatted SELECT * FROM 'table' Statement Results
Switch to another Oracle User and back
Access Internet Web pages from SQL or PL/SQL
What is a JDBC KPRB driver and what is it used for
How does one enable dead connection detection
How to connect to a system regardless of machine failure
The mystery of Stored Outlines
Top-N  SQL queries with Inline Views
iFS (Internet Filesystem) Test Installation
The Power of  CASE Expressions in SQL Queries
Online Rebuild of Indexes
Speed up Queries using Function based Indexes
File I/O with Oracle PL/SQL
Using Index Only Tables (IOTs)
Read a file word by word using DBMS_LOB
Mutating Table Problems with DELETE CASCADE
Oracle Servlet Engine OSE (New Feature in Oracle 8.1.7)
How to query a "n X m" relation
Logging using autonomous transactions
Creating updatable views using INSTEAD OF triggers
The Power of Inline Views
Using SQL Loader with an UTF8 Characterset Database
Counting Backwards to Reset a Sequence Value
Logon DB Trigger to Setup the User Environment
Identify the Datafile Size Limit
Oracle8i Profiler for PL/SQL
Manual Migration of Oracle 8.1.x to 8.1.7 (x < 7)
Enabling and Disabling Automatic Extension for a Datafile
Using Oracle's Parallel Execution Features
Net8 Connect-Time Failover
Net8 Transparent Application Failover
The Power of EXECUTE IMMEDIATE and CASE WHEN
Tracking the progress of a long running statement
Slow count(*) and the Highwater Mark
SQLNET Trace Route from Client to Server
Identifying Databases ( SERVICE_NAMES = DB_NAME + DB_DOMAIN )
Managing Files from PL/SQL with DBMS_BACKUP_RESTORE
Checkpoint Tuning and Troubleshooting
Dynamically changing the WHERE clause, without actually changing it ....
Migration to 8i / 9i: Set "_SYSTEM_TRIG_ENABLED" to FALSE
Manually Removing all Oracle Components from NT / 2000
Restrict the Number of Records
Interacting with Oracle via the UNIX Korn shell
How to escape special characters in Oracle ?
How to return an exit code from SQL*Plus to the Unix Shell ?
Help ! SQL*Plus hangs after installing 'login.sql'
How to restrict your users to only one Oracle session

Use of the NVL2 Function
Oracle 8i and 9i Online Documentation
Logging of DML commands

Truncating a Table from a Remote Database
LONG to BLOB Migration
How to create a LOB Table ?


 CREATE TABLE AS and LONG RAW 

Long Raw data types cannot be included in the CREATE TABLE AS syntax. This is documented in the Oracle 7.3 or 8.0 Server SQL Reference Guide 'AS subquery' clause explanation of the CREATE TABLE syntax. The INSERT INTO statement results in the same error (see example). Use export/import to workaround this limitation of long raw usage.

Solution Description

Use the following workaround to create a table using the "CREATE TABLE AS" syntax:

SQL> create table test1 (
       col1 int primary key,
       col2 long raw);

Table created.

SQL> create table test2 as select col1 from test1;

Table created.

SQL> alter table test2 add (col2 long raw);

Table altered.

You may now export from one table (test1) and import into the other table (test2).

  • Export table test1

  • Rename table test1 to test3

  • Rename table test2 to test1

  • Import table test3 into the new test1

  • Rename table test1 back to test2

  • Rename table test3 back to test1

 

 Sizing of Locally Managed Tablespaces 

More and more we are using locally managed tablespaces. They offer a large amount of benefits, so why should we not use this new feature?

Some thoughts are needed when you decided to use Uniform Extent Allocation. With the uniform method, you specify an extent size when you create the tablespace, and all extents for all objects created within that tablespace will be that size.

The uniform method also provides an enforcement mechanism, because you can’t override the uniform extent size of locally managed tablespaces when you create a schema object such as a table or an index.

Calculate the Size of Tablespaces

The goal is to allocate as much disk space as really needed and as really used. With the uniform extent allocation you can calculate or even estimate the number of extents you want to allocate. Gaps or unused disk space within the tablespace should be avoided.

Lets assume that we create a tablespace with the uniform extent size of 1 MByte and 10 extents. Remember that locally managed tablespaces will use another 64 KBytes or the Header Bitmap:

10 * 1 * 1024K + 64K = 10304K

Note that all calculations are made in KBytes and that your chosen extent size is the multiple of your defined block size. The following statement creates this locally managed tablespace with a uniform extent size of 1 MByte:

CREATE TABLESPACE uni_test
  DATAFILE ‘C:\Oradata\ASU1\tab\uni_test.dbf’
  SIZE 10304K
  EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1024K;

Check the Size and Number of Extents

Now every object created within the newly created tablespace gets its uniform extent size of 1 MByte:

CREATE TABLE tab_1 (
  num NUMBER
  ) TABLESPACE uni_test;

CREATE TABLE tab_2 (
  num NUMBER,
  text VARCHAR2(255)
  ) TABLESPACE uni_test
  STORAGE
      (INITIAL       100K
       NEXT          100K
       MINEXTENTS    1
       MAXEXTENTS    UNLIMITED
       PCTINCREASE   0);

CREATE TABLE tab_3 (
  num NUMBER,
  text VARCHAR2(255),
  create_date DATE
  ) TABLESPACE uni_test
  STORAGE
      (MINEXTENTS    2
       MAXEXTENTS    UNLIMITED
       PCTINCREASE   0);

If you are including a STORAGE clause when you create tables or indexes, Oracle will allocate as much extents as you indicate to use. Table TAB_1 will be allocated with one extent, table TAB_2 too because you need at least 100 KBytes. Table TAB_3 will be created with two extents. This could also be done by defining an INITIAL value of 2 MBytes.

The allocated blocks and extents can be verified using the view DBA_SEGMENTS:

SELECT segment_name, segment_type, blocks, extents
  FROM dba_segments
 WHERE owner = 'TEST'
 ORDER BY EXTENTS
/

SEGMENT_NAME         SEGMENT_TYPE           BLOCKS    EXTENTS
-------------------- ------------------ ---------- ----------
TAB_1                TABLE                     256          1
TAB_2                TABLE                     256          1
TAB_3                TABLE                     512          2

The free space in the tablespace UNI_TEST can be verified using the view DBA_FREE_SPACE:

SELECT tablespace_name, bytes, blocks
  FROM dba_free_space
 WHERE tablespace_name = 'UNI_TEST'
/

TABLESPACE_NAME                     BYTES     BLOCKS
------------------------------ ---------- ----------
UNI_TEST                          6291456       1536

That means in the tablespace UNI_TEST are still 1536 blocks available. How many extents are these blocks? This can be calculated by multiplying the number of available blocks by the block size and divided by the extent size:

1536 * 4K / 1024K = 6 extents

That fits with our calculations and verifications: 4 extents are already used and another 6 
extents could be used to fill up the whole tablespace.

Check the File Size

If you check the physical file size used for the tablespace UNI_TEST you will be surprised: Instead of the calculated 10304 KBytes (10'551'296 Bytes) you will find the disk file’s size of 10'555'392 Bytes. Oracle allocates another block which can not be used for object allocation. Some of the Oracle tools such as the Tablespace Manger shows the total number of blocks according to the disk file size. In our example this are 2577 blocks, but usable are only 2576 blocks minus 64 KBytes (for header bitmap).

Summary

Keep the following rules in mind during the sizing of tablespaces:

  1. Each extent size is the multiple of your defined block size.

  2. The usable tablespace size is the multiple of your estimated number of extents.

  3. The defined tablespace size used during CREATE TABLESPACE statement adds 64 
    KBytes for the header bitmap (HB) to the usable tablespace size.

  4. The physical file size adds one block (AB) to the defined tablespace size.

 Oracle8i: How to migrate LONG RAW to BLOB 

In Oracle8i BLOB's (Binary Large Objects) can be used instead of LONG RAW's to store binary unformatted data, like documents, images, audio and video. On the new BLOB data type many of the former LONG RAW restrictions are not valid anymore and up to 4GB can be stored. This tip shows how to migrate LONG RAW columns to BLOB's.

It is worth to create a separate tablespace for the LOB's bigger contents to gain performance. The tables containing LOB columns can be stored together with other tables in a tablespace (called tab in this sample). However the LOB columns referencing their data in a separate tablespace (called btabhere).

CREATE TABLESPACE btab
  DATAFILE '.../lob/POR1_lob1.dbf' SIZE 512064K REUSE
  AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
  EXTENT MANAGEMENT LOCAL UNIFORM SIZE 256K
  PERMANENT
  ONLINE;

A new table must be created that contains the new BLOB column. Even if it is possible to add a BLOB column to an existing table we cannot migrate old LONG RAW data in it. The required SQL functionTO_LOB can be used in SELECT subqueries of INSERT statements only.

Lets assume the old table docs looks like this...

id       NUMBER(10)    NOT NULL
bdata    LONG RAW      NULL

... we create the new one:

CREATE TABLE newdocs (
        id     NUMBER(10) CONSTRAINT nn_newdocs_id   NOT NULL,
        bdata  BLOB       DEFAULT empty_blob()       NULL    
    )
    PCTFREE  5
    PCTUSED  40
    INITRANS 1
    MAXTRANS 255
    TABLESPACE tab STORAGE (
        INITIAL       500K
        NEXT          500K
        MINEXTENTS    1
        MAXEXTENTS    UNLIMITED
        PCTINCREASE   0
        FREELISTS     1
    )
    LOB (bdata) STORE AS (
        TABLESPACE btab
        STORAGE (INITIAL 100M NEXT 100M PCTINCREASE 0)
        CHUNK 50
        PCTVERSION 10
        NOCACHE LOGGING
    );

LOB's in general do not use rollback segments. To maintain read consistency Oracle creates new LOB page versions every time a lob changes. PCTVERSION is the percentage of all used LOB data space that can be occupied by old versions of LOB data pages. As soon as old versions of LOB data pages start to occupy more than the PCTVERSION amount of used LOB space, Oracle tries to reclaim the old versions and reuse them. In other words, PCTVERSION is the percent of used LOB data blocks that is available for versioning old LOB data. The PCTVERSION can be set to the percentage of LOB's that are occasionally updated. If LOB's are inserted once and afterwards usually read only, 0% can be used.

If CACHE is specified Oracle places LOB pages in the buffer cache for faster access. NOCACHE can be used if there are occasionally no writes to stored LOB's and infrequently reads only. CACHE READ is good for busy read operations and infrequent writes.

Set CHUNK to the number of blocks of LOB data that will be accessed at one time. This reduces network roundtrip overheads. The INITIAL and NEXT storage parameters must be greater than CHUNK * DB_BLOCK_SIZE size. Use bigger CHUNK's if possible.

The default setting ENABLE STORAGE IN ROW stores LOB's less than 4KB within the table and greater LOB's are automatically moved out of the row. This is the recommended setting. DISABLE STORAGE IN ROW can be used to store all data outside the rows. A lot of small LOB's within a table can decrease performance of table operations like full table scans or multi-row accesses.

Consider that CHUNK and ENABLE/DISABLE STORAGE IN ROW cannot be altered after table creation.

Finally we can use the following SQL statement to migrate the data from the old to the new table:

INSERT INTO newdocs (id, bdata)
SELECT id, TO_LOB(bdata)
  FROM docs;

To copy the data is easy. The SQL function TO_LOB( ) can be used to convert LONG RAW to BLOB. It's also possible to convert LONG to CLOB if required. The main thing of the whole data migration is to choose good storage parameter settings especially if a large number and large LOB's in size need to be stored.

 Net8 access trough a firewall with port forwarding using SSH 

One option for secure communication between the Net8 client and server is to tunnel the communication inside the Secure Shell protocol. 

Conceptually, it works like this. First, you install an SSH client on the local machine where you run your Net8 client. You use the SSH client to establish an SSH connection to the remote host where the Net8 server is running. You also use the SSH client to establish a "listen" on a local port for Net8 requests.

Here's the cool part: when you fire up your Net8 client, it connects to the Net8 port on localhost - your machine - instead of connecting to port 143 on a remote server machine.

The SSH client then forwards everything it receives on the local Net8 port through the SSH session, or tunnel, to the remote SSH daemon, which then forwards the data to the Net8 port on the remote host.

How does the SSH daemon on the receiving end know what to do with all this Net8 information coming at it? Well, the information is part of the port-forwarding arrangement you gave the daemon when you first fired up the SSH session. For example, you'd invoke SSH from your unix client machine like this

ssh -f -L localport:remotehost:remoteport tail -f /dev/null

Tfhe command must be invoked as root because root privilege is required to set up port forwarding. The -f option tells SSH to run in the background after port forwarding has been established. -L localport:remotehost:remoteport specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side. In our example, we use port 5555 on the client and port 1521 on the database server 192.168.121.32

The server port must be whichever port listens for Net8 requests (1521 on most systems). Depending on the SSH client, you'll either be prompted for your password to log in to the SSHD 194.75.132.34 server when issuing the tunneling command, or you'll have to initiate a login manually to establish the session, In all cases, you'll have to use SSH to log in to the remote host before you can use it to "launder" your connection. The entire Net8 port-forwarding scenario is shown in the next figure.

Example

We start by using lsof (list open files), a program that tells you which open files and network connections belong to which processes. to check for software listening at local TCP port 5555. There is none. We confirm this by trying to telnet to localhost at port 555 without success.

lsof -i tcp:5555
telnet localhost 5555

At this point, we're certain that there's no activity, such as a listen or an open connection, on port 555 on our local machine. That port is okay to use. Next, we set up the port forwarding by issuing an SSH command. Remember that you have to be root to set up port forwarding:

su -
ssh -f -L 5555:192.168.121.32:1521 194.75.132.34 tail -f /dev/null
ps -ef

The tail -f /dev/null that we tacked on the end of the SSH command is just a low-overhead command to keep the session open. We didn't want to keep an actual shell session open and running in the background when we didn't need it, so we used the tail command instead. You can verify with ps -ef, that the command is now running in the background and you now have a permanent Net8 connection through two firewalls -- cool isn't it?

Next you have to setup your TNSNAMES.ORA configuration file, then check the connection withtnsping and finally connect with sqlplus.

ORA1.WORLD =
  (DESCRIPTION =
     (ADDRESS_LIST =
       (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 5555))
     )
     (CONNECT_DATA =
       (SERVICE_NAME = ORA1.WORLD)
       (SRVR = DEDICATED)
     )
  )

tnsping ORA1
sqlplus scott/tiger@ORA1

 Automatically Calculating Percentages in Queries 

Starting with Release 7.1 of Oracle, users have had access to a feature called an inline view. An inline view is a view within a query. Using this feature, you can easily accomplish your task.

Example: Show percentage of salaries for each department

Every row in the report must have access to the total sum of sal. You can simply divide sum (sal) by that total, and you'll have a number that represents the percentage of the total.

column percentage format 99.9

select deptno, sum(sal),sum(sal)/tot_sal*100 "PERCENTAGE"
  from emp, (select sum(sal) tot_sal from emp)
 group by deptno, tot_sal;

    DEPTNO   SUM(SAL) PERCENTAGE
---------- ---------- ----------
    10           8750       30.1
    20          10875       37.5
    30           9400       32.4

With Oracle8i Release 2 (8.1.6 and higher), you can calculate percentages by using the new analytic functions as well. The query using an analytic function might look like this:

column percentage format 99.9

select deptno, sum(sal), (ratio_to_report(sum(sal)) over())*100 "PERCENTAGE"
  from emp
 group by deptno;

    DEPTNO   SUM(SAL) PERCENTAGE
---------- ---------- ----------
    10           8750       30.1
    20          10875       37.5
    30           9400       32.4

The query produces the same answer—but it does so more efficiently, because it does not have to make two passes over the data to arrive at the answer. Because the analytic functions are built-in, queries that use them will find the answer more rapidly than the "pure" SQL-based approach.

 Show Table and System Privileges

It is normally difficult to list all privileges and roles assigned to a specific user in one select, since a privilege can be assigned to a role, which can be assigned to another role, which in turn can be assigned to another role

posted @ 2014-04-01 01:37  princessd8251  阅读(152)  评论(0)    收藏  举报