Saturday, May 31, 2008

ORA-02019: connection description for remote database not found

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

ORA-02019: connection description for remote database not found
This error can be seen when you specify a nonexistent or mistyped database link name or when invoking a synonym that points to an object containing a nonexistent database link.

As the former case is trivial, let's look at the latter:

say you have a db link called remote_db:
CREATE SYNONYM remote_table_a FOR table_a@remote_db;

then at a later time you drop the db link (supposing the connection closed, otherwise you'll get ORA-02018):
DROP DATABASE LINK remote_db;

now, when you attempt to run a query on remote_table_a, you get:

ORA-02019: connection description for remote database not found
Clearly, if you don't know that behind the synonym there is a db link, this error can be puzzling, especially if the synonym is public and the underlying definition has not been created by you...

See message translations for ORA-02019, ORA-02018 and search additional resources.

Thursday, May 22, 2008

ORA-02095: specified initialization parameter cannot be modified

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

You may get the following error message when attempting to execute a statement like:

ALTER SYSTEM SET DB_DOMAIN=yocoya.com SCOPE=SPFILE;

ORA-02095: specified initialization parameter cannot be modified

Certain initialization parameters are not modifiable using ALTER SYSTEM, so the only way to change their value is to perform the following steps:
  1. CREATE PFILE='path to pfile' FROM SPFILE;
  2. save a backup copy of this pfile in case of troubles!
  3. edit the initialization parameter contained in the pfile;
  4. restart the db using the newly created pfile instead of the default spfile: STARTUP PFILE='...';
  5. CREATE SPFILE FROM PFILE='path to file';
  6. restart the db normally, using the default spfile.
How do you if a parameter is modifiable?
If you look at the dynamic view V$PARAMETER, there is a column called ISSYS_MODIFIABLE, if the value of this column is FALSE, then the parameter is not modifiable using ALTER SYSTEM.
You can find a list of modifiable parameters in the Reference Manual (11g, 10gR2, 10gR1).

See message translations for ORA-02095 and search additional resources.

updated June 4: see Graeme's comment.

Tuesday, May 20, 2008

Need to download archived versions of oracle application express?

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

Yesterday i had to install on a PC an old version of Apex or better said, HtmlDB 2.0.
It may sound strange, but if you need to develop a small application basing on an obsolete version and you can't convince the customer to upgrade to the latest one, then you must work with what is available (or find another customer...).
To make things more complicated, i didn't carry with me the CD with the various zip files, so i thought that in the end i could still download the desired version from Oracle's servers.
This proved to be true in the end, but only after some research, because i didn't find any "official" oracle application express archived versions download page, but only some spare links gathered here and there plus some guessing.

Please note that you will need to authenticate yourself using OTN Credentials in order to download these files.

Of course I cannot guarantee that at time of reading these links are still working or that Oracle is willing to allow the downloading of these files through this page forever.
I guess also that you should read and accept the download terms as per Oracle download agreement prior to downloading the software.

At time of writing I couldn't locate a download link for HTMLDB 1.5.
This list of links will be included in the sidebar of oraclequirks for quicker access.
Note that you can already find the links of the related documentation in the sidebar.

PS: clearly i found the official archive page 5 minutes after publishing the posting...
Go to Oracle Apex archived versions page

Updated on May 30 for including version 3.1.1

Wednesday, May 14, 2008

Using an authorization scheme for displaying a friendly "page under construction" message

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

In certain cases it can be useful to prevent users from entering a page while it is being updated or upgraded.
If you are not enthusiastic about the idea of delivering a generic page not found error page then read on.

Yesterday i had to upgrade a single page of a public application: oracle application express makes the life of the workspace administrator very easy from this point of view as it allows to export and import a bunch of components without the need of exporting and importing the whole application.
However the upgrade involved the underlying database objects, so, unfortunately, it was not just a matter of exporting Apex's definitions, but i needed to change the structure of tables, migrate some data and reload a big table from scratch and all these activities took a couple of hours, also because at a certain point an unforeseen problem happened...

In a case like this, if you don't prevent access to the page, the end user may get inconsistent results or obscure application errors while the job is in progress, so you might want to display instead a nicely formatted error message informing the user that the page is temporarily unavailable.



Clearly you may also opt for bringing down the whole application if necessary, but the approach i am suggesting is less drastic and it's tailored for the specific case of updating just a few pages.
Another option is to display a simple notification message across all pages (see the free notifier application...), but in case of an unhandled oracle error, the notification message won't be displayed, so i don't find it really effective in this case.

I'll show you how i created a simple authorization scheme called "UNDER_CONTRUCTION", whose goal was to prevent any user to access the page being updated as long as necessary.
A user attempting to enter this page will read a friendly warning message explaining the situation instead of getting some weird application error and possibly the indication of the time by which the upgrade will be terminated if you are really really cool ;-)

The method works equally well for public applications (no authentication) and for non-public applications, it certainly requires additional work when a page with an existing authorization scheme is involved.
Later on I'll also provide the details for a slightly more refined mechanism.

The steps for achieving this are:
  1. create an authorization scheme called "UNDER_CONSTRUCTION";
  2. pick the Item in expression 1 is NOT NULL scheme type;
  3. write UNDER_CONSTRUCTION in the item1 attribute;
  4. write a proper warning message (see below);
  5. evaluation point set to: once per page view;
  6. create an application item called UNDER_CONSTRUCTION with session protection;
  7. assign this authorization to the relevant page(s);
  8. seed the application if translations exist;
  9. translate the message (*) in versions of Apex later than version 3.1.1;
  10. publish the application (only if step 8 applied).
(*) While i was working on this tip, it turned out that Apex doesn't provide a slot for the translation of the authorization scheme violation message and this has been acknowledged as a bug, that's why i wrote a multilingual message directly. See the following OTN thread for the full story.

Steps 1-6 are only required the first time you use this technique, in the future you only need to repeat steps 7-9 on the desired pages because you don't need to remove these components from the application, you just need to unselect the authorization scheme once you've completed the upgrade.
If the application has been translated, you will need also to seed and publish the mapped applications, otherwise the translated versions may still run the authorization code while the primary language doesn't.

The application item UNDER_CONSTRUCTION must remain empty at all times.

I don't think is a good idea to keep the authorization scheme and initialize this item to re-enable the page for a couple of reasons:

  • users who tried to open the page may still be using the same session ID, which means they could not see the updated item value (depending on how/when you initialize the item).
  • authorization scheme checking requires additional resources, which in the end means slower page loading.

I think it's just much better to deselect the authorization scheme from the page and eventually seed and publish the application, if there are any translations attached.

But what if you want to have exclusive access to the page prior to opening up the doors to everybody?

Note that with some minor changes you may proceed in the following fashion:

  1. define the UNDER_CONSTRUCTION application item as unprotected;
  2. change the scheme authorization type from item in expression1 is NOT NULL, to value of item in expression1 equals expression2;
  3. write a password in expression2.
This will allow you to enter the page by setting the application item from the browser with the given password.
In any case, remember to disable the authorization scheme once the page is working fine.

And the day you need to upgrade another page, you'll have all the necessary tools ready for showing your work in progress friendly message again.

See more articles about Oracle Application Express or download tools and utilities.

Monday, May 12, 2008

ORA-12505:TNS:listener does not currently know of SID given in connect descriptor

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

ORA-12505:TNS:listener does not currently know of SID given in connect descriptor

For an explanation of this error message, refer to the article on ORA-12514.
The main difference lies in the fact that the client is using a SID instead of a service name, hence the returned error message is slightly different.
I've seen this error frequently when trying to connect to a freshly started db using SQL Developer, prior that the instance registered itself with the listener.
Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was: 192.168.1.30:1521:orcl11

Vendor code 0
See message translations for ORA-12505 and search additional resources.

Friday, May 09, 2008

ORA-30653: reject limit reached

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

ORA-29913: error in executing ODCIEXTTABLEFETCH callout
ORA-30653: reject limit reached
You may get this error when selecting from an external table, type ORACLE_LOADER, and you have set the REJECT LIMIT to some numerical value instead of the literal UNLIMITED and, for some reason to be investigated, oracle reached the limit while loading the rows from the file.

First of all you should open the log file associated with the external table, if any.
If the log file is not present because the NOLOGFILE option was specified, it is advisable to redefine the table and specify a valid log file destination.

It's worth spending some more words on the significant differences that you may get with what is to be considered as a rejected record (collected in the .bad file) or as a discarded record (collected into the .dsc file), depending on whether certain keywords are specified or not in the external table definition.
In the end, what matters is that rejected records are those that affect the REJECT LIMIT counter, whilst discarded records (LOAD WHEN) do not affect it.

For instance, a classical problem of row rejection is represented by an empty line of text.

If REJECT LIMIT 0 is specified, then you must handle empty lines in some way, because they will cause rejections causing the failure of the operation. Let's look at the following example:

CREATE TABLE test_ext (
a VARCHAR2(10),
b VARCHAR2(10),
c VARCHAR2(10)
)
ORGANIZATION EXTERNAL
(TYPE oracle_loader
DEFAULT DIRECTORY file_location
ACCESS PARAMETERS
(
RECORDS DELIMITED BY newline
LOAD WHEN ((1:1) != "#")
FIELDS TERMINATED BY ":"
(
a CHAR(10),
b CHAR(10),
c CHAR(10)
)
)
LOCATION ('list.dat')
)
REJECT LIMIT 0
/
Then suppose the content of file list.dat is the text in green color:
#

test:external:table:
Line 2 contains just a newline character, so it will be considered an empty line.
When we attempt to access the table, we get:
select * from test_ext;

ORA-29913: error in executing ODCIEXTTABLEFETCH callout ORA-30653: reject limit reached
In the log file generated (in the folder pointed to by directory FILE_LOCATION), the last lines are:
KUP-04102: record 1 discarded from file ...list.dat
KUP-04021: field formatting error for field A
KUP-04023: field start is after end of record
KUP-04101: record 2 rejected in file ...list.dat
The first message refers to the line beginning with the pound sign (#), that we deliberately discarded by means of the LOAD WHEN clause. The next three lines refer to the empty line. In the end what really matters is that the record was rejected, thereby causing the entire operation to abort because of the reached reject limit.

Now, let's rebuild the table adding a special field definition clause (in green color):
CREATE TABLE test_ext (
a VARCHAR2(10),
b VARCHAR2(10),
c VARCHAR2(10)
)
ORGANIZATION EXTERNAL
(TYPE oracle_loader
DEFAULT DIRECTORY file_location
ACCESS PARAMETERS
(
RECORDS DELIMITED BY newline
LOAD WHEN ((1:1) != "#")
FIELDS TERMINATED BY ":"
MISSING FIELD VALUES ARE NULL
(
a CHAR(10),
b CHAR(10),
c CHAR(10)
)
)
LOCATION ('list.dat')
)
REJECT LIMIT 0
/

select * from test_ext;

A B C
---------- ---------- ----------

test external table

2 rows selected
If you look at the log file, this time there will be only the KUP-04102 message at the bottom.

Now, you might say you don't want null values in your table: piece of cake, just add one more clause:

CREATE TABLE test_ext (
a VARCHAR2(10),
b VARCHAR2(10),
c VARCHAR2(10)
)
ORGANIZATION EXTERNAL
(TYPE oracle_loader
DEFAULT DIRECTORY file_location
ACCESS PARAMETERS
(
RECORDS DELIMITED BY newline
LOAD WHEN ((1:1) != "#")
FIELDS TERMINATED BY ":"
MISSING FIELD VALUES ARE NULL
REJECT ROWS WITH ALL NULL FIELDS
(
a CHAR(10),
b CHAR(10),
c CHAR(10)
)
)
LOCATION ('list.dat')
)
REJECT LIMIT 0
/

select * from test_ext;

A B C
---------- ---------- ----------
test external table

1 rows selected
The last three lines in the log file this time contain:
KUP-04102: record 1 discarded from file ...list.dat
KUP-04073: record ignored because all referenced fields are null for a record
KUP-04049: record 2 discarded from file ...list.dat
Finally it's interesting to note a linguistic quirk, which makes me so happy, as you know:
the log file says record 2 discarded, but the clause we applied is REJECT ROWS...
Indeed the discarded record will be found in the .dsc file, not in the .bad file.

I guess how easily one can be fooled by such terminology where discarded records must be explicitly rejected and rejected records are those automatically discarded... good grief!
:-D

On a subtler level, finally note that in the log file the record discarded owing to REJECT ROWS clause is marked by code KUP-04049, whereas the record discarded because it doesn't match the LOAD WHEN condition is marked by code KUP-04102.

See message translations for ORA-30653 and ORA-29913 and search additional resources.

Wednesday, May 07, 2008

Extracting nodes belonging to different namespaces

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

As soon as i posted the previous article on the error caused by a missing namespace string parameter in the call to EXTRACT (or EXTRACTVALUE or UPDATEXML), a subliminal question started buzzing in my head.

What happens if i need to extract node(s) whose XPath expression contains elements belonging to different namespaces?
More precisely, how does the namespace parameter look like in such SQL expression?

The answer, fortunately, was found at the first attempt.
Let's take the same document used previously:


select extractValue(
xml_content,
'/feed/openSearch:totalResults',
'xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns="http://www.w3.org/2005/Atom"') val
from xml_documents
where id = 38;

VAL
---
175
As you can see the feed element has a default namespace (no prefix) matched by the blue string and the totalResults element, prefix openSearch, is matched by the green string. Both namespaces appear inside the same string (the famous third parameter of EXTRACT or EXTRACTVALUE), separated by a blank.

I guess one can generalize the namespace syntax as follows:
'xmlns[:prefix]="namespace1" [xmlns[:prefix]="namespace2"] [xmlns[:prefix]=...]'

Specifying the default namespace (sting in purple color in the document above) in the SQL/XML expression is necessary, if you don't do that, you'll get NULL as result:
select extractValue(
xml_content,
'/feed/openSearch:totalResults',
'xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"') val
from xml_documents
where id = 38;

VAL
---
(null)

LPX-00601: Invalid token in 'XPath expression'

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

You can get this error while attempting to extract nodes containing a namespace prefix using a SQL expression like the following:

select extractValue(
xml_content,
'//openSearch:totalResults') val
from xml_documents
where id = 38;

ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00601: Invalid token in: '//openSearch:totalResults'
The problem is caused by the missing namespace parameter in the function call:

select extractValue(
xml_content,
'//openSearch:totalResults',
'xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"') val
from xml_documents
where id = 38;

VAL
---
175
Clearly the namespace declaration in green, must match the corresponding string in the source XML document.
Note also that Oracle uses double quotes to enclose the string whereas single or double quotes might be used in the source document indifferently, what really matters is the string delimited by the quotes and do not forget that is case sensitive: a mismatching string will cause a null value to be returned instead of the expected node.

See a previous posting on problems related to default namespaces declarations and Oracle XML functions.

Oracle's XML SQL functions and the default namespace

Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.

Although I've been developing applications that make extensive use of XML for years, yesterday i was really amazed when i discovered that Oracle functions like EXTRACT and EXTRACTVALUE return a null value when the document being handled includes a default namespace declaration in the topmost element (see the purple string in the document sample below) and you do not explicitly specify this namespace as the third parameter for these functions.

Let's take a sample RSS XML document (many elements omitted for clarity):


select extractValue(xml_content,'/feed/title') title
from xml_documents
where id = 38;

TITLE
------
(null)

How can it be? i can see the title element right there below the feed element!

To make things worse, add up to the picture that the documentation for Oracle (up until 11gR1) is not so clear on this point but you might think that in the end it's just a matter of looking at some examples given in the SQL reference, however you may easily see yourself that the examples for EXTRACT and EXTRACTVALUE do not show the usage of the third parameter and the syntax diagram merely says "namespace string", without giving any insight on the real syntax of this value. Actually, finding a working example in the official documentation is not so straightforward as you need to go to the search page and review all the examples given for the EXTRACT function in the XML set of books, until you find the good one...

As a consequence, initially, i thought it would be enough to specify the namespace string, but all i got was

select extractValue(xml_content,'/feed/title','http://www.w3.org/2005/Atom') title
from xml_documents
where id = 38;

ORA-31013: Invalid XPATH expression.
At this point i was even more puzzled because even if i got this rather misleading error message, i had the feeling that the culprit was an incorrectly specified namespace string, so i set out on the web in pursue of some working example.

After some research i finally encountered an OTN forum posting where this phantom parameter was eventually specified, so i adapted the example for my case:
select extractValue(xml_content,'/feed/title','xmlns="http://www.w3.org/2005/Atom"') title
from xml_documents
where id = 38;

TITLE
------------------------------------
Annals of Oracle's Improbable Errors
So, finally we got it, but notice the peculiar syntax (in green and blue) and the double enclosing quotes around the namespace string.
At least we can now draw a preliminary conclusion, the namespace string syntax for EXTRACT, EXTRACTVALUE and UPDATEXML is the following:
'xmlns[:prefix]="namespace"'
and in the case of a default namespace there is no prefix.

You may wonder, as i did, why you never came across this problem before today.
May be i always dealt with XML documents without a default namespace declaration like those spawned by Oracle Application Express for instance, when you unload a table in XML format.
Such documents do not pose any problems to the EXTRACT or EXTRACTVALUE functions, so you may live well for years ignoring the namespace parameter.

Note also that a tool like XMLSpy does not ask you to specify a default namespace, for the simple reason it is considered a default value, so, when you specify an XPath expression like /feed/title, it assumes that the elements without a prefix belong to the default namespace.
This situation may easily lead to some confusion if you try out such XPath expression in XMLSpy first and then you use it inside an Oracle XML/SQL expression returning nothing.

I can't say if the behavior depends on a strict interpretation of the XML specification, at any rate it's somewhat curious that one is forced to specify a supposedly default value.

yes you can!

Two great ways to help us out with a minimal effort. Click on the Google Plus +1 button above or...
We appreciate your support!

latest articles