Make Oracle last_day function be compatible with H2 database - oracle

I am writing integration testing and I want to test my sql queries by using a H2 database. In production these queries are running against an Oracle database.
I have to run this query
I have tries to use the compatibility mode
SELECT last_day(MY_CURRENT_DATE) from MY_TIME
by using the oracle compatibility mode jdbc:h2:mem:default;MODE=Oracle;DB_CLOSE_DELAY=-1 but I receive this error:
org.h2.jdbc.JdbcSQLException: Function "LAST_DAY" not found; SQL statement:
SELECT last_day(MY_CURRENT_DATE) from MY_TIME [90022-176]
It just seems that the compatibility mode does not cover the vendor-specific functions.
I have an idea how to solve this in testing. Just override the Oracle last_day function with a H2 user-defined function:
DROP ALIAS IF EXISTS last_day;
CREATE ALIAS last_day AS $$
String last_day(java.sql.Connection con, Date date) throws Exception {
//get the last day of month
}
}
$$;
But I am wondering if it is the best idea?
Is there a way to re-write the Oracle LAST_DAY function (that calculates the last day of month) in a way which is compatible with all other databases (including H2)?

It is clear for me that for acceptance/system tests you should use a database very similar to the one in production.
For the integration and unit testing you can mock the database server component entirely.

Related

How BusinessObjects parses date string on Oracle database behind

Looking into a query in WebIntelligence, after running, the prompts are replaced by values provided by user (for instance dates).
When I run the same query on Oracle (because this database I use for my universe) I’m getting error in terms of dates. Dates in query (in BO) are just strings,
like StartDate = '30-06-2020 00:00:00′. When I run the query generated in WebIntelligence on Oracle I’m getting error:
ORA-01843: not a valid month
01843. 00000 – ” not a valid month”
And to fix this I need to use for instance to_date function and then it’s working fine. My question is: how dates are parsed in WebIntelligence while running a query?
so the mentioned error does not occur?
I am getting the same error as you when I try a query directly against Oracle using SQL Developer that works in Web Intelligence. According to this BusinessObjects makes a call to set the date format.
So you can do that either in the preferences of SQL Developer (or presumably whatever database query tool you are using) or explicitly setting it with the alter session command.
alter session set nls_date_format = 'DD-MM-YYYY HH24:MI:SS';
select...[the rest of your query]
Both options are shown in the answer to How can I set a custom date time format in Oracle SQL Developer?.

Jasper report with 2 differents databases (Oracle and postgresql)

I'm here to ask for your help, so my probleme is:
I have created report with jasperrerport 3.7.6 (queries based on oracle).
and now I'm trying to use the same report with PostgreSql Database and I'm getting errors for specific oracle functions like (NVL, sysdate ...), and I don't want to change the query for now (unless I have to).
Is there any thing to use to make autoconversion when executed on a postgresql database?
If there are no matching functions in both databases, consider creating your own functions which will "simulate" the originals.
For example, for Oracle's SYSDATE:
create or replace function f_sysdate return date is
begin
return sysdate;
end;
I don't know PostgreSQL, but - you'd do the same in that database. Function's name must be the same: F_SYSDATE.
Then, in JasperReports, instead of calling "originals", you'd call your own functions, e.g.
select ename, job, sal,
f_sysdate --> this
from emp
where deptno = 10
Doing so, report would work in both databases. True, you'd have to put some initial effort, but - it might pay off in the future.

How to use getDate() in h2 as like sql server

I'm testing the already developed application through Junit test cases, uses SQL server in production but while executing test cases we used embedded h2 database.
And some of the SQL server specifications are not working in h2 (ex: conditional queries, getDate(), DATEPART,..........) can anyone help me how to tackle this kind issues further in my JUnit testing with h2 DB
SQL SERVER: select * from getDate() -: 2006-12-30 00:38:54.840
h2 DB : select * from getDate() -: 2006-12-30
While executing test cases that scripts are executing in h2 database and as a part of logic, I'm parsing the value from getdate() into SimpleDate format of 2006-12-30 00:38:54.840, and I'm getting parse exception that 2006-12-30 couldn't parse.
Thanks in Advance
To use getDate in H2, simply run the following query before using a query with getDate()
drop alias if exists getDate;
create alias getDate as '
java.util.Date getDate() {
return new java.util.Date();
}
';
You can use User-Defined Functions and Stored Procedures built in H2 database.

Upgrading from ojdbc6/jdk6 to ojdbc8/jdk8 has broken TIMESTAMPTZWrapper. Cannot cast TIMESTAMPTZWrapper to TIMESTAMPTZ

We have recently uplifted a major application that was written under JDK6 using ojdbc6 against an 11g Oracle database. It was uplifted to use JDK8 against the same 11g database, but we were also in the midst of upgrading to 12c. The uplifted code has been running in production against the 11g database, but slower than it was before. Against the 12c database in our QA environment, we're noticing jobs either throwing exceptions or running VERY slow. When I looked at the code, I noticed that the project team assigned to uplift the code failed to upgrade the ojdbc from 6 to at least 8. I have since done that work, but now we are getting errors from submitting the following code:
Calendar endModDate = Calendar.getInstance();
// get the timestamp from the db
Query qry = em.createNativeQuery("select SYSTIMESTAMP from dual");
TIMESTAMPTZWrapper tsTZWrapper = (TIMESTAMPTZWrapper)qry.getSingleResult();
The em is our entity manager. But when the code calls the qry.getSingleResult() member function, we get this error:
oracle.sql.TIMESTAMPTZ cannot be cast to org.eclipse.persistence.internal.platform.database.oracle.TIMESTAMPTZWrapper
I've searched high and low for an answer, and anything that resembles an answer doesn't appear to fix my solution. This same logic is used in one other area of the code and produces the same issue. If we switch back to ojdbc6, it then works but we can't use ojdbc6 (and we really shouldn't since we're on jdk8) since we need to upgrade to Oracle 12c in the coming month.
Thanks for any assistance in this matter.
Just quick comment about TIMESTAMP datatype:
There is a bug in JDBC drivers "Bug 21891493 : JDBC SENDS TIMESTAMP SCALE OF NULL WHEN NANOSECONDS ARE ZERO", which can cause creation of excessive number child cursors in Oracle database. This bug was fixed in 12.2 JDBC drivers.
The datatype TIMESTAMP WITH TIMEZONE uses internally a function to convert the this into GMT. When you create an index on it, in some cases this function based index is not used, especially when you compare this column with TIMESTAMP value of different subtype. You should compare exec plans between 11g and 12c.

How to rewrite Oracle specific function TO_NUMBER to ANSI SQL

There is a legacy software running against an Oracle database. I'm trying to generalize it for Docker tests, so I prepared a PostgreSQL image with the database schema. Now I'm trying to run that application against the Postgres DB, but there is the following error:
org.postgresql.util.PSQLException: ERROR: function to_number(text) does not exist
So I looked into the code and found the following construct in some selects:
to_number(to_char({0},'HH24MI')) <= to_number(to_char({1},'HH24MI'))
to_number(to_char({0},'HH24MI')) > to_number(to_char({1},'HH24MI'))
Since I'm not a database specialist, I assume that this TO_NUMBER is an Oracle-specific function. In this case it works as a filter to return records for the specified time range.
Is there a way how could I simply replace this TO_NUMBER function with some similar function in ANSI SQL?
Instead of the Oraclism
to_number(to_char(current_timestamp, 'HH24MI'))
you could use this standard SQL construct:
100 * EXTRACT(HOUR FROM current_timestamp)
+ EXTRACT(MINUTE FROM current_timestamp)

Resources