I am having a problem with update mapping in query based view object. When I use NULLIF function in where clause the application gives the builder error(An unexpected severe error has occurred in JDeveloper, The program may be unstable, which could result in data loss).
Example of my code:
select table1.column1,table1.column2,table2.column3
from table1 left join table2
on table1.column1 = table2.column1
where
table1.column1 = nullif(table1.column1,?)
When you are creating your business components - which flavor of SQL/JDBC are you using? Make sure it is the generic one and not the Oracle specific.
Related
As we have seen that after you get a data source. We need to configure SQL dialects based on the database we use. After we select a particular dialect, How would that be used to make SQL queries specific to DB. Do frameworks like hibernate and JOOQ construct SQL queries in string based on the selected dialect ? If so which would be the most optimal way to support this in a framework of our own ?
Do frameworks like hibernate and JOOQ construct SQL queries in string based on the selected dialect
Yes. In jOOQ, there's an internal StringBuilder that collects SQL fragments from your expression tree, which are generated for your target SQL dialect specifically. You can see how that works in action on this website: https://www.jooq.org/translate. Try translating for example this input: SELECT * FROM t LIMIT 1 (which could correspond to your jOOQ API usage ctx.selectFrom(T).limit(1). It translates to:
-- Oracle 12c and more
SELECT * FROM t FETCH NEXT 1 ROWS ONLY
-- Oracle 11g and less
SELECT *
FROM (
SELECT x.*, rownum rn
FROM (SELECT * FROM t) x
WHERE rownum <= 1
)
WHERE rn > 0
If so which would be the most optimal way to support this in a framework of our own ?
You need:
An expression tree representation of your SQL query.
Optionally, you can parse a string to build this expression tree, like jOOQ's parser if you want to support actual SQL, or you can have your own language abstraction like Hibernate did with HQL / JPQL
Traverse that expression tree using something like a visitor to collect the SQL strings and bind variables.
But!
Do not build your own when you have off the shelf products like jOOQ or to some lesser extent Hibernate that can do the same. Building such a generic SQL abstraction is really difficult, and unless you want to actually sell such a product (you probably don't given your question), investing this time into building this product is not worth it at all.
The above LIMIT emulation is one of the more simple examples from jOOQ. Here's a lot more to help you decide against rolling your own, and that answer is still just scratching the surface of what jOOQ does behind the scenes.
So I've got a SQL query that is called from an API that I'm trying to write an integration test for. I have the method that prepares the data totally working, but I realized that I don't know how to actually execute the query to check that data (and run the test). Here is what the query looks like (slightly redacted to protect confidental data):
SELECT HeaderQuery.[headerid],
kaq.[applicationname],
HeaderQuery.[usersession],
HeaderQuery.[username],
HeaderQuery.[referringurl],
HeaderQuery.[route],
HeaderQuery.[method],
HeaderQuery.[logdate],
HeaderQuery.[logtype],
HeaderQuery.[statuscode],
HeaderQuery.[statusdescription],
DetailQuery.[detailid],
DetailQuery.[name],
DetailQuery.[value]
FROM [DATABASE1].[dbo].[apilogheader] HeaderQuery
LEFT JOIN [DATABASE1].[dbo].[apilogdetails] DetailQuery
ON HeaderQuery.[headerid] = DetailQuery.[headerid]
INNER JOIN [DATABASE2].[dbo].[apps] kaq
ON HeaderQuery.[applicationid] = kaq.[applicationid]
WHERE HeaderQuery.[applicationid] = #applicationid1
AND HeaderQuery.[logdate] >= #logdate2
AND HeaderQuery.[logdate] <= #logdate3
For the sake of the test, and considering I already have the SQL script, I was hoping to be able to just execute that script above (providing the where clause programmatically) using context.Database.SqlQuery<string>(QUERY) but since I have two different contexts, I'm not sure how to do that.
The short answer is no, EF doesn’t support cross database queries. However there are a few things you can try.
You can use two different database contexts (one for each database).
Run your respective queries and then merge / massage the data after
the query returns.
Create a database view and query the view through EF.
Using a SYNONYM
https://rachel53461.wordpress.com/2011/05/22/tricking-ef-to-span-multiple-databases/
If the databases are on the same server, you can try using a
DbCommandInterceptor
I’ve had this requirement before and personally like the view option.
I have the following query, which executes perfectly in SSMS. However, when I paste the code into a newly created dataset and click "execute", BIDS crashes and closes without notice - any suggestion as to the reason?
Code:
SELECT MSP_EpmProject_UserView.ProjectOwnerName,
MSP_EpmProject_UserView.ProjectUID,
CurrentActivities.Activities_Current
FROM MSP_EpmProject_UserView
Left Join
(Select t1.projectUID, STUFF(
(Select ', ' + t2.TaskName
From (SELECT MSP_EpmProject_UserView.ProjectUID, MSP_EpmTask_UserView.TaskName
FROM MSP_EpmAssignmentByDay_UserView INNER JOIN MSP_EpmTask_UserView ON MSP_EpmAssignmentByDay_UserView.TaskUID = MSP_EpmTask_UserView.TaskUID INNER JOIN MSP_EpmProject_UserView on MSP_EpmAssignmentByDay_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID
WHERE (MSP_EpmAssignmentByDay_UserView.TimeByDay = #refDate) AND MSP_EpmProject_UserView.[Project Departments] = #prjDep) t2
Where t1.ProjectUID = t2.ProjectUID
Order by t2.TaskName
For XML Path(''), Type).value('.','varchar(max)'),1,2,'') as Activities_Current
From
(SELECT MSP_EpmProject_UserView.ProjectUID, MSP_EpmTask_UserView.TaskName
FROM MSP_EpmAssignmentByDay_UserView INNER JOIN MSP_EpmTask_UserView ON MSP_EpmAssignmentByDay_UserView.TaskUID = MSP_EpmTask_UserView.TaskUID INNER JOIN MSP_EpmProject_UserView on MSP_EpmAssignmentByDay_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID
WHERE (MSP_EpmAssignmentByDay_UserView.TimeByDay = #refDate) AND MSP_EpmProject_UserView.[Project Departments] = #prjDep) t1
Group by t1.ProjectUID) CurrentActivities On CurrentActivities.ProjectUID = MSP_EpmProject_UserView.ProjectUID
WHERE (MSP_EpmProject_UserView.[Project Departments] = #prjDep)
I would try to create a view and see if that still crashes. BIDS is not meant to be SSMS and it's interpretation of the XML parsing may be blowing it up. You are translating values from a query using 'for xml', with 'type' which gets rid of the root element of the xml, then extending it, then nesting it, then nesting that, then left joining that, then you have a regular sql expression. BIDS is not meant to do a lot of dynamic SQL, intense CLR, and xml node or xquery expressions nesting things in my experience. Everytime I have thrown lot's of XML, table variables, recursive CTE's, dyanmic SQL... it blows up. It's interpreter is blowing up I am guessing as it does not have the resources SSMS does to evaluate the expression and gives up in the form of a blow up.
My thought on doing the view is that the interpretation will be then forced on the SQL engine in the database to perform it's logic and execution plan and then return the results. BIDS will just know it is a call to perform but not have to reason out the logic. In my recollection SSRS with BIDS on 2008 has many issues with complex query logic and SSAS cubes.
This may not work but I know putting things to views, functions, or procs will often times fix issues with complex logic the engine has to perform.
I managed to work my way around this by just pasting the code into the dataset, updating the fields, NOT clicking the "query designer" and by manually adding the parameters BIDS did not detect automatically (in my case an INT parameter for DATEADD() ). When I then close the dataset windows and use the dataset in my report, everything works fine
I have a generic code that is used to retrieve DDL information from a Firebird database (FB2.1). It generates SQL code like
SELECT * FROM MyTable where 'c' <> 'c'
I cannot change this code. Actually, if that matters, it is inside Report Builder 10.
The fact is that some tables from my database are becoming a litle too populated (>1M records) and that query is starting to take too long to execute.
If I try to execute
SELECT * FROM MyTable where SomeIndexedField = SomeImpossibleValue
it will obviously use that index and run very quickly.
Well, it wouldn´t be that hard to the database find out that that is an impossible matcher and make some sort of optimization and avoid testing it against each row.
Is there any way to make my firebird database to optimize that search?
As the filter condition is a negative proposition (and also doesn't refer a column to search, but only a value to compare to another value), Firebird need to do a full table scan (without use any index) to confirm that aren't any record that meet your criteria.
If you can't change you need to wait for the upcoming 3.0 version, that will implement the Boolean data type, and therefore should start to evaluate "constant" fake comparisons in advance (maybe the client library will do this evaluation before send the statement to the server?).
I'm using Zend Framework for my website and I'd like to retrieve some data from my PostgreSQL database.
I have a request like :
SELECT DISTINCT ON(e.id) e.*, f.*, g.* FROM e, f, g
WHERE e.id = f.id_e AND f.id = g.id_f
This request works well but I don't know how to convert the DISTINCT ON(e.id) with Zend.
It seems that I can get DISTINCT rows but no distinct columns.
$select->distinct()->from("e")->join("f", "e.id = f.id_e")
->join("g", "f.id = g.id_f");
Any idea on how to make a select with distinct column ?
Thanks for help
You probably can't do this with Zend Framework since distinct on is not part of the SQL standard (end of page in Postgres documentation). Although Postgres supports it, I would assume its not part of Zend Framework because you could in theory configure another database connection which does not offer support.
If you know in advance that you're developing for a specific database (Postgres in this case), you could use manually written statements instead. You'll gain more flexibility within the queries and better performance at the cost of no longer being able to switch databases.
You would then instantiate a Zend_Db_Apdapter for Postgres. There a various methods available to get results for SQL queries which are described in the frameworks documentation starting at section Reading Query Results. If you choose to go this route I'd recommend to create an own subclass of the Zend_Db_Adapter_Pgsql class. This is to be able to convert data types and throw exceptions in case of errors instead of returning ambiguous null values and hiding error causes.