Can I use Oracle Pipelined Function like a select in QueryDSL? - oracle

For a specific reason of a requirement, instead of using a VIEW, I use an Oracle pipelined function to get data in a table.
It works perfectly using Native Query:
"select * from (table (PAC_FOO_PIPELINED.FUNCTION_BAR(:fooDate, :barDate)))"
The problem is that I need to use QueryDSL. If I use native query, it would be necessary to rewrite a lot of code that is now bound to abstract methods that were implemented using QueryDSL.
Can anyone tell me if it is possible to perform this select through QueryDSL?

Related

How to create Interactive/Classic Report with dynamic SQL?

I'm running Apex 19.2 and I would like to create a classical or interactive report based on dynamic query.
The query I'm using is not known at design time. It depends on an page item value.
-- So I have a function that generates the SQL as follows
GetSQLQuery(:P1_MyItem);
This function may return something like
select Field1 from Table1
or
Select field1,field2 from Table1 inner join Table2 on ...
So it's not a sql query always with the same number of columns. It's completely variable.
I tried using PL/SQL function Body returning SQL Query but it seems like Apex needs to parse the query at design time.
Has anyone an idea how to solve that please ?
Cheers,
Thanks.
Enable the Use Generic Column Names option, as Koen said.
Then set Generic Column Count to the upper bound of the number of columns the query might return.
If you need dynamic column headers too, go to the region attributes and set Type (under Heading) to the appropriate value. PL/SQL Function Body is the most flexible and powerful option, but it's also the most work. Just make sure you return the correct number of headings as per the query.

Change SQL query with a parametric query in Oracle

We have an application that uses a framework that we don't have access to it's java classes. I can just see the .class file in byte-code format. So I can't override that class. At that class we have a native query like below:
"Select col1 from table1 where col2='x'";
I mean where condition is not parametric. As well I don't have access to change the query in the code. the App uses Oracle database and Hibernate as ORM.
The question is
"Is there any way to tell Oracle or Hibernate to change this hardcoded query with a parametric one?"

User defined table types in Oracle

First of all usually I am working with MSSQL. But I have a stored procedure in MSSQL, which I need to use in Oracle now and since I am absolutely new to Oracle I have no idea at all how to do it correct.
I needed to use user defined table types in my MS SQL stored procedure because I am using "logical" tables in my stored procedure, which I also need to pass them to a dynamic sql statement within this procedure (using column names of "physical" tables as variables/parameters).
I've started to add the oracle function in a package I made before for another function. It looks like
TYPE resultRec IS RECORD
(
[result columns]
);
TYPE resultTable IS TABLE OF resultRec;
Function MyFunctionName([A LOT PARAMETERS]) RETURN resultTable PIPELINED;
I also described the layout of the tables (the user defined table types in MSSQL), which I want to use within this function in this package header.
So far so good, but now I don't really know where I have to declare my table variables or user defined table types. I also tried to put them in the package header, but if I am trying to use these tables in the package body, where I am describing my function, Oracle tells met, that the table or view does not exist.
I also tried it to describe the tables within the package body or in the block of my function, which looks like that:
FUNCTION MyFunctionName
(
[MyParameters]
)
RETURN resultTable PIPELINED is rec resultrec;
TYPE tableVariableA IS TABLE OF tableRecA;
TYPE tableVariableB IS TABLE OF tableRecB;
BEGIN
INSERT INTO tableVariableA
SELECT ColumnA, ColumnB FROM physicalTable WHERE[...];
[A LOT MORE TO DO...]
END;
But in this case Oracle also tells me, that it doesn't know the table or view.
I also tried a few more things, but at the end I wasn't able to tell Oracle what table it should use...
I would appreciate every hint, which helps me to understand how oracle works in this case. Thanks a lot!
You can't insert into a collection (e.g. PL/SQL table). You can use the bulk collect syntax to populate the collection:
SELECT ColumnA, ColumnB
BULK COLLECT INTO tableVariableA
FROM physicalTable
WHERE [...];
However, you might want to check this is an appropriate approach, since SQL Server and Oracle differ quite a bit. You can't use PL/SQL tables in plain SQL (at least prior to 12c), even inside your procedure, so you might need a schema-level type rather than a PL/SQL type, but it depends what you will do next. You might not really want a collection at all. Trying to convert T-SQL straight to PL/SQL without understanding the differences could lead you down a wrong path - make sure you understand the actual requirement and then find the best Oracle mechanism for that.

How to use table functions in queries with Spring Data

When using Spring Data JPA with Hibernate, what are the options available to write queries that join with table functions.
For example, I'd like to generate queries as described below:
CASE 1: SELECT * FROM getfoo(1) AS t1;
CASE 2: SELECT * FROM getfoo(1) x INNER JOIN tbl1 y on x.id = y.id;
Edit
To elaborate more, I'm using Spring Data for all things CRUD (It works great). However, I need to write complicated queries that join tables with "table functions". Table functions(AKA Table-Valued User-Defined Functions) are database functions that return tabled-values which can be used in the JOIN clause in combination with tables. Postgresql and Sql Server support them.
In the Spring Data realm, which includes much more than JPA, what are the options to consider when writing such queries? Whats the best practice from your experience? user2658013 was kind enough to describe one such approach using the entityManager.reateNativeQuery method.
In my mind here are the options:
JPA
Use #NamedStoredProcedureQuery ( >=JPA 2.1)
Use entityManager.createNativeQuery or #NamedNativeQuery
Non-standard
Use Spring Data's #Query to declare finder queries directly on repository methods.
Use SimpleJdbcCall
Any others?
I believe you are asking about Postgres stored functions. Postgres stored functions are analogous to "Stored Procedures". So I think you are asking how would invoke a stored procedure using JPA? Am I close?
The following pseudo code is derived from details published here (see section on Stored Procures):
http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html
EntityManager em = emf.createEntityManager();
SOMEVAL_TYPE result = (SOMEVAL_TYPE)em.createNativeQuery("SELECT getfoo(?1) FROM SOMEDB")
.setParameter(1, SOME_PARM)
.getSingleResult();
In general you can use JPQL with JPA instead of SQL.
Note! The above assumes you have already created the stored function in you Postgres database.
Hope that helps :)

Writing an isnull() wrapper for nvl()

We are moving our database from Oracle to SQL Server. My queries make extensive use of Oracle's nvl function. In SQL Server, the function to use is isnull(). If possible, I'd like to start getting my queries ready by changing them to use isnull(), while still on Oracle. My idea is to create a wrapper function isnull() in my schema and change my queries to use that function instead. That way when we switch database platforms, my queries are already using the new function.
Is there a way I can create a wrapper function in Oracle called isnull() that accepts and returns any datatype? Or do I just have to have multiple isnull() declarations, overloaded for all the expected data types?
Another approach might be to use COALESCE instead of NVL, since the syntax for COALESCE is the same in both Oracle and SQL Server. Still, the goal (if it is your goal) of having identical SQL that works efficiently (or even works at all) in both Oracle and SQL Server may not be realistic.
The only way in PL/SQL to have multiple overloads for the same function would be to create them in a package. You can create a package that includes a number of different overloaded IsNull functions that accept and return different data types and use those in your queries. Of course, that does mean that you will have to include the package name in your code. It's potentially easy enough to remove the package name when you move to SQL Server but it won't be an exact migration.

Resources