I am using EF to connect with Oracle database and writing a linq query like this
var keyword = this.Keywords.ToLower();
var filteredItems = from item in active_items
where item.Name.Contains(keyword)
select item;
The generated SQL from linq makes use of Like and keyword wrapped in %% signs.
e.g. WHERE "EXTENT1"."NAME" LIKE '%keyword%'
Which seems OK but I need the sql to make use "Contains" keyword and need the SQL to be like
e.g. WHERE CONTAINS(NAME,'keyword') > 0
How do I achieve this?
First option:
use devart library: http://blog.devart.com/using-oracle-full-text-search-in-entity-framework.html
Second option:
make a stored procedure in oracle that receive your keyword and search it and map the procedure into your model (if you are using model-first)
Third option:
in the linq mapping use a function like INSTR. See http://docs.oracle.com/cd/E11882_01/win.112/e18754/canonical_map.htm#ODPNT7777
Related
I'm using the #sap/hana-client npm module in a NodeJS project to connect to a HANA database and run queries.
I have a list of IDs that I want to include in a WHERE ID IN(...) SQL clause via parameterized queries, but cannot seem to figure out the syntax to do it.
Here's what I imagine it would look like (but this does not work, fails at the parameter binding stage)
const ids = [1,2,3,4];
const params = [ids];
const sql = "SELECT * FROM T WHERE ID IN (?)";
// this fails with => code: -20007, message: 'Can not bind parameter(0).', sqlState: 'HY000'
conn.query(sql, params, (err, result) => {
// process query results or errors
});
I know that in Postgres I can do this by using the UNNEST(...) 1 array function, but the same does not seem to work in HANA
That's a well-known difficulty with HANA.
ARRAY-like types are not natively supported in the client software.
Your (special) case of this, namely turning an array into a list of parameters for an IN clause requires some additional efforts.
See e.g. Errors with declared array/table variable values in SAP HanaDB SQL
The bottom line is that Postgres handles this special case specifically by replacing the single IN-clause parameter ? with a whole list of delimited values.
HANA does (sadly) not do something like that.
Instead, if you have to know in advance how many elements (at max) the IN-list will have so that you can prepare a statement with a parameter ? for each of those elements.
Alternatively, you can use SQLScript and the UNNEST construct that I've shown in the linked question, or you can create a temporary table, fill it with the IN-list elements and use it in the IN-clause (or join it).
Either way, it's rather cumbersome to manually do this, and I'd probably look for a framework that does that sort of stuff.
I want to pass 'A0101', 'A0201' this like a parameter in sql server query using in clause but from c# to a sp
If the "IN" clause is just being used to filter, you can use Linq without passing it into the stored procedure (it will still be evaluated on server with deferred execution).
var results = (from item in context.SPCall
where new[] {"A0101", "A0201"}.Contains(item.Property)
select item).ToList();
I have a simple sql query in orientdb function like this:
select *
from TestExecutionPlanReport
where executionPlan IN :executionPlans
It accepts "executionPlans" as parameter where an array value should be passed.
When I tried just one value like "#59:71", it works and return the wanted output. BUT when I tried to pass in an array value like "[#59:71,#59:214]", is not working. It returns an empty response. It works when I query "select * from SomeClass where field IN [#59:71,#59:214]" (Not in OrientDb function)
I had the same issue when trying to run an SQL query from Scala code. I solved it by passing a set as the parameter instead of a list or an array.
If I got your question right, you are trying to execute the query you've mentioned in a OrientDB server side function (probably written in JavaScript) which takes executionPlan as a parameter.
I also noticed this happening if you use parameterized queries. A parameterized query is something like the following;
var query = "select * from TestExecutionPlanReport where executionPlan IN ?";
return db.query(query, executionPlans);
However, when I used string concatenation to build the query, it works. I'm referring to the following
var query = "select * from TestExecutionPlanReport where executionPlan IN " + executionPlans
If you are using string concatenation I think the issue is with how you pass the parameter. Rather than passing "[#59:71,#59:214]", try passing [#59:71,#59:214] to your function and see if it works.
Usually when you use string concatenation to build queries, you can use the print() function to print the concatenated query on the OrientDB console. However, concatenation based queries could be exploited to do SQL injections, hence discouraged.
I cannot explain why this doesn't work for parameterized queries. I'll do more research on this. Perhaps it's a bug. I'm using OrientDB 2.0.3.
Hope this helps.
I have to perform lexical analysis on the oracle query and separate the query to various parts (based on the clauses)in perl. For example,Consider :
Select deleteddate,deletedby from temptable where id = 10;
I need to print
select : deleteddate , deletedby
from : temptable
where : id = 10
I used this code snippet :
my $parser= SQL::Statement->new();
$parser->{PrinteError}=1;
my $query = SQL::Statement->new("select deleteddate,deletedby from temptable where id =10",$parser);
my #columns = $query->columns();
print $columns[0]->name();
Though this prints deleteddate, this fails when i give a subquery inside the select clause:
Select deleteddate,deletedby,(select 1+1 from dual) from temptable where id = 10;
Can you please point me in the correct direction.
Thanks.
It looks to be a limitation of that package; it seems to be a general purpose parser and not something that can understand advanced features like subqueries or Oracle-specific constructs like "from dual".
What are the constraints of your system? If python is an option it looks like this is a more fully-featured library:
http://code.google.com/p/python-sqlparse/
The other option would be to use the actual Oracle database, if that's an option. You would:
use the DBI and DBD::Oracle modules to create a connection to Oracle & get a database handle,
create a statement handle by calling prepare() on the database handle using your query,
execute the query (there may be an option in Oracle to execute in "test only" or "parse only" mode),
examine the statement handle (such as the NAMES_hash property) to get the column names.
Otherwise it seems the SQL::Statement module unfortunately just isn't up to the task...
I found that Entity SQL support NEWID(), but does ObjectQuery support it as well?
http://msdn.microsoft.com/en-us/library/bb738616.aspx,
Can I write objectquery like:
context.member.orderby("NEWID()").select("it.UserID");
or something like this? or I should write in other way?
I thought if entity sql support NEWID() function, it should be accepted by ObjectQuery also. Like you can use distinct(it.UserID), or BitWiseAND(it.UserID, 1) in ObjectQuery.Where() or Select().
Many thanks.
This is a SQL Server-specific canonical function, so it should be prefixed with 'SqlServer':
context.member.orderby("SqlServer.NEWID()").select("it.UserID");
Unfortunately, this will not work either: the Where extension method needs at least one reference to the immediate input scope.
Thanks Devart for response.
Actually, I found that I can use like:
var query1 = context.member.select("it.userid, SqlServer.NEWID() as newid").orderby("it.newid");
this can make random order for result, you will find that NEWID() is in the translated sql query.
but if you want to select partially result from 'query1' result set, you cannot write:
var query2 = context.member.select("it.userid, SqlServer.NEWID() as newid").orderby("it.newid").select("it.userid");
because when you use sql profiler to watch the sql that translated pass into sql server, you will find that the 'NEWID()' disappear.
However, I think 'query2' should be make sense. But it doesn't work.