Nhibernate Generate wrong SQL for Oracle with locking - oracle

yesterday I've been trying to make this code work inspite the fact it's just working fine with nhibernate and SQL server but when it come to oracle it generate wrong sql
UnitOfWork.Current.CreateCriteria<Bill>().Add(Restrictions.IsEmpty("ReqId"))
.SetMaxResults(BatchSize).SetLockMode(LockMode.Upgrade).List<Bill>();
the generated SQL will something like
Select * from
(Select bill_0.id,bill_0.BillNo ...... from Bill bill_0 where bill_0.reqId is Not null )
where ROWNUM < 10 for UPDATE of bill_0.ID
so i wont run because the allies bill_o is defined inside the inner sql statement so who got the solution ?
the correct sql would be something like this which i tried and worked on oracle db
Select bill_0.id,bill_0.BillNo ...... from Bill bill_0
where bill_0.reqId is Not null and ROWNUM < 10 for UPDATE of bill_0.ID

Since, as you say, NHibernate is generating invalid Oracle SQL, I suggest you file a bug with the NHibernate people. The SQL would work if the in-line view had been assigned an alias of "bill_0", or if the FOR UPDATE clause didn't use a table alias ("for UPDATE of ID"). Whether you can modify your NHibernate calls to make either of these happen I'm afraid I have no idea.

Related

Can't get Oracle SQL Developer to display specific values from object table

I've started learning SQL and playing with Oracle SQL Developer v22. For some reason I'm not able to retrieve value from an object table by using SELECT VALUE(A). It only gives my user ID.object_name as in the below screenshot. Any tips why?
SELECT VALUE(A) FROM table A;
If I use SELECT * FROM table; all is fine.
SELECT * FROM table A;
I've tried printing using dmbs_output, same problem.
Tried with other object tables, same behaviour.
Please share your table DDL and DML for a more accurate answer, but setting this preference should do what you're looking for
'Display Struct Value in Grid'
I talk about that here
Disclaimer: I work for Oracle and am the product manager for SQL Developer.

Jaspersoft Studio - Oracle JDBC Data Adapter - Set Specific Schema as Current Schema

I have the latest version of Jaspersoft Studio and I am using Oracle's JDBC data adapter (ojdbc11.jar), but the connection is made with the default schema, while I want the queries of each report to be executed in another schema (let's call it that: "MySchema").
For example a report with this SELECT clause will not work:
select *
from myTable
while a report with this SELECT clause will work:
select *
from MySchema.myTable
I tried things like this:
jdbc:oracle:thin:#//10.1.1.55:1521/DOMAIN.COM;connectionProperties={currentSchema=MySchema}
or this:
jdbc:oracle:thin:#//10.1.1.55:1521/DOMAIN.COM;connectionProperties={CURRENT_SCHEMA=MySchema}
or this:
jdbc:oracle:thin:#//10.1.1.55:1521/DOMAIN.COM?searchpath=MySchema
or this:
jdbc:oracle:thin:#//10.1.1.55:1521/DOMAIN.COM??currentSchema=MySchema
but without success.
Do you have a solution in this direction or do you know of any other way to solve the problem?
This is an extremely big problem if you consider that I have reports that make selects to dozens of tables and functions.

CREATE TABLE statement in Oracle with the existence check

This question is inspired by this.
As stated, I don't want a solution from PL/SQL. I want a 1 or 2 SQL statements that will check for table existence and if its not exist - create it.
Such statement(s) will be plugged into C++ application (not a script) and so I want a plain SQL solution. If such solution is not exist (please say so), I'd like to have a simple string I can plug into C++ code and use either SQLExecute() or a native Oracle client API to execute such a string.
Trying to google for a solution I am getting a results that can be used either in the shell script or a stored procedure. As I explain here and in the previous question - my situation is completely different - I work in C++ and want an appropriate solution.
There is no single SQL statement that will create a table only if it does not exist in Oracle 11g.
It is not obvious to me why you're objecting to a PL/SQL based solution. If you're using raw ODBC calls in C++, you can pass a PL/SQL block to SQLPrepare just as you would pass a plain SQL statement. Given that PL/SQL blocks work almost exactly like a pure SQL statement, it would be unusual to categorically reject a PL/SQL based solution.
If you are going to categorically reject PL/SQL, you can certainly take the logic from any of the PL/SQL based solutions and implement that in a couple of SQL statement executed from your application. For example, you can query dba_| all_| user_tables (depending on your privileges, whether you are creating tables in other schemas, etc.) to determine whether the table exists and then conditionally execute your DDL
select owner, table_name
from dba_tables
where owner = <<schema that will own the table>
and table_name = <<name of the table>>
If that returns no rows you can then execute your DDL.
Of course, you can also just execute your DDL statement and catch the ORA-00955 name is already used by an existing object error in C++.

How to have sysdate result remoted across database link?

I'm running a query across a database link to a Sybase server from Oracle.
In it's where clause is a restriction on date, and I want it tied to sysdate, so something like this:
select * from some_remote_view where some_numeric_key = 1 and
some_date > sysdate+2
The problem is, when I do explain plan, only the condition some_numeric_key = 1 shows up in the actual sql that is getting remoted to the sybase server. Oracle is expecting to perform the date filter on its side.
This is causing a performance nightmare - I need that date filter remoted across to have this query working quickly
Even if I try something like casting the sysdate to a charcater string like this:
to_char(sysdate-2,'YYYY-MM-DD')
It still does not remote it.
Is there anything I can do to get Oracle to remote this date filter across the db link to Sybase?
Doing integration between Oracle and other platforms I often run into this problem, not just with SYSDATE but with other non-standard functions as well.
There are two methods to work around the issue, the first being the most reliable in my experience.
First, you can create a view on the remote db with the filters you need, then on the Oracle side you just select from the new view without additional filters.
Second, if you are not allowed to create objects on the remote side, try using bind variables (of the correct data type!) in your Oracle SELECT statement, e.g.:
declare
v_some_date constant date := sysdate + 2;
begin
insert into oracle_table (...)
select ...
from remote_table#db_link t
where t.some_numeric_key = 1
and t.some_date > v_some_date;
commit;
end;
/

ORA-00907 when quering from my Java application but works fine in SQL Developer

My query that I put into a prepared statement is:
select *
from ( select seq, audit_ts, message_type
from log2
where 1 = 1
and message_type in ('SOURCE', 'DEST')
order by seq desc )
where ROWNUM <= ?
When I run the query in my application, I get:
java.sql.SQLSyntaxErrorException: ORA-00907: missing right parenthesis
EDIT: Here is the java executing the query. I am trying to return a set of search results, so the prefix contains the SELECT statement and then I can have any number of suffixes (in this excerpt "AUDIT_LOG_SEARCH2") which are the parameterized WHERE clauses based on the user search:
StringBuffer query = new StringBuffer(300);
query.append(dbAdapter.getQuery("AUDIT_LOG_ENTRY_PREFIX"));
query.append(dbAdapter.getQuery("AUDIT_LOG_SEARCH2"));
// Insert parameters to complete the sql prepared statement
PreparedStatement ps = _dbConn.prepareStatement(query.toString());
ResultSet rs = ps.executeQuery();
But the query runs fine when I run it separately in SQL Developer. The query was originally created for Postgres, then updated for Oracle. Any tips?
You need to set the variables into the preparedStatement before executing.
PreparedStatement ps = _dbConn.prepareStatement(query.toString());
ps.setInt(1, 10);
Please post what query.toString() gives you if that doesn't work. Not query, but query.toString()
What are you doing in your:
// Insert parameters to complete the sql prepared statement
Are you using correctly the methods ps.setString... or whatever? Or are you just replacing the question marks? the second might be corrupting your query.
Based on #AlexPoole and #EdGibbs comments, I decided to add a bunch more debug statements. It turns out the method was being recursively called with a different sql "suffix" later on in the program if certain conditions were met. The suffix was not updated with the necessary parenthesis for the new ROWNUM wrapping the statement. So although the ORA-00907 can be thrown for many different formatting problems, it was in fact a right parenthesis that was causing me problems :P
The prefix and suffix seems like a weird pattern in this code base for creating sql queries. I'm thinking of getting rid of this and refactoring so queries don't have to be built like that. Any advice??
So for anyone else who runs into this Oracle error, I would suggest logging the sql statement you are generating and play around with it in SQL Developer. If it works in there, but not in your application, your code is probably doing something funky :P

Resources