Oracle TNS Listener service not starting

Whenever I tried to start my local TNS Listener service, OracleOraDb10g_home1TNSListener, I would get an error like this.

The OracleOraDb10g_home1TNSListener service on Local Computer started and then stopped. Some services stop automatically if they have no work to do, for example, the Performance Logs and Alerts service.

This forum thread, Can’t start Oracle service, suggested I do the following to diagnose the problem.

  1. cmd
  2. lsnrctl
  3. start

This worked and I saw the following error which showed my Oracle install had not been properly done, the listener was pointing to the wrong server.

LSNRCTL> start
System parameter file is
  C:\oracle\product\10.2.0\db_1\network\admin\listener.ora
Error listening on:
  (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=bad.betweengo.com)(PORT=1521)))
TNS-12545: Connect failed because target host or object does not exist
 TNS-12560: TNS:protocol adapter error
  TNS-00515: Connect failed because target host or object does not exist
    32-bit Windows Error: 1004: Unknown error

In C:\oracle\product\10.2.0\db_1\network\admin\listener.ora the listener is improperly configured for bad.betweengo.com.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = bad.betweengo.com)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
  )

I ran Oracle’s Net Configuration Assistant and updated the Listener configuration which fixed the above listener to point to my server. Now C:\oracle\product\10.2.0\db_1\network\admin\listener.ora points correctly to good.betweengo.com.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = good.betweengo.com)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
  )

Listing All Tables

With MySQL listing all the tables in a database is easy enough.

mysql> show tables;

With Oracle it’s a little less straight-forward.

> select table_name from user_tables;

OR

> select * from user_objects where object_type = 'TABLE'; 

OR

> select table_name from tabs;

OR

> select table_name from all_all_tables;

Debugging a Category’s Bad Child Products

Today I was using the CategoryLookup droplet to find a category’s child products. However when I accessed the child products I would get this JDBC error.

java.lang.NullPointerException
at java.lang.String.(String.java:166)
at oracle.sql.CharacterSet.AL32UTF8ToString(CharacterSet.java:1517)

I realized my product data was corrupted. However this category had over 70 child products. The stack trace wasn’t telling me which one was corrupt and going through each child product to find out which one was corrupt was too painful.

I first queried the database to find all the child product ID’s.

SQL> select child_prd_id from dcs_cat_chldprd where category_id='cat101' order by sequence_num;

I then created a simple JHTML page which would query each child product and output which ones were corrupted.

<java>
final String [] product_ids = { "prod101", "prod102", "prod103" };

for (int ii = 0; ii < product_ids.length; ii++) {
out.print(ii + ". [" + product_ids[ii] + "] ");
try {
</java>
<droplet name="/atg/commerce/catalog/ProductLookup">
<param name="id" value="`product_ids[ii]`">
<oparam name="output">
<valueof param="element.displayName"/><br/>
</oparam>
</droplet>
<java>
} catch (RuntimeException exc) {
out.println(exc + "<br>");
}
}
</java>

Once I knew which child products were bad I removed their mappings to the category in dcs_cat_chldprd.

SQL> delete from dcs_cat_childprd where child_prd_id = 'prod102' and category_id='cat101';

Then I updated the sequence numbers so that they are all consecutive by moving the ones at the end to fill the holes created by the previous deletes.

SQL> update dcs_cat_childprd set sequence_num = 1 where child_prd_id = 'prod103' and category_id='cat101';

Retrieving the Source from the Database

Sometimes I am faced with a situation where I need to know the source for a view or a procedure or a function. Fortunately Oracle stores the source in the database.

First I check to see what kind of object whose source I need is.

SQL> select object_name,object_type,status from user_objects where object_name = 'FOO';

If the object is a table I can simply recreate the table by doing a desc on that object.

SQL> desc FOO;

If the object is a function or stored procedure you can find its source in the user_source table.

SQL> select text from user_source where name = 'FOO' order by line;

If the object is a view you can find its source in the user_views table.

SQL> select text from user_views where view_name = 'FOO';

If the output seems to be truncated it is because text is of type LONG which is a big binary field. To allow more output do this.

SQL> set long 4000

Thanks to this article and this forum for helping me figure this out.

Determining Permissions for a User

SQL> select privilege from user_tab_privs where lower(table_name)=’t_foo’ and lower(grantee)=’frank’;

PRIVILEGE
—————————————-
UPDATE
SELECT
INSERT
DELETE

SQL> select * from user_role_privs;

USERNAME GRANTED_ROLE ADM DEF OS_
—————————— —————————— — — —
FRANK AQ_ADMINISTRATOR_ROLE NO YES NO
PUBLIC SELECT_CATALOG_ROLE NO YES NO

Inserting a text value with special characters

To insert a text value with an ampersand, e.g. AT&T, one can do something like this.

insert into foo values(‘AT’||Chr(38)||’T’)

To learn more see How does one disable interactive prompting in SQL*Plus?

To insert a text value with a single quote, e.g. Don’t do it, one can do something like this.

insert into foo values(‘Don”t do it’)

To learn more see How does one escape special characters when building SQL queries?

Catching Oracle exceptions

Oracle SQL queries can throw exceptions. For example in this query f there is no data then Oracle will throw a NO_DATA_FOUND exception.

SELECT status_date INTO v_status_date FROM member WHERE member_id = p_member_id_in;

ORA-01403: no data found

If this query is part of a stored procedure and is called from Hibernate you will get this uninformative exception.

org.hibernate.exception.DataException: could not execute query

Oracle SQL, like many languages, has a try catch construct. In this example you could do the following.

BEGIN
  SELECT status_date INTO v_status_date FROM member WHERE member_id = p_member_id_in;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    v_status_date := NULL;
END;

Calling Oracle Stored Procedures and Functions

Calling an Oracle function is quite simple. For example

SELECT package.register(1, "Frank", "Kim") FROM dual;

However calling Oracle stored procedures is a bit more tricky, especially if the Oracle stored procedure has output parameters. Here is an example of how to call an Oracle stored procedure that has three input parameters and two output parameters.


DECLARE p_credit_status_out INTEGER;
p_school_status_out INTEGER;

BEGIN
package.get_status(1, "Frank", "Kim", p_credit_status_out, p_school_status_out);
END;
/