views:

266

answers:

5

Hello everyone,

I'm querying an oracle 9i database with:

SELECT * FROM table WHERE column LIKE '%' || ‘someText’ || '%' ESCAPE '\';

and it fails with the error "escape character must be character string of length 1" ( ORA-01425 error), while succeeding in an oracle express 10g database.

Making it a double backslash (ESCAPE '\\') solves the problem for the oracle 9i database, but generates instead the same ORA-01425 error for the 10g database.

I cannot edit the SQL since it's auto-generated via Telerik OpenAccess ORM.

The Linq code that leads to the SQL above is:

activity.Name.Contains.("someText")

I would like both databases to handle the ESCAPE '\'... Or instead, have another way of searching table items by their name or description.

Thanks in advance!

+1  A: 

Try:

  SELECT * FROM TABLENAME 
  WHERE COLUMNNAME LIKE '\%' ESCAPE '\';

Generally ESCAPE symbol in LIKE used for allow search symbols '%' and '_'

Michael Pakhantsov
escape '\\\\' works for the first database, escape '\\' works for the second. I would like the single backslash to work in the first one too! The reason is that this is auto-generated sql by a mapper, that I cannot edit...
naruu
@naruu, is it exact query which fail? because on my db (9 and 10g) everything is works. SELECT * FROM all_tables WHERE table_name LIKE '%' ESCAPE '\'; but does not work will '\\' or '\\\'
Michael Pakhantsov
The single backslash fails on the 9i, the double backslash fails on the 10g express. The ORM generates (automatically) SQLcode with the single slash, and I would like it to work on the 9i too (actually, I would like the same sql code to work on any recent oracle database)... Not sure what I should be looking out for. The application and the mapping are working fine, except for this escape clause. While setting the application to run with the oracle 9i server database, it fails only because of the ESCAPE single-backslash.
naruu
It should be working just like Michael is describing.A couple questions.. Can you use a different character instead of the backslash? Also, can you confirm the actual code that is making it to the database? I am guessing something is happening to the backslash characters in your calling application before they are being sent to the database.
Craig
Thanks Craig for your suggestions! However I can't alter the SQL. It's auto generated by Telerik Open Acess ORM, and the database is queried exactly with the single backslash. The auto-generated SQL is always the same. I queried each database on my own (with the oracle client SQL Developer), and verified what I described in this question - the databases respond differently to exactly the same query, when the query contains the escape backslash clause.
naruu
+1  A: 

you could avoid the backslash issue altogether. Try using the curly braces around the escaped characters instead.

http://download.oracle.com/docs/cd/B10500_01/text.920/a96518/cqspcl.htm

sql_mommy
Isn't that specific to oracle text and queries using the contains operator?
Jörn Horstmann
Thankyou sql_mommy and Jörn Horstmann for your input! Unfortunately I cannot modify the sql, since it's autogenerated.The following Linq piece of code:[activity.Name.Contains.("someText")]Is converted to the following SQL with the single backslash (via Telerik OpenAccess ORM):[c."NAME" LIKE '%' || 'someText' || '%' ESCAPE '\']So yes, this issue is happening only with the Contains... I am searching an Activity by it's Name... I don't seem to find another way to write this in Linq, and the resulting SQL code is valid and works in the express 10g database...
naruu
makes sense - actually, I looked this up yesterday, and I was wrong regardless. Curly braces won't work for backslashes. According to the oracle docs (and my testing), the backslash should be escaped with double backslashes. Have you tried it without the escaped command? So "where column like '%\\'? I think that should work in either, but I actually have 11g - so I can't test it out to be sure. OF course, since it's autogenerated, I don't know how you could change it.
sql_mommy
Thanks sql_mommy for looking up the subject for me. I can't change the autogenerated code, however, I can try the queries to see how they work out. Escaping with the double backslash only reverses the problem: it succeeds on the 9i, it gives the ORA-01425 error on the 10g express... I would like the same code to work on both databases. As for the omitting the escape part (using just the LIKE '%'), that works on both databases, but even if I could omit the escape (which I believe I can't), I hope there could be a different solution...
naruu
+2  A: 

Not familiar with Linq but I'm a bit confused about where you're executing the query - are you just pasting the generated code into SQL*Plus running against two databases, where that behaviour can at least be explained?

If you are doing it in SQL*Plus, do a show escape in each environment; I suspect 9i will report escape "\" (hex 5c) while the 10g will report escape off. This might indicate that escape handling has previously been set up in the 9i instance but not in the (presumably more recent) 10g one.

If any of this has turned out to be relevant so far, try doing set escape \ in the 10g session and try the \\ version again. And in 9i try doing escape off and try the single-\ version there. Both should now work.

Assuming you're still with me, the next question is why 9i has that setting; there's probably a login.sql or glogin.sql file that's setting it automatically. You might be able to get that removed, as long as it won't affect anything else, to allow the generated code to run unaltered.

I don't think any of that will be relevant if you're going to be executing the code some other way; not sure if you're just testing and debugging the generated code in SQL*Plus and will eventually execute it elsewhere (lack of knowledge of Linq again), in which case this may be a transitory problem anyway.

I'm also not sure what you're actually escaping anyway...

Alex Poole
Alex, I got the auto-generated code, and tested it myself in each database. I was indeed surprised to see different output for the same SQL command, considering the tables were exactly the same too (they were created using the same script). I tried “show escape” on both, and got “escape off” on both. Thank you for your suggestion to check this setting, It would be nice to know about some setting that is causing this different behavior! But, for my situation and for now, the problem is solved :)
naruu
I was using Linq to use the ORM (Telerik OpenAccess). The ORM uses my C# and Linq, and generates SQL code to handle the databases. The escape was auto-generated for a search function. (I’m not sure why, but possibly it could have been to protect against special characters or something... it was a web application project.)
naruu
+1  A: 

Does it fail for every input or just specific strings? The problem may not be with the query, but with the input. If there is an odd number of backslashes, Oracle may try to escape something that shouldn't need an escape.

For example, this works because it's escaping the '%':

select * from dual  where 'test' like '%'||'\'||'%' escape '\';

But this fails because it's trying to escape 'a', which doesn't need escaping:

select * from dual  where 'test' like '%'||'\a'||'%' escape '\';

Can you modify the string before it's passed to the function and fix odd backslashes?

jonearles
It doesn't look like it's getting as far as the someText string. The error (particularly the empty `''`) suggests the backslash is being treated as an escape character already and is being lost before the query itself is parsed.
Alex Poole
I think you're right. I just noticed my code generates ORA-01424, not ORA-01425.
jonearles
Thank you jonearles for the suggestion! However, it was a nvarchar2 field issue only. select * from dual where 'dummy' like '%' escape '\';works on both because the field ‘dummy’ is varchar2.
naruu
A: 

In case anyone stops by with the same problem... My issue was that I was dealing with “NVARCHAR2” fields. I received help with this issue in the oracle forums :)

This query: select * from dual where 'dummy' like '%' escape '\';

works on both because the field ‘dummy’ is varchar2. If it were nvarchar2, the part of the query that could (only possibly!) cause problems would be the “escape '\'” part (my oracle 9i wants escape ‘\’, my oracle 10g wants ‘\\’).

To overcome the problem, instead of using the ORM’s autogenerated code, I have written a stored procedure (only when I’m searching for strings), where I handle nvarchar2 fields like this: where TableName.ColumnName like N'%' || ‘someText’ || N'%' escape N'\'

And it’s working fine :)

That doesn’t explain, however, how having the same NVARCHAR2 columns, and the same SQL queries, they were handled differently by the two oracle servers (the 10g express on my local PC and the 9i) – that remains a question. So for anyone running into similar problems, it may be good to know if it’s a nvarchar2 issue (I had no idea it could be a problem), and try working around it.

naruu