Our large application (VB.Net, Framework 3.5) has been developed more or less from the start to use SQL Server, and SQL Server only. Of course one day someone sold it to a client with the promise we could make it work on Oracle (10g and above), and it now does, but we have considerable performance issues.
This stems from the fact that nearly all the SQL (contained in the app code) is in parametrized queries of the form
SELECT Col1, Col2, Col3 FROM TableName WHERE IdCol = @EntityId
This is then passed to our data access layer along with an array of parameter names, an array of types and an array of values and is then executed using Enterprise Library 5 to handle the actual connections and so on.
When this project started, someone realised that Oracle requires parameters in the form
:EntityId
and decided that rather than trying to find and re-write every bit of SQL (this app alone has about a million LOC and there are others in the suite) they would add a function which is called just before the query is executed that replaces @ with : in both the query and the parameter names array. It also removes ‘WITH NOLOCK’, square brackets and replaces concatenation characters and other such artefacts that SQL Server uses but which Oracle doesn’t. The problem with that of course is that string searching and replacing is expensive and at one point in a simple action in the app more than 2,000 simple queries are executed sequentially. Against SQL Server this takes no time at all, but against an Oracle platform it is taking 20-30 seconds.
Ideally I’d like to re-write huge reams of code to weed out poor/inefficient code and design and fix up dodgy architecture and replace the lot with nHibernate or Entity Framework. But that isn’t going to happen any time soon thanks to commercial pressures and the size of the task.
Given that I am very unlikely to be allowed to make such huge fundamental changes as switching to an ORM or re-architecting large amounts of code, my question is pretty simple:
Is there a way to make either SQL Server or Oracle understand the parameter identifier for the other or some sensible, simple way to write parametrized queries in a generic way without huge amounts of string replacements or IF…Else statements dependant upon the target platform? I realise I may still have to edit almost every SQL statement in the application but if that’s the case then so be it, I’ll just have to sell the idea to my bosses.
Cheers
I think the easiest way is just to optimize queries converting. For example you can just cache converted queries and once query is converted then next time you need to convert it you jast take it from cache. And you can just use hash code of query string as a key to cache. Like query plans caching. And also you can profile and optimize query converting itself too.
This simple caching approach is used in real application. For example NHibernate Linq (in NH3.0) provider convert Linq expressions to AST of is internal HQL language and then converts it to sql. And on each step it caches “query plans” so if the same query (same structure, different parameters) needs to be converted again nh can just take it from cache