Today Joseph was creating a windows service, which had an schedule task to execute something on an Oracle Server.
Everything worked out of the Windows Service but as soon as he added it to the Windows Service, it fail.
He suspected it had something to do with the 64 bit platform so he made sure to compile for AnyCPU, but it did not work...
Answer: It was the OracleClient fault. The OracleClient for ADO.NET do not work for AnyCPU. You need to use the 64 or 32 bit version.
Out of the blue, I just started getting this obnoxious exception. Why?? Why meeeeeee!!
Another weird thing is that is was only from my test server. Again Why?>>> Why Meeee!!!
In general when I executed some stored procedures or performed select staments againts the
Oracle database I just got that exception.
ORA-01843: not a valid month
CAUSE:
The source of the problem is that when a table has a date stored in a format that the client is not able
to understand due to format differentes it will throw this message.
For example, if the table is storing dates like ‘DD-MM-YY’, (that is day-month-year european format)
and the client tries to read the date as ‘MM-DD-YY’ or viceversa. In this case we can see that the
month number is confused with the day and it is very likely that there will be dates with a month value
bigger that 12.
SOLUTION:
The solution to this problem is to tell the client the right format to use for dates. This is part of the session values
in oralce. Part of those values can be queries with the following statement:
select * from nls_session_parameters
In the query results, we can see the value of the NLS_DATE_FORMAT that is being used by the client.
You can take several actions.
1. If you are just performing a query on SQL PLUS and is just an isolated query you can just change that value for
your current session by executing:
alter session set NLS_DATE_FORMAT=’DD-MM-RR’
This will take effect ONLY for the actual session. In this example we can see that the format is being changed to
‘day-month-year’. The RR, indicates the year.
2. If you want a more permanent change or at least something that applies to all your session. You can:
2.1. Create an After Logon Trigger something like:
CREATE OR REPLACE TRIGGER LOGINTRG AFTER LOGON ON DATABASE
BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''DD-MM-RR'''; END LOGINTRG;
2.2. Option 2. Go to the Registry and locate
\\HKEY_LOCAL_ MACHINE\SOFTWARE\ORACLE\KEY_HOMENAME\
For example in my case it was
\\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0
And create an String Key called NLS_DATE_FORMAT and set it to DD-MM-RR
Today I had an stored procedure defined in a package and I didn’t know how to call it.
And my stored procedure returned a cursor and I needed to see the results.
So after some tests this is the way to perform this. You can use code like the following:
variable r refcursor -- use this if you have an out parameter that is an out cursor
DECLARE
-- Declare a variable for each of your stored procedure arguments
VAR_IN_1 VARCHAR2(32767);
VAR_IN_2 VARCHAR2(32767);
VAR_IN_3 VARCHAR2(32767);
INFO sys_refcursor;
BEGIN
-- Init the variables with the parameter you want to use to test the stored procedure
VAR_IN_1 := 'Param1';
VAR_IN_2 := 'Param2';
VAR_IN_3 := 'Param3';
-- Call the stored procedure. You should write something like schema.package.storedprocedure( param1, param2, ..., paramN);
MYSCHEMA.PKG_TEST.TEST_STORED_PROC ( VAR_IN_1, VAR_IN_2, VAR_IN_3, INFO );
-- If one of the parameters was an out cursor assign it to the r variable to be able to see the results
:r := PC_INFO;
COMMIT;
END;
-- Execute this code in SQL PLUS
And after executing it just call in the SQL PLUS prompt
PRINT r to see cursor results
This is an useful script taken from: http://dbaforums.org/oracle/index.php?showtopic=16834 which provides a list of the currently
open sessions.
To track if you application is having problems releasing connection you can open the SQLPlusW and run this script
a couple of times while you exercise your application.
set line 150;
ttitle "dbname Database|UNIX/Oracle Sessions";
set heading off;
select 'Sessions on database '||substr(name,1,8) from v$database;
set heading on;
select
substr(a.spid,1,9) pid,
substr(b.sid,1,5) sid,
substr(b.serial#,1,5) ser#,
substr(b.machine,1,20) computer,
substr(b.username,1,10) username,
-- b.server,
substr(b.osuser,1,8) os_user,
substr(b.program,1,30) program
from v$session b, v$process a
where
b.paddr = a.addr
and type='USER'
order by spid;
ttitle off;
spool off;
This will provide an output like:
I had a Windows Server 2003 and I was trying to connect to Oracle with the System.Data.OracleClient provider.
I was able to connect from a console application but not from ASP.NET.
From ASP.NET I only got ORA-12154 errors.
I found that on Windows 2003 Server, ASP.NET applications run in the
security context of the “Network Service” user.
So I tried these two things:
I first started following these steps:
1. Log on to Windows as a user with Administrator privileges.
2. Launch Windows Explorer from the Start Menu and and navigate to the
ORACLE_HOME folder. It is usually under the oracle instalation folder.
In my case that is C:\oracle\product\10.2.0\client_1
3. Right-click on the ORACLE_HOME folder and choose the "Properties" option
from the drop down list. A "Properties" window should appear.
4. Click on the "Security" tab of the "Properties" window.
5. Click on "Authenticated Users" item in the "Name" list (on Windows XP
the "Name" list is called "Group or user names").
6. Uncheck the "Read and Execute" box in the "Permissions" list under the
"Allow" column (on Windows XP the "Permissions" list is called
"Permissions for Authenticated Users").
7. Re-check the "Read and Execute" box under the "Allow" column (this is
the box you just unchecked).
8. Click the "Advanced" button and in the "Permission Entries" list make
sure you see the "Authenticated Users" listed there with:
Permission = Read & Execute
Apply To = This folder, subfolders and files
If this is NOT the case, edit that line and make sure the "Apply onto"
drop-down box is set to "This folder, subfolders and files". This
should already be set properly but it is important that you verify this.
9. Click the "Ok" button until you close out all of the security properties
windows. The cursor may present the hour glass for a few seconds as it
applies the permissions you just changed to all subfolders and files.
10. Reboot your computer to assure that these changes have taken effect.
(I thought that rebooting was not that important but it seems that you have to reboot to make changes effective)
It sometimes happens that it is not enough, because it seems that some oracle installations need the
the ASP.NET process to run with an account with sufficient privileges.
The second thing you can do in that case is.
1. First open the machine.config file. That will be usually in %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config
2. Look for something like:
<system.web>
<processModel autoConfig="true" />
3. Add the userName=”System” attribute. For example
<processModel autoConfig="true" userName="System" />
4. Restart the IIS.
Linc\EAE used profiles for their queries. Well the profile information is used by our migration tool to generate indexes.
In Java is easy to intercept all SQL statements used by the translated application and analyze them.
To analyse how a query is executed you have to study its explain plan. For go here an excellent guide on EXPLAIN PLAN.
After you read that page, you will find useful the following function, that will shorten the lines that you have to type to see the explain plan:
create OR REPLACE function ShowPlan return sys_refcursor
as
c_test sys_refcursor;
BEGIN
open c_test for select
substr (lpad(' ', level-1) || operation || ' (' || options || ')',1,30 ) "Operation",
object_name "Object"
from
sys.plan_table$ start with id = 0 connect by prior id=parent_id;
return c_test;
END;
SQL>
explain plan for select * from MY_TABLE
SQL> variable rc refcursor
SQL> exec :rc := testfunc()
PL/SQL procedure successfully completed.
SQL> print rc
Operation Object
------------------------------ ------------------------------
SELECT STATEMENT ()
TABLE ACCESS (FULL) MY_TABLE
When we migrate from LINC/EAE to Oracle, the migration tool generates an schema an tables form the original ISPECS.
I came across with the problem that I had been playing around with a test database and I didn’t know who was the owner of the table.
Well just as a reminder this is what is needed:
select owner, table_name, tablespace_name from dba_tables where table_name='YOUR_TABLE';
This will return something as:
OWNER TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------ ------------------------------
THE_OWNER MY_TABLE USERS
If you have to write stored procedures for oracle is important
to notice which Java version is supported by your Oracle Database,
A common technique is create a JAVA stored procedure for that:
1. Create a function with an ORACLE SQL statement like:
CREATE OR REPLACE FUNCTION getJavaProperty(myprop IN VARCHAR2)
RETURN VARCHAR2 IS LANGUAGE JAVA
name ‘java.lang.System.getProperty(java.lang.String) return java.lang.String’;
2. Once you created the function you can use it to get the version:
SELECT getJavaProperty(‘java.version’) from dual;
You can see in the attached version that for my Oracle Database 10.1.0.4.2 the Java version is 1.4.2_04 :)
Microsoft announced that they won’t support the System.Data.OracleClient anymore :(
The message says that it will still be available in .NET 4.0 but “deprecated” and that it wont impact existing applicatoions.
So what are my options?
Well you have to go to a third party. Not now but eventually.
Oracle Data Provider for .NET (ODP.NET) (Oracle states that ODP.NET is Free)
DataDirect ADO.NET Provider for Oracle
dotConnect for Oracle
Migration to ODP.NET
Installation
Microsoft OracleClient to ODP.NET Application Migration: Code Migration
Oracle provide general instructions. In summary you need to:
- Add the references to Oracle.DataAccess
- Change namespaces: System.Data.OracleClient by Oracle.DataAccess.Client; and maybe add “using Oracle.DataAccess.Types”
- Update the connection String (most attributes are the same). Change Integrated Security by "User Id=/", change “Server” attribute to “Data Source” and remove Unicode
- The following is anoying but you have to add after all OracleCommands something like OracleCommand1.BindByName = true;
Deployment
- Oracle Universal Installer (either in normal installation or Silent Install)
- XCopy (I like this :) ) just remember to download the ODAC xcopy version
If you have created any schedule jobs or you just need to see what jobs are available in a server you use the dba_jobs table.
The following links provides more details about this view: http://www.praetoriate.com/data_dictionary/dd_dba_jobs.htm