I'd like to generate the following SQL with rails / arel:
SELECT * FROM GROUPS
WHERE id = 10
CONNECT BY PARENT_ID = ID
I don't want to use plain SQL except for the last statement which is oracle specific (the real query is much more complex and I don't want to perform endless string concatenations).
What I've tried so far:
Group.where(id: 10).join('CONNECT BY PARENT_ID=ID')
This does not work as it places the custom SQL before the WHERE statement (as it assumes it's a join).
So the actual question is, how to add a custom bit of SQL to a query after the WHERE statements?
Related
I'm using entity framework core for mysql, and i've been running a complex linq query which i'm trying to optimise.
I turned on logging in the mysql server to view the resulting queries from the linq queries.
Oddly, none of it made sense as my complex query that joined 5 tables and performed multiple group bys, where, and order by clause was registered in the logs as 5 separate select all columns from table statements.
So, I tried a simple group by statement for one table. The resulting sql log produced "Select all_columns from table_name order by groupbyid".
Can anyone explain what happened here?
Thanks in advance.
More info as requested:
Sql query:
var queryCommand = (from p in _context.TableExtract group p by p.tableExtractPersonId);
queryCommand.ToList();
Resulting mysql log after:
SELECT .... [very long list of column names]
FROM TableExtract AS p
ORDER BY p.tableExtractPersonId
I've tried two different entity framework libraries: MySql.Data.EntityFrameworkCore(v8.0.17) and Pomelo.EntityFrameworkCore.MySql (v2.2.20) with the same results. I've tried .net core 3.0 and also received the same results. I'm going to try .net standard next.
Ok. I found it:
var queryCommand = (from p in _context.TableExtract group p by p.tableExtractPersonIdinto g select g.Key)
Forces linq to evaluate as a SQL group by. Otherwise apparently it does it's own thing with the group by.
How can I use a plsql code block like this with an Interactive Grid (Using Oracle Apex) :
begin
Query A;
exception when no_data_found then
Query B;
end;
Actually sometimes 'Query A' returns nothing and I want to run 'Query B'. any solution?
An interactive grid has to use a sql-query as source.
a. Write one query and use sql-query as source:
SELECT * FROM A
UNION ALL
SELECT * FROM B WHERE COUNT(SELECT * FROM A) = 0;
b. Write some function which does the work
Read this:
How to return a resultset / cursor from a Oracle PL/SQL anonymous block that executes Dynamic SQL?
But it sounds a little bit strange, that you got one grid for two datasources. This will bring up some problems when manipulating the data.
Open questions
Do you want to modify the data?
Do you want to insert new rows?
Does the user understand what's going on and what he is seeing?
Since there is no apparent way to NOT use an SQL query as the Interactive Grid source, you could maybe (depending on your specific solution) think differently and create an Interactive Grid region for each query. Then you could show one or another when the page loads, using a region server-side condition or even a Dynamic Action.
To expand on other answers with a little specificity, since this is about managing results of 2 different queries, you can put the 2 different queries in 2 different Grid regions. Then on the first region add a Server-side Condition of "Rows returned" and copy the SQL Query into the query input provided. On the 2nd region, you would set "No Rows returned" condition and again copy Query 1 into the SQL input provided.
Is it possible to update 2 columns in an Update statement that are in different tables? - The reason for the"scripted":
Where "Scripted" will be the "flag" so the formula does not run again on the same records if this field is filled in.
MERGE INTO arinvt_lot_docs ALD
USING
(SELECT arinvt.id,arinvt.class,fgmulti.in_date fgmulti.cuser3 FROM arinvt,fgmulti
WHERE arinvt.class LIKE 'CP%'
OR arinvt.class LIKE 'FG%'
OR arinvt.class LIKE 'IN%'
OR arinvt.class LIKE 'LA%'
OR arinvt.class LIKE 'PK%') Classes
ON (ALD.arinvt_id = classes.id
AND to_date(in_date) = '31-Dec-2015') --just picked a date to validate
WHEN MATCHED THEN
UPDATE SET non_conform_id = '21', fgmulti.cuser3 = 'SCRIPTED' --this text "Scripted" will fill in a field that will tell us in our reports if this was set by the script
I would like to join the tables using the arinvt.id field that is present in all 3 tables ARINVT_LOT_DOCS, FGMULTI & obviously ARINVT. ARINVT_LOT_DOCS & FGMULTI contain the NON_CONFROM_ID field that needs to be changed to '21'. The FGMULTI table also contains the CUSER3 field that would have "SCRIPTED" entered in it. The ARINVT table contains the Class of the inventory item which reflects in the conditions mentioned.
You cannot update two tables in one query in Oracle and other DBMS such as SQL Server but you can use transaction to achieve similar result.
This oracle community answers exactly that, if you try to join two tables, you will get this error
ORA-01776: cannot modify more than one base table through a join view
You can use transactions to update two tables in batch-like statement.
This https://stackoverflow.com/a/2044520 shows how to do it but for SQL Sever though. You need similar statement in Oracle.
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
I am using SQLManager Lite for firebird and it was impossible so far to write a query which would do an operation on char/varchar columns. Character set is win1252.
A query like
select * from Person where name = 'John'
won't return any results despite the fact that the record exists in the database. A similar query on a numerical column works just fine.
AM I am missing anything here?
Also, this query runs fine from my application. The only issue is that I would like to be able to run it within SQLManager Lite too. As a side note, values for char and varchar columns are not displayed properly within the same SQLManager Lite.
change to like
select * from Person where name like 'John'