Showing posts with label Tips. Show all posts
Showing posts with label Tips. Show all posts

Installing Oracle silently

Oracle Universal Installer by default installs any oracle products in its GUI mode. In situations where the GUI could not be started, it is not possible to install Oracle, such as in Linux environments if X Server could not be started it is difficult to install any Oracle products.

Moreover for a DBA, it is very cumbersome to sit and click buttons for installation. For automating purposes, Oracle Universal Installer (OUI) provides a silent mode of installation.

The runInstaller script which is used for calling the OUI has some switches which can be used to achieve this functionality.

./runInstaller -record -destinationFile  
./runInstaller -silent -responseFile

Here is how:

First Step
./runInstaller -record -destinationFile ResponseFile.txt

The record parameter tells the installer to write to the response file and the destinationFile parameter defines the name of the response file. Once the response file is created you can run the installer in silent mode using the following command:

Second Step
./runInstaller -silent -responseFile ResponseFile.txt

The silent parameter indicates the OUI to install the product using the parameters found in the file passed throught responseFile parameter.

Once the installer stops for executing root.sh as root user, the installation will be completed.

Fastest spool: SQL Plus Vs UTL_FILE

I got a following query from Suvankar Das.

"I need to unload few Oracle tables with average data volume of 15M records to flat files. Is the SQL* Plus spool a good option for this volume of data from performance point of view OR is it better to do through PL/SQL UTL_FILE option."

And this is how I responded:

"SQL* Plus will have the fastest result to the flat file. Only use UTL_FILE if you need some more programmatic control in between the spooling.

To make sure first take a sample set of data (some thousands of records) for spooling using SQL *Plus and do the same using UTL_FILE. Compare both the timings.

Also based on the sample estimate the time for the entire 15M records."

The Verdict:
There is no hard rule that says either SQL *Plus or UTL_FILE will perform faster. It varies from environment to environment.

Where SQL *Plus/UTL_FILE could perform faster
SQL *Plus is a client program which is accessing Oracle database. Therefore it highly depends on the network. If the network traffic to the server is slow, then SQL *Plus will perform slower. No doubt. If the server and client are in same machine expect SQL *Plus to perform faster.

UTL_FILE is a server-side program residing within the Oracle database server. Use this procedure if you need to spool something in the server. This will perform faster in such cases. In client machine it always depends on the network load. Whether you are using SQL *Plus or UTL_FILE the network load is always a factor to check with.

Unloading oracle data to flat files

Today I was answering one of the queries, this question seriously made my interest. The question was

"I have 15 million records in my table. What do you suggest a best method for unloading them from Oracle table to a flat file".

Seriously till that time I had never done this. The need had not come. I clearly know two ways of doing this:
  • Using SQL Plus and SPOOL command
  • Using UTL_FILE built-in package
UTL_FILE vs SPOOL
I know that SPOOL command will be faster in execution than UTL_FILE package, but also I reminded myself that this may not be the case always. SPOOL commands operates in the client machine and depending upon the network traffic it might take time for the SPOOL operation than UTL_FILE. 

SO I ADVICE TO TEST BOTH OPTIONS IN YOUR ENVIRONMENT BEFORE FINALISING ON ONE OF THE ABOVE.

I will soon publish routines for this purpose. Your patience is appreciated.

More resources for your inquisitive mind
A little surfing did a wonderful job in putting this article up. In asktom I found a beautiful document that should be the starting page for such exploration. Here is the link for you. I am not going to discuss how tom reviews this anymore. Check the link for yourself.

If you are not having Oracle client in your machine and still you need to unload the data to flat file, follow this link and introduce yourself to a tool OraCmd. I have not personally used this tool, but from the description in the website it promises to be one. I will test the performance issues with this as well in the near future. Here is the link for unloading using OraCmd.

Making Oracle Case sensitive, again

This article is a continuation on Making Oracle Case Insensitive. Read that first to understand the context discussed here.


Oracle is always Case Sensitive while querying data. Now we have learned how to make Oracle Case Insensitive for queries. Let us ask some questions to get going.

What is the purpose of making Oracle Case Insensitive?
By making Oracle Case Insensitive, you need not any more use Case mixed words. For example Test, TEST, tESt are all same once you have made Oracle Case Insensitive. Its use could be in Data warehousing applications.

How to make Oracle Case Sensitive back again after this?
You have to alter two session paramaters NLS_COMP and NLS_SORT.

First set NLS_COMP to binary.

ALTER SESSION SET nls_comp=binary;

Secondly set NLS_SORT to generic.

ALTER SESSION SET nls_sort=GENERIC_M_CI;

Once these variables are altered Oracle is back in business as case sensitive.

MSSQL-Creating a table as duplicate of another table

I was very much frustrated with the simple but syntactical change between Oracle and MS-SQL Server. I was trying to just create a table with the normal Oracle syntax in MS-SQL Server:

CREATE TABLE test AS SELECT * FROM existing_table;

I got an error from MS-SQL and then I had to call up some experts on MS-SQL to understand how it is done in MS-SQL.

The syntax for creating such a duplicate table of an existing one in MS-SQL is as follows:

SELECT *
INTO {new_table}
FROM {existing_table}
WHERE {if_clause if any};

Thus our example can be translated to as:

SELECT *
INTO test
FROM existing_table;

This short article is to just keep up the difference between MS-SQL and Oracle. Oracle professionals may sometimes need to work in MS-SQL, and this kind of tips on MS-SQL comes handy in times of trouble.

Deleting duplicate rows from Oracle Table

Tip Courtesy: Oracle Tips by Burleson Consulting (dba-oracle)

Removing duplicate rows from Oracle tables with SQL can be very tricky, and there are several techniques. This post shows some examples of using SQL to delete duplicate table rows using an SQL sub query to identify duplicate rows, manually specifying the join columns:

DELETE FROM
   table_name A
WHERE
  a.rowid >
   ANY (
     SELECT
        B.rowid
     FROM
        table_name B
     WHERE
        A.col1 = B.col1
     AND
        A.col2 = B.col2
        );


For a script that does not uses ROWID concept, read this post.

Deleting/Listing duplicate records without ROWID

How to validate values in PL/SQL

I chose to write on this topic in order to increase the readability of programs and to maintain a standard way of validating values from within PL/SQL blocks, whether be it Anonymous blocks or Stored Procedures or Stored Functions or Packages. There has been always need for writing efficient piece of code before delivering the final one.

Validating NULL Values

NVL Function
This function is boon to programmers. I always chose to use this function because of its simplicity. In Oracle one must always remember that while validating with a NULL value the result you are going to get is also a NULL. So in order to avoid this it is better to use NVL() function.

Syntax:
NVL(variable1, variable2)

Example:
SELECT NVL(NULL, 'This is the output') null_test FROM dual;

Result:
null_test
This is the output

Both the parameters are required for NVL function to perform. You can use this function in WHERE clause so that you are not going to omit any NULL values from your query.

NVL2 Function
NVL2 function is an extension of NVL function that it can return two values, one when the variable to be tested is NULL and when the variable to be tested is NOT NULL.

Syntax:
NVL2(variable1, variable1_if_not_null, variable1_if_null)

Example 1:
SELECT NVL2(NULL,'NOT NULL','NULL') nvl2_test FROM dual;

Result:
nvl2_test
NULL

Example 2:
SELECT NVL2('some value','NOT NULL','NULL') nvl2_test FROM dual;

Result:
nvl2_test
NOT NULL

Validating NOT NULL Values
While validating NOT NULL values there is no need to use such functions as the value will be present already in the variable. But if the check is for whether the value is null or not then NVL2 function will be best suitable for the purpose.

How to enter a single quotation mark in Oracle

Q: How to enter a single quotation mark in Oracle?

Ans: Although this may be a undervalued question, I got many a search for my blog with this question. This is where I wanted to address this question elaborately or rather in multiple ways.

Method 1
The most simple and most used way is to use a single quotation mark with two single quotation marks in both sides.

SELECT 'test single quote''' from dual;

The output of the above statement would be:
test single quote'

Simply stating you require an additional single quote character to print a single quote character. That is if you put two single quote characters Oracle will print one. The first one acts like an escape character.

This is the simplest way to print single quotation marks in Oracle. But it will get complex when you have to print a set of quotation marks instead of just one. In this situation the following method works fine. But it requires some more typing labour.

Method 2
I like this method personally because it is easy to read and less complex to understand. I append a single quote character either from a variable or use the CHR() function to insert the single quote character.

The same example inside PL/SQL I will use like following:

DECLARE
l_single_quote CHAR(1) := '''';
l_output VARCHAR2(20);
BEGIN
SELECT 'test single quote'||l_single_quote
INTO l_output FROM dual;

DBMS_OUTPUT.PUT_LINE(l_single_quote);
END;

The output above is same as the Method 1.

Now my favourite while in SQL is CHR(39) function. This is what I would have used personally:

SELECT 'test single quote'||CHR(39) FROM dual;

The output is same in all the cases.

Now don't ask me any other methods, when I come to know of any other methods I will share here.

LONG to BLOB Migration

In release 8.1, a new SQL function, TO_LOB, copies data from a LONG column in a table to a LOB column. The datatype of the LONG and LOB must correspond for a successful copy. For example, LONG RAW data must be copied to BLOB data, and LONG data must be copied to CLOB data. In the next example we show how to migrate a table with one LONG to a CLOB datatype.

Create the LOB Tablespace

CREATE TABLESPACE lob1
DATAFILE '/lh4/lob1.dbf' SIZE 2048064K REUSE
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 50M
PERMANENT
ONLINE;

Disable temporarily all Foreign Keys

set feed off;
spool gen_dis_cons.sql;
SELECT 'ALTER TABLE ' table_name
' DISABLE CONSTRAINT ' constraint_name ';'
FROM user_constraints WHERE UPPER(constraint_name) like 'FK_%'
/
spool off;
set feed on;
@gen_dis_cons.sql;

Convert LONG to LOB in temporary Table

Create a temporary table with converted BLOB field.

CREATE TABLE lob_tmp
TABLESPACE tab
AS SELECT id, TO_LOB(bdata) bdata FROM document;

Drop and Rename Tables

DROP TABLE document;
RENAME lob_tmp TO document;

Create the necessary Constraints and enable the Foreign Keys again

set feed off;
set heading off;
spool gen_ena_cons.sql;
SELECT 'ALTER TABLE ' table_name
' ENABLE CONSTRAINT ' constraint_name ';'
FROM user_constraints WHERE UPPER(constraint_name) like 'FK_%'
/


spool off;
set feed on;
@gen_ena_cons.sql;


Courtesy: akadia

Switch to another Oracle User and back

Sometimes, the DBA needs to log into a user's account to make a change, such as to grant a privilege on a user's table to another user, but, may not know what the user's password is, or, may need to make changes to a set of users from a script, but, doesn't want to include their passwords in the script itself.  Oracle provides an undocumented "identified by values" clause in the "alter user" command that can be used for this purpose. 

Since the dba_users table contains the encoded password for each user, this value can be used to generate an "alter user" command to reset the user's password back to its original value.  Then, from user system or another DBA user, you can alter the user's password to a known value (such as "whatever"), log into the user's account using "connect userid/whatever", make the changes that are needed, connect back to the system account, and run the generated "alter user" command to put the original password back.

The following SQL generates a password change script (setpw.sql) to set all users to a known password ("whatever"), and, another script (resetpw.sql) to set all users back to their original passwords.  This would be used as part of another script to generate the password change scripts, run setpw.sql, log in and make the changes that are needed, and immediately run resetpw.sql to put the passwords back.  Note that the users won't be able to log in during that time, since their passwords are not valid while you are running the script.

spool setpw.sql
select 'alter user ' || username || ' identified by whatever;' from dba_users;
spool off

spool resetpw.sql
select 'alter user ' || username || ' identified by values ''' || password || ''';' from dba_users;
spool off

Generated Script setpw.sql

alter user SYS identified by whatever;
alter user SYSTEM identified by whatever;
alter user DES identified by whatever;
alter user ELAN identified by whatever;

Generated Script resetpw.sql

alter user SYS identified by values '5638228DAF52805F';
alter user SYSTEM identified by values 'D4DF7931AB130E37';
alter user DES identified by values 'ABFEC5AC2274E54D';
alter user ELAN identified by values 'B53CE8493EC6FB92';

Source & Credits: www.akadia.com

How to switch Oracle in Single User-Multi Session Mode

During a migration it may be important, that nobody can connect to the database. You may have two possibilities to achieve this

On Table Level using LOCK TABLE

On Database Level using RESTRICTED SESSION

Exclusive Table Locks (X)

An exclusive table lock is the most restrictive mode of table lock, allowing the transaction that holds the lock exclusive write access to the table. An exclusive table lock is acquired for a table as follows:

$ sqlplus scott/tiger

SQL> GRANT ALL ON emp TO PUBLIC;
SQL> LOCK TABLE emo IN EXCLUSIVE MODE;

$ sqlplus test/test

SQL> SELECT * FROM scott.emp; (This works)
SQL> DELETE FROM scott.emp WHERE empno = 7369; (Waiting ...)

Permitted Operations

Only one transaction can obtain an exclusive table lock for a table. An exclusive table lock permits other transactions only to query the table.

Prohibited Operations

An exclusive table lock held by a transaction prohibits other transactions from performing any type of DML statement or placing any type of lock on the table.

Lock Duration

Oracle releases all locks acquired by the statements within a transaction when you either commit or roll back the transaction. Oracle also releases locks acquired after a savepoint when rolling back to the savepoint. However, only transactions not waiting for the previously locked resources can acquire locks on the now available resources. Waiting transactions will continue to wait until after the original transaction commits or rolls back completely.

Oracle in Single User Mode

You may use the RESTRICTED SESSION system privilege to switch the database in single user mode for migrations.

RESTRICTED SESSION - Specifies whether logon to Oracle is restricted

ENABLE - Allows only users with RESTRICTED SESSION system privilege to log on to Oracle. Existing sessions are not terminated.

DISABLE - Reverses the effect of the ENABLE RESTRICTED SESSION clause, allowing all users with CREATE SESSION system privilege to log on to Oracle. This is the default.

You can use this clause regardless of whether your instance has the database dismounted or mounted, open or closed.

In a first step (before the migration), you shutdown the database an start it again to be sure that all users are disconnected. Now revoke the RESTRICTED SESSION system privilege from most users, this system privilege is normally not used.

$ svrmgrl
svrmgr> CONNECT SYS AS sysdba;
svrmgr> SHUTDOWN IMMEDIATE;
svrmgr> STARTUP;
svrmgr> SPOOL revoke_restricted_session;
svrmgr> SELECT 'REVOKE restricted session FROM '
username ';' FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM');
svrmgr> SPOOL OFF;
svrmgr> @revoke_restricted_session.log;
svrmgr> ALTER SYSTEM ENABLE RESTRICTED SESSION;

As user SYS you can now perform the migration. If an ordinary user tries to connect, he will get the following error messge:

sqlplus scott/tiger

ERROR: ORA-01035: ORACLE only available to users
with RESTRICTED SESSION privilege

After the migration to not to forget, to disable the RESTRICTED SESSION system privilege

svrmgr> ALTER SYSTEM DISABLE RESTRICTED SESSION;

Source: www dot akadia dot com

Proxy user connect for SQL *Plus

Oracle Tips by Burleson Consulting

Today, systems with thousands of individual Oracle user ID's are not very common.  Almost all enterprise applications (ERP packages like SAP, Oracle Financials) use pre-spawned Oracle connections that are created by a single Oracle user ID with names like AR or SAPR3. 

The application server manages the connections to Oracle for us. 

This is called a "proxy", the term proxy meaning an act where a 3rd party does something on our behalf.   Unfortunately, when our end-users connect anonymously through a proxy, we do not have any end-user level security through traditional security tools like granting privileges or using roles and the only Oracle security is that is granted the ERP "master" user ID.

Who goes there?

From a DBA perspective, all database activity is being done by this single user and a query of the v$session view for an ERP does not identify any specific user, because they are connected to Oracle via the proxy on the application server.

This is a special nightmare for Oracle auditing, and all database auditing must now be done within the application server because is not aware of the "real" end-user, behind the proxy connection.

For complete information on Oracle auditing for ERP's see my notes in my bestselling security book "Oracle Privacy Security Auditing" with Arup Nanda.

The answer is to create a method whereby the ERP can maintain it's pre-spawned connection to Oracle while giving Oracle the ability to impose traditional security management (via roles, privileges, VPD's, etc.).

Oracle proxy connect authentication in 10gr2

To address this issue of unknown specific users within pre-spawned Oracle connections, Oracle has introduced a new proxy connection authentication in Oracle 10g release 2.

Under this new architecture, the ERP user ID is given limited privileges (create session only), and individual Oracle user ID's are created for each ERP user, using the traditional "create user" syntax.

Traditionally, you always connected to Oracle by only specifying your user ID and password:

connect scott/tiger

New with 10r2 proxy identification in SQL*Plus, the "connect" command has been enhanced to allow for a "proxy":

connect sapr3[scott]/tiger

You can also use this syntax to connect to SQL*Plus directly from the OS prompt:

root> sqlplus sapr3[scott]/tiger@mydb

As we see, we have a second, "proxy" user ID in the connect request (scott, in this case).  When Oracle establishes the database connection, he will first connect as SAPR3 (who only has connect and resource privileges) and then open a proxy connection as scott.

Now, we have complete Oracle privileges and access control, just as if the scott user was connected, but in reality we have connected with the SAPR3 user, keeping our pre-spawned connection pool happy.

Note:  To see the "proxy owner" of any Oracle session, you can see a proxy connection by using the sys_context package:

-- Here we see that Oracle has scott as the user ID

select user from dual;

USER
---------------------------------------
SCOTT
 


-- Here we call sys_context to reveal the proxy user:

select sys_context('USERENV','PROXY_USER') from dual;

SYS_CONTEXT('USERENV','PROXY_USER')
---------------------------------------
SAPR3

 If you like Oracle tuning, see the book "Oracle Tuning: The Definitive Reference", with 950 pages of tuning tips and scripts. 

You can buy it direct from the publisher for 30%-off and get instant acc

 

Article Courtesy:

http://www.dba-oracle.com/t_proxy_connect_authentication.htm

Running out of space? Want to move Oracle Datafiles?

Are you running out of space in the file system where database files (data files) are installed?

Try out this tip in order to move some of your data files from one drive to another and update the datafile location in your database.

The operating system: Oracle Enterprise Linux

The Database: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

In our environment we have installed our database's files (data files) in /oracle/oradata/mydb location. The drive is getting up to 99% of utilization. Now we will move the system01.dbf from the above mentioned location to a new location in /oracle/hdb1/oradata/mydb location. /oracle/hdb1 is mounted from /dev/hdb1. The drive is nearly empty, that's why I chose it.

Now for the real moving part, we will perform the following steps:

  1. Login to SQL* Plus and shutdown the database

  2. Logout from SQL* Plus and move the files from the source directory to destination directory.

  3. Login to SQL* Plus as /nolog

  4. Connect as SYSDBA to the database to an idle instance.

  5. Issue startup mount command to bring up the database.

  6. Issue ALTER DATABASE RENAME command to rename the data files from the source directory to destination directory.

  7. Now finally open the database.

The above mentioned are the brief steps by which we can achieve our goal. Now to demonstrate see the following commands as well so that it serves as a live example:

Step 1

oracle@astrn10: sqlplus /nolog

SQL> conn /as sysdba

SQL> shutdown immediate;

Troubleshooting: If you are not able to get the SQL prompt, check your ORACLE_HOME, and ORACLE_SID.

Step 2

SQL> exit;

oracle@astrn10: mv /oracle/oradata/mydb/system01.dbf /oracle/hdb1/oradata/mydb/

Now check whether the file have been moved or not by issuing the following command:

oracle@astrn10: ls /oracle/hdb1/oradata/mydb/

total 429924352

-rw-r----- 1 oracle oinstall 429924352 Feb 12 11:00 system01.dbf

Now we are ready for the next step.

Step 3

oracle@astrn10: sqlplus /nolog

SQL>

Step 4

SQL> conn /as sysdba

Connected to idle instance.

Step 5

SQL> startup mount;

Database mounted.

Step 6

SQL> alter database rename file '/oracle/oradata/mydb/system01.dbf' to '/oracle/hdb1/oradata/mydb/system01.dbf';

Database altered.

Step 7

SQL> alter database open;

Database opened.

That's all. We are done with our agenda for moving data files from one drive to another. If this where Windows/any other operating system, then copy files as per your operating system commands/interface in Step 2.

In order to copy more files (in this demonstration we have moved only one file), then repeat Step #2 and Step # 6 for each file.

#End of tip


Running 10gAS Form in full window

Mini Tip: Running 10gAS forms in MDI Window

Author: Anantha Narayanan

Date: November 6th 2007

 

Those who have been migrating from Oracle Client Server forms would have always wondered why the 10g forms are running always inside a browser. They probably know the reason of such behaviour.

 

In today’s mini article we will see how to change the default behaviour of 10gAS forms back to client server mode. If you have installed 10gAS in your local machine then there is no problem of access rights. If this is installed in some server and you do not have access to that machine, then forget this setting, because we need to modify the default server settings.

 

Locate the file formsweb.cfg (for default installations) (its default location will be in <AS_INSTALLATION_PATH>\forms\server and find out a parameter named separateFrame. This is a Forms applet parameter. These parameters are used to initialize the forms applet.

 

Modify the value for separateFrame from false to true. That’s all you need to do to change the default behaviour.

 

Note: If 10gAS is installed in D:\oracle\as, then the formsweb.cfg can be found out in D:\oracle\as\forms\server folder in case of Windows installations. In case of Linux/Unix installations if 10gAS is installed in /oracle/as, then the formsweb.cfg can be found out in /oracle/as/forms/server directory.

Conditional compilation of package

This tip was found in Oracle forums. With due respect to the author I am replicating the idea of the message below:

 

Oracle introduced conditional compilation of packages/procedures from 10g.

 

Conditional compilation allows PL/SQL code to be tailored to specific environments by selectively altering the source code based on compiler directives. It is considered a new feature of Oracle 10g Release 2, but is available in Oracle 10g Release 1 (10.1.0.4.0).

 

Compiler flags are identified by the "$$" prefix, while conditional control is provided by the $IF-$THEN-$ELSE syntax.

 

$IF boolean_static_expression $THEN text

  [ $ELSIF boolean_static_expression $THEN text ]

  [ $ELSE text ]

$END

 

Find below a simple example of procedure that uses conditional compilation. The objective of this package is to invalidate the package by not modifying the source/underlying objects.

 

SQL> create or replace package p is $IF ($$x) $then INVALID $else $end end;
 
Package created.
 
SQL> select status from user_objects where object_name='P';
 
STATUS
-------
VALID
 
SQL> alter package p compile PLSQL_CCFLAGS='x:true';
 
Warning: Package altered with compilation errors.
 
SQL> select status from user_objects where object_name='P';
 
STATUS
-------
INVALID

 

Thus without modifying the actual contents of the package we have been successful in invalidating the package.

 

More reads on:

Oracle Forum Topic

Oracle-Base

How to create view without underlying table

This tip will enable to create a view even if you do not have an underlying table already present in your database.

 

In this article you will learn to

  • Create view without a table
  • Creating a table for that view
  • How to make the view to work

 

Consider the following example:-

 

CREATE OR REPLACE FORCE VIEW force_view AS SELECT * FROM force_table;

 

Now check whether the view is created or not:

 

SELECT object_name, object_type, status, temporary, generated, secondary FROM user_objects WHERE object_name='FORCE_VIEW';

 

OBJECT_NAME OBJECT_TYPE STATUS      TEMPORARY   GENERATED   SECONDARY

----------- ----------- --------   ---------   ---------  ---------

FORCE_VIEW  VIEW        INVALID     N           N           N

 

So this ensures that the view is created, but what about the status? It says the view created is invalid.

 

Now we will try to execute the view:

 

SELECT * FROM force_view;

 

Error starting at line 1 in command:

select * from force_view

Error at Command Line:1 Column:14

Error report:

SQL Error: ORA-04063: view "RND.FORCE_VIEW" has errors

04063. 00000 -  "%s has errors"

*Cause:    Attempt to execute a stored procedure or use a view that has

           errors.  For stored procedures, the problem could be syntax errors

           or references to other, non-existent procedures.  For views,

           the problem could be a reference in the view's defining query to

           a non-existent table.

           Can also be a table which has references to non-existent or

           inaccessible types.

*Action:   Fix the errors and/or create referenced objects as necessary

 

This is the error which I get when running the view. So now you will understand that we will be just able to create the view, but it is useless until it has an underlying table attached to it.

 

Now we will create table for this view:

 

CREATE TABLE force_table (a NUMBER, b VARCHAR2(10));

 

Now will check again the status for the view.

 

SELECT object_name, object_type, status, temporary, generated, secondary FROM user_objects WHERE object_name='FORCE_VIEW';

 

OBJECT_NAME OBJECT_TYPE STATUS      TEMPORARY   GENERATED   SECONDARY

----------- ----------- --------   ---------   ---------  ---------

FORCE_VIEW  VIEW        INVALID     N           N           N

 

The status is still INVALID. Now we need to re-compile the view to make it VALID.

 

ALTER VIEW force_view COMPILE;

 

OBJECT_NAME OBJECT_TYPE STATUS      TEMPORARY   GENERATED   SECONDARY

----------- ----------- --------   ---------   ---------  ---------

FORCE_VIEW  VIEW        VALID       N           N           N

 

 

 

Selecting Nth MAX or MIN

This query has become the mostly asked question in any Oracle technical Interview. Following is an excerpt tip which comes from Ramcharan Karthic, software engineer in Bangalore, India.

 

Note: This tip was published in the January/February 2003 issue of Oracle Magazine.

 

This Select query will help you select the Nth Max or Min value from any table.

 

For example, consider a table TAB1 in which you want to find the Nth Max or Min from the column, COL1.

 

First, the query for Max:

 

SELECT * FROM TAB1 a

WHERE &N = (SELECT count (DISTINCT (b.col1))

FROM TAB1 b WHERE a.col1<=b.col1)

 

Next, the query for Min:

 

SELECT * FROM TAB1 a

WHERE &N = (SELECT count (DISTINCT (b.col1))

FROM TAB1 b WHERE a.col1>=b.col1)

 

If N=1 will return first max or first min. N=2 will return second max or min.

How to identify called procedure

This script and article is courtesy of asktom

Many times we are asked "in a procedure/function, can I find out who called me" or "can I dynamically figure out the name of the procedure or package that is currently executing".

You can find it in the call stack returned by dbms_utility.format_call_stack. I wrote a small routine called who_called_me that returns this sort of information (it doesn't tell you who you are; it lets you know who called you). If you wrap who_called_me with a function who_am_i, you'll get what you need. If you create the who_called_me/who_am_i routines, you'll be able to:

SQL> create or replace procedure demo
  2  as
  3  begin
  4     dbms_output.put_line( who_am_i );
  5  end;
  6  /
 
Procedure created.
 
SQL> exec demo;
TKYTE.DEMO

You can download who_called_me and who_am_I from here

 

Get Oracle table size

Oracle Tips by Burleson Consulting


First, we must remember that table size is constantly changing as DML adds and removes rows. Also, we have many other factors that determine the "actual" size of a table:

  • The high water mark for the Oracle table
  • The number of allocated extents
  • The amount of spaced reserved on each block for row expansion (PCTFREE)

Click here for the script

You need to ask yourself exactly which Oracle table size, you wish to query:

  • Do you want only the row space consumed? ( select avg_row_len*num_rows from dba_tables)
  • Do you want to include allocated file space for the table? (select . . . from dba_segments)
  • Do you want to include un-used extent space? (select . . . from dba_data_files, dba_extents . . )
  • Do you want to include un-used space up to the high water mark? This may over-estimate the real Oracle table size.
  • Do you want table sizes for Oracle growth monitoring?

There are many Oracle scripts for computing the size of a table, here is one.

Multipurpose code in Oracle and Oracle Forms

Author: Steve Callan, stevencallan@hotmail.com

When Oracle gave up the ghost on client-server Forms several years ago, one of the built-in's that went by the wayside was related to feeding parameters into an alert message function. If you handled errors or missing input (as you should), part of the Forms migration process involved changing the built-in from the 6i version to the 9i version. A complex application can have thousands of alert messages, and a major application (Forms, that is) change can require thousands of changes. Making a change like that was really bad form on Oracle's part.

On the other hand, as a DBA and developer using PL/SQL, how many times have you written DBMS_OUTPUT.PUT_LINE('whatever')? Having to write or type DBMS_OUTPUT.PUT_LINE gets to be very tiresome, so wouldn't it be nice to have a shorter piece of code along the lines of a handy built-in? Maybe not so much as foresight, but due more to good luck or realizing the same thing had to be typed over and over, crafty Forms developers made their own built-in, in the form of a procedure used to generate an alert message. That same construct can be used in your everyday PL/SQL code. In fact, you can create a small message library to take care of many types of output messages. Let's take a look at some of these possibilities.

A Simple Alert Message Procedure

Just as the section heading says, this first method is quite simple. Suppose you have a frequent need to output the number of records updated by a procedure, function, or block of code. Let's say the number of rows updated was 46. A simple “am(46);” based on the procedure below generates the output you're looking for.

CREATE OR REPLACE procedure am (msg number) as
begin
dbms_output.put_line('Records updated: '||msg);
end;
/

An alternative version can handle strings, so a call to “ams('your message here');” significantly shortens your typing/number of keystrokes. When debugging or troubleshooting code/logic, having an easily accessible “built-in” is invaluable for outputting stubs or “where am I in the code” statements. Location reporting can confirm, for example, where you were branched in an IF-THEN-ELSE statement. If your problem code has lots of calls to other objects (procedures, functions, etc.), echoing out state information such as “calling function X” and “returned from function X” can confirm process flow. Finally, another use case involves reporting values. You can report or track how (and even where) a variable has its value changed.

Building an Alert Message Library

The degree of complexity or flexibility of your message library is, of course, entirely up to you. If your (output) messaging needs are simple, then keep the procedure simple. More precisely, keep the number of separate procedures to a minimum. Two simple ones, named ams and amn can be used to output messages based on string and numeric input.

If the text component of the output you want needs to vary based on what just took place, such as the outcome of a DML statement, then you may want to have a set of three built-ins (one for inserted, updated and deleted). Maybe you want to specify the type or reason of deletion. Let's say that one step in a batch processing job is to count the number of duplicate records. An output of “Records counted: 46” is useful, but then in that vein, “Duplicates counted: 46” would appear to be even more telling. So let's add two more built-ins.

Just like that, we're up to at least six separate procedures. Hints of manageability issues should be apparent now. We were looking for something simple, but at the same time, robust. There are at least two ways to re-simplify the desired functionality. One way is to make the alert message procedure accept two input parameters, and the other, which is what I'm leading up to, is to package the procedures.

Increase the number of input parameters

Again, if this simpler solution fulfills your needs, there is no need to go further. Create the procedure with two inputs, the first being the message text or base, the second being the outcome, location, state or value. The two input combinations of text/text and text/number can be boiled down to text/text if you (not Oracle) take care of the data type conversion. Do you **have** to do the conversion? No, but to be consistent in what you do, if you cast elsewhere, then cast here. Regardless, the following example shows the flexibility of this first approach.

CREATE OR REPLACE procedure am (msg1 varchar2, msg2 varchar2) as
begin
dbms_output.put_line(msg1||msg2);
end;
/

After compilation, shown below is an example of its use.

SQL> set serveroutput on
SQL> exec am('Here I am',46);
Here I am46

PL/SQL procedure successfully completed.

Well, this output could look better (note the lack of a space between msg1 and msg2 in the output). Great, we're stuck with also having to format one or both message inputs to make the output look nice. However, if nicety is not a concern, then creating messages based on inputs like ('dupes ',46), where you take care of the spacing or formatting, is still pretty simple. Are there any pitfalls with this approach? That depends. What if all you need is msg1 and nothing for msg2? When creating the procedure, allow for msg2 to be null as needed. Obviously, this is not needed for msg1, right?

CREATE OR REPLACE procedure am
(msg1 varchar2, msg2 varchar2 default null) as
begin
dbms_output.put_line(msg1||msg2);
end;
/

Procedure created.

SQL> exec am('Where am I?');
Where am I?

PL/SQL procedure successfully completed.

Increasing the robustness

What if your message is very long, or needs to fit on a page/line of spooled output? Ignoring word wrapping for the time being, a simple way to chop up the text is to substring it appropriately. This situation cries out for recursion, and of course, the best way to understand recursion is to first understand recursion (sorry, old joke). The chopping up process performs a length check, if the remaining string is longer than your cutoff value, make a call to the substring-ing step, and repeat as necessary.

What if the cut takes place in the middle of a word? Okay, remember, this is PL/SQL, not a word processing program/language. In a Forms environment, where the text is going into a text field, you generally get this formatting for free. You do get some formatting functionality via SQL*Plus, but be sure to pick the right type for your needs. Using a series of eight strings of A through J (and a space after J), and setting the linesize low (easier to see the difference between the word wrapping options), the output below is an example of what takes place.

set serveroutput on format word_wrapped
exec am(insert the 8 strings here);
abcdefghij abcdefghij
abcdefghij abcdefghij
abcdefghij abcdefghij
abcdefghij abcdefghij

set serveroutput on format wrapped
exec am(insert the 8 strings here);
abcdefghij abcdefghij abcdefgh
ij abcdefghij abcdefghij abcde
fghij abcdefghij abcdefghij

The object lesson in this example is to take advantage of what is already built in. No need to reinvent the wheel is there? If “FORMAT WORD_WRAPPED” were not available, how would you solve this? The second example shows the straightforward cut referenced by the recursion approach.

Packaging up your library

There's a good example of how to create a base library in O'Reilly's Oracle PL/SQL Developer's Workbook (by Steven Feuerstein, published in 2000), and it takes advantage of overloading. As you may recall from a previous article, overloading allows you to use the same name for a function or procedure (within a package), and Oracle knows which version you're referencing by evaluating the number and types of parameters.

A clever naming convention to use, particularly if you work with Java developers, is to name the package “prt” and the procedures “ln,” so the end result is “prt.ln('your message');.” Java's method of printing a line uses System.out.println(), so you can see why “prt.ln” seems fairly intuitive as to its purpose and function. The examples shown in the book handle text, numeric, date, and Boolean types of input.

CREATE or REPLACE package prt is
Procedure ln (msg in varchar2);
Procedure ln (msg in number);
Procedure ln (msg in date);
Procedure ln (msg in boolean);
END prt;
/

The procedures above can be expanded to include the other examples or cases mentioned earlier. You can still have output with boilerplate text already built in. Just add “Procedure dup(msg in number” to the package and package body, and a call such as “prt.dup(46);” can result in an output of “Duplicates counted: 46.”

In Closing

So what if Oracle Corporation were to one day change/deprecate the DBMS_OUTPUT built-in? How many places in your code base have you used this? The beauty of packaging up this functionality into your own library is that you would only need to update one body of code – that of what is in the package body. The Forms community spent thousands of hours having to update thousands, if not millions, of forms binary files because of how the alert message functionality/specification changed. For DBAs and developers, this should serve as a valuable lesson in learning how to take charge of what Oracle provides out of the box and making something better to suit your own purposes.