Showing posts with label ORA ERROR. Show all posts
Showing posts with label ORA ERROR. Show all posts

Wednesday, October 22, 2008

ORA-00257: archiver error. Connect internal only, until freed.

ORA-00257: archiver error. Connect internal only, until freed.

Cause: The archiver process received an error while trying to archive a redo log. If the problem is not resolved soon, the database will stop executing transactions. The most likely cause of this message is the destination device is out of space to store the redo log file.

Action: Check the archiver trace file for a detailed description of the problem. Also, verify that the device specified in the initialization parameter ARCHIVE_LOG_DEST is set up properly for archiving.

ORA-000257 error is somewhat common error and is caused whenever archiver is unable to archive the online redo log files at the desired location. Usually this error cocurs when archive destination is full and the archiver was not able to write any more due to lack of space.

So for understanding this ORA-000257 error, it is better knowing the concepts of Oracle Archiving. SO here are the archiving details


What is archiving and Oracle archived redo logs ?

The folowing explanation excerpt from Oracle documentation
"Oracle Database lets you save filled groups of redo log files to one or more offline destinations, known collectively as the archived redo log, or more simply the archive log. The process of turning redo log files into archived redo log files is called archiving. This process is only possible if the database is running in ARCHIVELOG mode. You can choose automatic or manual archiving.

An archived redo log file is a copy of one of the filled members of a redo log group. It includes the redo entries and the unique log sequence number of the identical member of the redo log group. For example, if you are multiplexing your redo log, and if group 1 contains identical member files a_log1 and b_log1, then the archiver process (ARCn) will archive one of these member files. Should a_log1 become corrupted, then ARCn can still archive the identical b_log1. The archived redo log contains a copy of every group created since you enabled archiving.

When the database is running in ARCHIVELOG mode, the log writer process (LGWR) cannot reuse and hence overwrite a redo log group until it has been archived. The background process ARCn automates archiving operations when automatic archiving is enabled. The database starts multiple archiver processes as needed to ensure that the archiving of filled redo logs does not fall behind."


Why archived redo logs are used?

-To Recover a database

-To Update a standby database


-To Get information about the history of a database using the LogMiner utility



Oracle database can be run in two modes (1) ARCHIVELOG mode (2) NOARCHIVELOG mode

NOARCHIVELOG Mode:


When you run your database in NOARCHIVELOG mode, you disable the archiving of the redo log.

NOARCHIVELOG mode protects a database from instance failure but not from media failure. Only the most recent changes made to the database, which are stored in the online redo log groups, are available for instance recovery. If a media failure occurs while the database is in NOARCHIVELOG mode, you can only restore the database to the point of the most recent full database backup. You cannot recover transactions subsequent to that backup.

In NOARCHIVELOG mode you cannot perform online tablespace backups, nor can you use online tablespace backups taken earlier while the database was in ARCHIVELOG mode. To restore a database operating in NOARCHIVELOG mode, you can use only whole database backups taken while the database is closed. Therefore, if you decide to operate a database in NOARCHIVELOG mode, take whole database backups at regular, frequent intervals.


ARCHIVELOG Mode:

When you run a database in ARCHIVELOG mode, you enable the archiving of the redo log. The database control file indicates that a group of filled redo log files cannot be reused by LGWR until the group is archived. A filled group becomes available for archiving immediately after a redo log switch occurs.

The archiving of filled groups has these advantages:

A database backup, together with online and archived redo log files, guarantees that you can recover all committed transactions in the event of an operating system or disk failure.

If you keep an archived log, you can use a backup taken while the database is open and in normal system use.

You can keep a standby database current with its original database by continuously applying the original archived redo logs to the standby.


So, If you cannot afford to lose any data in your database in the event of a disk failure, use ARCHIVELOG mode.
In reality most of the Oracle databases run in ARCHIVELOG mode.

The Oracle error ORA-000257, which we are discussing occurs in the databases that run in ARCHIVELOG mode.


Where does the Archive Logs stored/resides?

Oracle database lets you specify whether to archive, redo logs to a single destination or multiplex them. If you want to archive only to a single destination, you specify that destination in the LOG_ARCHIVE_DEST initialization parameter. If you want to multiplex the archived logs, you can choose whether to archive to up to ten locations (using the LOG_ARCHIVE_DEST_n parameters) or to archive only to a primary and secondary destination (using LOG_ARCHIVE_DEST and LOG_ARCHIVE_DUPLEX_DEST).

Two methods for specifying archive destination:

Method 1: Using the LOG_ARCHIVE_DEST_n Parameter


Use the LOG_ARCHIVE_DEST_n parameter (where n is an integer from 1 to 10) to specify from one to ten different destinations for archival. Each numerically suffixed parameter uniquely identifies an individual destination.

Steps for setting archivelog destination:

step1 )Use SQL*Plus to shut down the database.

SHUTDOWN

step2 )Set the LOG_ARCHIVE_DEST_n initialization parameter to specify from one to ten archiving locations. The LOCATION keyword specifies an operating system specific path name. For example, enter:

LOG_ARCHIVE_DEST_1 = 'LOCATION = /disk1/archive'
LOG_ARCHIVE_DEST_2 = 'LOCATION = /disk2/archive'

Step3) Optionally, set the LOG_ARCHIVE_FORMAT initialization parameter, using %t to include the thread number as part of the file name, %s to include the log sequence number, and %r to include the resetlogs ID (a timestamp value represented in ub4). Use capital letters (%T, %S, and %R) to pad the file name to the left with zeroes.
example for UNIX OS:
LOG_ARCHIVE_FORMAT=%t_%s_%r.dbf


Method 2: Using LOG_ARCHIVE_DEST and LOG_ARCHIVE_DUPLEX_DEST

To specify a maximum of two locations, use the LOG_ARCHIVE_DEST parameter to specify a primary archive destination and the LOG_ARCHIVE_DUPLEX_DEST to specify an optional secondary archive destination. All locations must be local. Whenever the database archives a redo log, it archives it to every destination specified by either set of parameters.

Perform the following steps the use method 2:

step1) Use SQL*Plus to shut down the database.

SHUTDOWN

Step2) Specify destinations for the LOG_ARCHIVE_DEST and LOG_ARCHIVE_DUPLEX_DEST parameter (you can also specify LOG_ARCHIVE_DUPLEX_DEST dynamically using the ALTER SYSTEM statement). For example, enter:

LOG_ARCHIVE_DEST = '/disk1/archive'
LOG_ARCHIVE_DUPLEX_DEST = '/disk2/archive'

Step3) Set the LOG_ARCHIVE_FORMAT initialization parameter.
example for UNIX OS:
LOG_ARCHIVE_FORMAT=%t_%s_%r.dbf


The Oracle error ORA-000257, which we are discussing occurs in the databases that run in ARCHIVELOG mode when the above mentioned archive destinations are full and when the archiver was unable to write to these archive destinations

In order to resolve this error you need to find the archive log info from the database. For that Oracle provides number of internal views and commands. The following are those details:


Oracle Archive related Views:

V$DATABASE Shows if the database is in ARCHIVELOG or NOARCHIVELOG mode and if MANUAL (archiving mode) has been specified.
V$ARCHIVED_LOG Displays historical archived log information from the control file. If you use a recovery catalog, the RC_ARCHIVED_LOG view contains similar information.
V$ARCHIVE_DEST Describes the current instance, all archive destinations, and the current value, mode, and status of these destinations.
V$ARCHIVE_PROCESSES Displays information about the state of the various archive processes for an instance.
V$BACKUP_REDOLOG Contains information about any backups of archived logs. If you use a recovery catalog, the RC_BACKUP_REDOLOG contains similar information.
V$LOG Displays all redo log groups for the database and indicates which need to be archived.
V$LOG_HISTORY Contains log history information such as which logs have been archived and the SCN range for each archived log.

To find which redo log group requires archiving run the folowing query:

SELECT GROUP#, ARCHIVED
FROM SYS.V$LOG;

GROUP# ARC
-------- ---
1 YES
2 NO

To find the current archiving mode run the following query:

SELECT LOG_MODE FROM SYS.V$DATABASE;

LOG_MODE
------------
NOARCHIVELOG



The ARCHIVE LOG LIST Command
The SQL*Plus command ARCHIVE LOG LIST displays archiving information for the connected instance. For example:

SQL> ARCHIVE LOG LIST

Database log mode Archive Mode
Automatic archival Enabled
Archive destination D:\oracle\oradata\TESTDB1\archive
Oldest online log sequence 11270
Next log sequence to archive 11274
Current log sequence 11274

This display tells you all the necessary information regarding the archived redo log settings for the current instance:

The database is currently operating in ARCHIVELOG mode.

Automatic archiving is enabled.

The archived redo log destination is D:\oracle\oradata\TESTDB1\archive.

The oldest filled redo log group has a sequence number of 11270.

The next filled redo log group to archive has a sequence number of 11274.

The current redo log file has a sequence number of 11274.



RESOLUTION/Fix to ORA-00257 error:

Increase the free space in the archive log destination directories. The location where archiver archives the log is determined by parameter file pfile or spfile.
You can find the archive log destination by running the following command from SQL*Plus
SQL> show parameter log_archive_dest

You can also find archive destination information using above mentioned oracle internal views and commands mainly by using " archive log list" command

In case no more space is available at the current archive destination due to OS / Disk limitations , you can specify a new desination location by setting the parameter log_archive_dest (or log_archive_dest_1 in some cases) so that the new archives are produced at new location.
You can do this modifying init.ora file or using alter system if spfile is present

SQL> alter system set log_archive_dest_1=’LOCATION = /disk9/archive'

The other option is to take a backup of the archives from the current desination and delete those archives from that place so that new archives can generated at the current destination.
The backup can be OS level backup and OS level file deletion BUT the recommended method for ASM in place is taking RMAN backup and delete using RMAN.
Eample:
rman target sys/sys

RMAN> backup archive log all device type disk format ‘/oracle/arch_%U’;

RMAN> delete archive until time ‘trunc(sysdate)’;

This will delete all the archive logs until today and space will freed and the archiver will start archiving redo logs


CONCLUSION:


The ORA-00257 Oracle error is related to archiving of the oracele database redo logs and it requires immmediate attention of the DBA. So Oracle users when you encounter this error notify the DBA so that this error will be corrected abd instance crashes will be avoided.
This error is mainly caused because of lack of space at the archive destination. Oracle provides number of views and commands to find the archivelog, archive destination info as mentioned above in the article, by using them we can find identify which archive destination ran out of space and can take appropriate action as described in the resolution to the error.

I hope this article is informative enough to identify root cause for ORA-00257 error, to provide insights on oracle ARCHIVELOG feature and to help in resolving ORA-000257 error. More Details at http://ora-00257.ora-code.info/.

Mendus, Oracle OCP
www.ora-code.info

Wednesday, April 30, 2008

ORA-04091: table is mutating trigger

ORA-04091: table string.string is mutating, trigger/function may not see it

Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.

Action: Rewrite the trigger (or function) so it does not read that table.


ORACLE MUTATING TABLE PROBLEM

The mutating trigger error (ORA-04091) is a pretty common problem in Oracle that happens and frustrates many application developers and DBAs as the application developers bug them to find a solution. It happens when a trigger on a table tries to insert, update, or even select from the same table of whose trigger is being executed. Sometimes the inability to see the table causes standstill in the development.

 

The following explanation and the associated scripts attempt to present just one work-around for the problem. The work around may not be the best but rather does show that a work-around is possible and provides a solution that will be applicable in most cases. The approach is described by a case study.

 
 
SCENARIO
 

The mutating table problem comes when the trigger tries to select or modify any row of the same table. This situation comes when a table preserves some effective date.

To describe this method, the SALGRADE table will be used.

The table SALGRADE contains information on salary limits for each grade. The salary limits are also based on a time factor, i.e. the employees' salary is determined by checking which grade level was effective when they joined or reviewed, not necessarily the grade effective now.

So the table looks like this:

 
SQL> desc salgrade;
 Name                            Null?    Type
 ------------------------------- -------- ----
 GRADE                                    NUMBER
 LOSAL                                    NUMBER
 HISAL                                    NUMBER
 START_DATE                               DATE
 END_DATE                                 DATE
 
The table data looks like:
 
GRADE   LOSAL   HISAL   START_DATE       END_DATE
------- ------- ------- ----------       ---------
1       1000    2000    1-APR-94         3-AUG-95
1       1200    2200    3-AUG-95                   <---- Null
2       1500    3000    23-JUL-92        12-DEC-93
2       1600    3200    12-DEC-93        11-JAN-95
2       1800    3400    11-JAN-95                  <---- Null
 

This means the effective salary range of Grade 1 now is (1200-2200) not the employees who had review between 1-APR-94 to 3-AUG-95 will be in the range (1000-2000). This is a purely hypothetical scenario. The objective is to devise a trigger that does the following when a new record is inserted:

(1) Integrity checking for overlapping dates, i.e. the new record can't have a start date that is already covered.

(2) Update the record for the current grade to make the end_date equal to the start date of the new record (the new record's end_date must be null as that is the current record).

In both cases the table SALGRADE has to be selected and updated on the after insert row trigger on the same table. But the table will be mutating when the trigger fires and thus a run-time error will occur.

For the first requirement, consider the following trigger:

create or replace trigger taiudr_salgrade
after insert on salgrade
for each  row
declare
        hold_found      varchar2(1);
begin
        select 'Y' into hold_found
        from salgrade
        where grade = :new.grade
        and end_date is null
        and start_date > :new.start_date;
 
exception
        when NO_DATA_FOUND then
                raise_application_error(-20000,'Overlapping Dates');
end;
/
 
Although the trigger can be created with no errors, when a user tries to
insert into the table the following mutating table error is returned:
 
SQL> insert into salgrade values (2, 9000, 100000, '25-dec-95', null);
insert into salgrade values (2, 9000, 100000, '25-dec-93', null)
            *
ERROR at line 1:
ORA-04091: table SCOTT.SALGRADE is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.TAIUDR_SALGRADE", line 4
ORA-04088: error during execution of trigger 'SCOTT.TAIUDR_SALGRADE'
 
SOLUTION
 

The following approach is another possibility for the task:

1. Create a package "SALGRADE_PKG" that contains PL/SQL tables for holding the

SALGRADE data. Here 3 tables are created - one for holding start_dates, one

for end_dates, and one for holding the change_flag that identifies the

updated row.

2. Create a BEFORE INSERT STATEMENT trigger that populates the PL/SQL table with the start dates, end_dates and changed_grades flag ('N'). Although this still executes a SELECT agaist the SALGRADE table, the mutating table restriction, applies to all triggers that use the FOR EACH ROW clause and this new trigger will be a STATEMENT or table level trigger.

3. Create an AFTER INSERT ROW trigger that compares the newly inserted row against this PL/SQL table not the Database table. This way the integrity check can be done. The same trigger should assign the new end_date value to the PL/SQL table and update the value of the flag to indicate that this

has to be changed.

4. Create a AFTER INSERT STATEMENT trigger to update the SALGRADE table with the values in the PL/SQL table after looking at the change flag.

All these programs can be created by the sources found below.

CODE:
 
Code to create test table and populate it with data:
 
drop table salgrade;
 
CREATE TABLE SALGRADE
      (GRADE NUMBER,
        LOSAL NUMBER,
        HISAL NUMBER,
        START_DATE DATE,
        END_DATE DATE);
 
INSERT INTO SALGRADE VALUES (1,1000,2000, '1-apr-94', '3-aug-95');
INSERT INTO SALGRADE VALUES (1,1200,2200, '3-aug-95', null);
INSERT INTO SALGRADE VALUES (2,1500,3000, '23-Jul-92', '12-dec-93');
INSERT INTO SALGRADE VALUES (2,1600,3200, '12-dec-93', '11-jan-95');
INSERT INTO SALGRADE VALUES (2,1800,3400, '11-jan-95', null);
 
Code for package STEP 1 above:
 
create or replace package salgrade_pkg as
type datetabtype        is table of date index by binary_integer;
type chartabtype        is table of char(1) index by binary_integer;
type rowidtabtype   is table of rowid  index by binary_integer;
start_date_tab          datetabtype;
end_date_tab            datetabtype;
rowid_tab                       rowidtabtype;
changed_grade           chartabtype;
start_date_tab_size     binary_integer;
end;
/
 
Code for before insert statement trigger STEP 2 above:
 
create or replace trigger tbiuds_salgrade
before insert on salgrade
declare
 hold_start_date  date;
 hold_end_date  date;
 hold_rowid   rowid;
 hold_grade   binary_integer;
 cursor start_date_cur is
  select rowid, grade, start_date
  from salgrade
  where end_date is null
  order by grade;
begin
 open start_date_cur;
 loop
  fetch start_date_cur into
   hold_rowid, hold_grade, hold_start_date;
  exit when start_date_cur%notfound;
  salgrade_pkg.start_date_tab(hold_grade) := hold_start_date;
  salgrade_pkg.end_date_tab(hold_grade) := hold_end_date;
  salgrade_pkg.rowid_tab(hold_grade) := hold_rowid;
  salgrade_pkg.changed_grade(hold_grade) := 'N';
 end loop;
 salgrade_pkg.start_date_tab_size := hold_grade;
 close start_date_cur;
end;
/
 
Code for after insert row trigger STEP 3 above:
 
create or replace trigger taiudr_salgrade
after insert on salgrade
for each  row
begin
 if (:new.grade <= salgrade_pkg.start_date_tab_size) then
  if salgrade_pkg.start_date_tab(:new.grade)
    > :new.start_date then
   raise_application_error(-20001,'Overlapping Dates');
  end if;
  salgrade_pkg.end_date_tab(:new.grade) := :new.start_date;
  salgrade_pkg.changed_grade(:new.grade) := 'Y';
 else
  salgrade_pkg.start_date_tab(:new.grade) := :new.start_date;
  salgrade_pkg.end_date_tab(:new.grade) := :new.end_date;
  salgrade_pkg.changed_grade(:new.grade) := 'N';
  salgrade_pkg.start_date_tab_size :=
    salgrade_pkg.start_date_tab_size + 1;
 end if;
end;
/
 
Code for after insert statement trigger STEP 4 above:
 
create or replace trigger taiuds_salgrade
after insert on salgrade
begin
        for i in 1..(salgrade_pkg.start_date_tab_size) loop
                if (salgrade_pkg.changed_grade(i) = 'Y') then
                        update salgrade
                        set end_date = salgrade_pkg.end_date_tab(i)
                        where rowid = salgrade_pkg.rowid_tab(i);
                end if;
        end loop;
end;
/
 
Once all the package and triggers are created, the same insert doesn't succeed but gives the user the a more appropriate error:
 
SQL> insert into salgrade values (2, 9000, 100000, '25-dec-93', null);
insert into salgrade values (2, 9000, 100000, '25-dec-93', null)
            *
ERROR at line 1:
ORA-20001: Overlapping Dates
ORA-06512: at "SCOTT.TAIUDR_SALGRADE", line 5
ORA-04088: error during execution of trigger 'JACK.TAIUDR_SALGRADE'
 

The above method is one possible solution to Mutating problem.

The following section provides more in depth details about this mutating problem and some other possible solutions and workarounds:

ORA-4091 Mutating Table Explanation and Workarounds

The purpose of this explanation is to illustrate to those customers who require one of the following functional capabilities whilst being able to maintain referential integrity among objects:

  • Cascade Update
  • Cascade Delete
  • Cascade Insert

For cascade Update and Insert functions, using stored triggers and procedures will result in an ORA-04091 - "Table is mutating" error.

ORA-04091: "table %s.%s is mutating, trigger/function may not see it"
Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.

ORA-04091 is a very common error that occurs with triggers if triggers are not managed properly. A full understanding of triggers will help you avoid that error.

A mutating table is a table that is currently being modified by an update, delete, or insert statement. You will encounter the ORA-04091 error if you have a row trigger that reads or modifies the mutating table. For example, if your trigger contains a select statement or an update statement referencing the table it is triggering off of you will receive the error.

Another way that this error can occur is if the trigger has statements to change the primary, foreign or unique key columns of the table the trigger is triggering from.

If you must have triggers on tables that have referential constraints, the workaround is to enforce the referential integrity through triggers as well.

It must be stressed that this solution should ONLY be used to overcome DML restrictions imposed on triggers in order to maintain referential integrity. Whenever possible it is recommended that normal declarative integrity should be used to maintain foreign key integrity. Enforcing this integrity through stored triggers and procedures will have an effect on performance compared with declarative integrity.

For this solution to work correctly there must be no declarative integrity constraints between objects to enforce the foreign key constraint. The basic principle behind this solution is to suppress the validation checks performed as a result of inserting or updating a foreign key in the CHILD table triggered by a cascade Update or Insert. These checks would normally verify the existence of the new foreign key value in the PARENT record (by SELECTING from the parent table). The suppression of this check is only carried out as a direct result of Cascade Update or Delete, as we can be confident that this new value for the foreign key in the CHILD record does exist (i.e. a result of it being inserted or updated in the PARENT table). In all other circumstances no suppression will take place (e.g. when changing the DEPTNO of an employee or when inserting a new employee).

The following code illustrates how this is achieved for the cascade Update scenario, the code can easily be modified to add the other functionality and encapsulate it all within the same package. The EMP and DEPT table have been used, with the column EMP.DEPTNO in the EMP table referencing DEPT.DEPTNO in the DEPT table.



Conceptual Model

 -------------  1. Trigger on PARENT for cascade function
 |           |       SET global_variable = 'NO';
 |  PARENT   |           do cascade update;
 |           |       SET global_variable = 'YES';
 -------------     End;
       |                              -------------------
       |                              | GLOBAL_VARIABLE |
       |                              -------------------
      /|\
 ------------  2. Trigger on CHILD to maintain referential integrity
 |          |       CHECK global_variable;
 |  CHILD   |           IF global_variable = 'YES' THEN
 |          |              check existence of (fk) in PARENT;
 ------------           ELSE
                           null;
                  End;

EXAMPLE:

Oracle does not allow you the reading of a mutating table in a row trigger as it may lead to consistent data.

Attempt to do so, results in the following error:

ORA-04091 Table %s.%s is mutating, trigger/function may not see it

However, this operation can be performed within a statement trigger.

One way to work-around the mutating error within a row level trigger is to use a package PL/SQL table to store ROWIDs of updated records in a row trigger, and reprocess the updated records in a statement trigger.

Solution

Note that there are concurrency issues with this if more than one session tries to perform operations simultaneously. This is not intended as a total solution, but as the framework to help show one option.


The following is the sample work-around that used the EMP table.

Create the package to define the objects that will house the data.

create or replace package emp_pkg as
type emp_tab_type is table of rowid index by binary_integer;
emp_tab emp_tab_type;
emp_index binary_integer;
end emp_pkg;
/


Create the table level trigger to reset the index BEFORE any changes take place.

create or replace trigger emp_bef_stm_all before insert or update or delete on emp
begin
--Remember to reset the pl/sql table before each statement
emp_pkg.emp_index := 0;
end;
/


The following Row level trigger will fire for each row being modified and copy the RowID for each row to the EMP_TAB object defined within the package.

create or replace trigger emp_aft_row_all after insert or update or delete on emp
for each row
begin
--Store the rowid of updated record into global pl/sql table
emp_pkg.emp_index := emp_pkg.emp_index + 1;
emp_pkg.emp_tab(emp_pkg.emp_index) := :new.rowid;
end;
/


The following table level trigger will fire AFTER the others and will print out each RowID affected.

create or replace trigger emp_aft_stm_all after insert or update or delete on emp
begin
for i in 1 .. emp_pkg.emp_index loop
-- Re-process the updated records.
--There is no restriction here.
dbms_output.put_line(emp_pkg.emp_tab(i));
end loop;
emp_pkg.emp_index := 0;
end;
/


In order to see how this work from SQL*Plus, the output must be turned on.

SQL> SET SERVEROUTPUT ON


This first example, displays the RowIDs for Department 20 then issues a DELETE command. The trigger should fire and display the same RowIDs to confirm it is working. (The RowIDs will vary from machine to machine.)

SQL> SELECT ROWID, DEPTNO FROM EMP WHERE DEPTNO = 20;

ROWID DEPTNO
------------------ ----------
AAAM4iAAEAAAAG+AAA 20
AAAM4iAAEAAAAG+AAD 20
AAAM4iAAEAAAAG+AAH 20
AAAM4iAAEAAAAG+AAK 20
AAAM4iAAEAAAAG+AAM 20

SQL> DELETE EMP WHERE DEPTNO = 20;
AAAM4iAAEAAAAG+AAA
AAAM4iAAEAAAAG+AAD
AAAM4iAAEAAAAG+AAH
AAAM4iAAEAAAAG+AAK
AAAM4iAAEAAAAG+AAM

This second example, displays the RowIDs for Department 10 then issues an UPDATE command. The trigger should fire and display the same RowIDs to confirm it is working. (The RowIDs will vary from machine to machine.)

SQL> SELECT ROWID, DEPTNO FROM EMP WHERE DEPTNO=10;

ROWID DEPTNO
------------------ ----------
AAAM4iAAEAAAAG+AAG 10
AAAM4iAAEAAAAG+AAI 10
AAAM4iAAEAAAAG+AAN 10

SQL> UPDATE EMP SET JOB='Test' WHERE DEPTNO=10;
AAAM4iAAEAAAAG+AAG
AAAM4iAAEAAAAG+AAI
AAAM4iAAEAAAAG+AAN

3 rows updated.

To rollback the changes, issue the Rollback command.

SQL> ROLLBACK;

Rollback complete.

CONCLUSION :
 

The above methods are not submitted as solutions to all cases, however, those are provided as some of the possibilities for the Mutating problem. By following the above examples and customizing them to the individual needs , these Mutating problems can be avoided or fixed.


Tuesday, April 22, 2008

ORA-12154: TNS:could not resolve the connect identifier specified - Oracle Error

ORA-12154: TNS:could not resolve the connect identifier specified - ORA-12154 Error/ Oracle Error

Cause: A connection to a database or other service was requested using a connect identifier, and the connect identifier specified could not be resolved into a connect descriptor using one of the naming methods configured. For example, if the type of connect identifier used was a net service name then the net service name could not be found in a naming method repository, or the repository could not be located or reached.

Action:

- If you are using local naming (TNSNAMES.ORA file):

o Make sure that "TNSNAMES" is listed as one of the values of the NAMES.DIRECTORY_PATH parameter in the Oracle Net profile (SQLNET.ORA)

o Verify that a TNSNAMES.ORA file exists and is in the proper directory and is accessible.

o Check that the net service name used as the connect identifier exists in the TNSNAMES.ORA file.

o Make sure there are no syntax errors anywhere in the TNSNAMES.ORA file. Look for unmatched parentheses or stray characters. Errors in a TNSNAMES.ORA file may make it unusable.

- If you are using directory naming:

o Verify that "LDAP" is listed as one of the values of the NAMES.DIRETORY_PATH parameter in the Oracle Net profile (SQLNET.ORA).

o Verify that the LDAP directory server is up and that it is accessible.

o Verify that the net service name or database name used as the connect identifier is configured in the directory.

o Verify that the default context being used is correct by specifying a fully qualified net service name or a full LDAP DN as the connect identifier

- If you are using easy connect naming:

o Verify that "EZCONNECT" is listed as one of the values of the NAMES.DIRETORY_PATH parameter in the Oracle Net profile (SQLNET.ORA).

o Make sure the host, port and service name specified are correct.

o Try enclosing the connect identifier in quote marks. See the Oracle Net Services Administrators Guide or the Oracle operating system specific guide for more information on naming.

This Oracle error ORA-12154 is thrown during the logon process to a database. This ORA-12154 error indicates that the communication software in Oracle ( SQL *Net ) did not recognize the host/service name specified in the connection parameters.

For a database name to be recognized, it must be resolved by Oracle Client. To resolve a name, Oracle client uses either a TNSNames.ora, A Directory Server or an Oracle Names Server.

ORA-12154: TNS:could not resolve service name - ORA-12154 Error / Oracle Error

If the cause for this Oracle error is Oracle Net could not locate the net service name specified in the tnsnames.ora configuration file the perform the following steps to resolve this ora error / tns error:

· Verify that a tnsnames.ora file exists.

· Verify that there are not multiple copies of the tnsnames.ora file.

· In the tnsnames.ora file, verify that the net service name specified in your connect string is mapped to a connect descriptor.

· Verify that there are no duplicate copies of the sqlnet.ora file.

· If you are using domain names, verify that your sqlnet.ora file contains a NAMES.DEFAULT_DOMAIN parameter. If this parameter does not exist, you must specify the domain name in your connect string.

· If you are not using domain names, and this parameter exists, delete it or disable it by commenting it out.

· If you are connecting from a login dialog box, verify that you are not placing an "@" symbol before your connect net service name.

· Activate client tracing and repeat the operation.

If the cause for the ORA-12514 Oracle error is " Oracle Net could not locate the database service name or net service name specified in the directory server" then perform the following steps for resolving this ora error or tns error:

· Verify that the database service or net service name entry exists in the directory that this computer was configured to use.

· Verify that the sqlnet.ora file includes the following entry:

· NAMES.DIRECTORY_PATH=(ldap, other_naming_methods)