I need to create a WHERE-IN query (using Oracle) that is case insensitive. I've tried this way:
select user from users where lower(user) in lower('userNaMe1', 'useRNAmE2');
but I get ORA-00909: invalid number of arguments
The list is dynamically generated in my Spring app. That's why I can't add lower() to every single list's value.
Is there any other way to achieve it?
lower() takes a single argument, so you can use:
where lower(user) in (lower('userNaMe1'), lower('useRNAmE2'))
You could also express this using regular expressions (regexp_like() accepts a case sensitivity argument) if you prefer:
where regexp_like(user, '^(userNaMe1|useRNAmE2)$', 'i')
There is another more drastic approach, and is to make your session or your searching in the database case insensitive.
You can find how to do it in this answer:
Case insensitive searching in Oracle
Related
Using SQL I would like to know if its possible to do the following:
If I have a variable that the user inputs mutiple strings into seperated by a comma for example ('aa','bbb','c','dfd'), is it possible using LIKE with a wilcard at the end of each string in stead of having the user to enter each variations in multiple macros.
So say if user was looking for employee numbers that start with ('F','E','C') is it possible without using OR statements is the question I guess am asking?
It would be similar to that of an array I guess
No, LIKE is its own operator and therefore needs separated by an OR.
You might prefer ILIKE to LIKE, as it is a case-insensitive comparison.
You can also try to use REGEXP_LIKE, which is similar to what you want, except you'll have to use regex expressions instead of 'FEC%'
That depends on your SQL dialect; I don't know Impala at all, but other SQL engines have support for regular expressions in string matches, so that you can build a query string like
SELECT fld FROM tbl WHERE fld REGEXP '^[FEC].*$';
No matter what you do, you will need to build a query from your user's input. Passing through user input unprocessed into your SQL processor is a big "nope" anyways, from a "don't accidentally delete a table" point of view:
How am I going to use BETWEEN Operator with Text Value or what is the right syntax when you will select all products with a ProductName for example ending with any of the letter BETWEEN 'C' and 'M'?
Most SQL dialects provide the RIGHT() function. This allows you to do:
WHERE RIGHT(TextValue, 1) BETWEEN 'C' AND 'M'
If your database doesn't have this function, you can do something similar with the built-in functions. Also, the exact comparison might depend on the collation of the column/table/database/server. Sometimes comparisons are independent of case and sometimes they are dependent on case.
In case you are interested in an alternative method (which does work with the w3schools SQL editor), you can also use the LIKE operator:
WHERE ProductName LIKE '%[c-m]'
This will get you all Product Names ending on any character between C and M.
(It does work with the w3schools SQL Editor.)
In this case, the LIKE operator is using two wildcard characters:
1.%
Any string of zero or more characters.
2.[c-m]
Any single character within the specified range ([a-f]) or set
([abcdef]).
You can find more information about the LIKE operator here:
https://msdn.microsoft.com/en-us/library/ms179859.aspx
I need to determine if all rows in varchar column in a db contain any characters outside of the particular set below:
abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ.-#,1234567890/\&%();:+#_*?|=''
I tried this but am not sure if it is correct:
select AccName
from Transactions
where AccName not like '%[!abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ.-#,1234567890/\&%();:+#_*?|='']%'
Should this work?
Any help appeciated.
You cannot use a regular expression inside an ordinary LIKE condition in a query. If you want to use regular expressions, you will have to use a special operator. In MySQL, you could try the following:
SELECT AccName
FROM Transactions
WHERE AccName REGEXP [!abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ.-#,1234567890/\&%();:+#_*?|='']%';
If this doesn't run to boot, then you may have to tidy up the regular expression you gave. And as marc_s asked, the exact regular expression and query will depend on the DB system you are using.
Database management systems vary in their support for matching regular expressions. Examples below use PostgreSQL, which supports POSIX regular expressions, along with other flavors. Examples below also test for case-sensitive matches to avoid sentences like "'Mike' doesn't not match the regular expression".
AFAIK, no DBMS lets you mix the like operator with a regular expression.
A like expression in the form column_name like '%a%' will match 'a' if it appears anywhere in the column. But you need your regular expression to match on the whole value of the column. Anchor the regular expression at the start and end of each value (^ and $), and tell the dbms to match one or more instances (+) of the atom.
select 'Mike' ~ '^[a-zA-Z0-9]+$'; -- 'Mike' matches the regex
Write a failing test.
select 'Mike?' ~ '^[a-zA-Z0-9]+$'; -- 'Mike?' doesn't match the regex
Add the question mark to the regex, and verify the test succeeds.
select 'Mike?' ~ '^[a-zA-Z0-9?]+$'; -- 'Mike?' matches the regex
Repeat failing test and succeeding test for each character. When you've caught all the characters you want, invert the logic using the !~ operator in place of the ~ operator.
When your data is clean move this into a CHECK constraint.
PostgreSQL pattern matching
From the following question,
SQL server ignore case in a where expression
Is it possible with Oracle?
Also, is it possible to compare "your,text" with "your text"?
I want to convert All characters other than A-Z0-9 into space and then compare the string.
I can do it by Java methods through regex but don't prefer writing unecessary code.
Yes, with the UPPER() function.
select whatever from your_table where UPPER(col) = UPPER('YourText');
(Or LOWER() if you prefer that.)
Performance warning: that won't play well with indexes, unless you've indexed on UPPER(col) also and are careful with NULLs.
I just realized that SQL server '=' comparator when used for text comparison is case insensitive. I have a few questions regarding this functionality:
Is this the same for all databases or specific to SQL server?
I have been using the lower function to ensure the text comparison is insensitive till now. Is it still a good idea to follow the same?
How can we do case sensitive comparisons in SQL server?
Why is '=' operator defaulting to case insensitive comparison?
No, case sensitivity has nothing to do with the equals sign.
Case sensitivity is determined by the collation for the database -- see the documentation for details.
Case sensitivity depends only on the collation.
You can specify the collation within each '=' operation
SELECT *
FROM [Table_1] a inner join
[Table_2] b on a.Col1=b.Col2 collate Modern_Spanish_CS_AI
I have been using the lower function to ensure the text comparison is insensitive till now. Is it still a good idea to follow the same?
Absolutely not. You will generally preclude the use of an index if you do this. Plain old = (or < or > or whatever) will either work or not depending on the collating you have chosen. Do not do this "just to be safe". Testing will make sure you've got it right.
The case sensitivity of operations in SQL Server is determined during installation when you set the collation for the database. At that point in time you can choose to install SQL Server as case insensitive (default) or case sensitive.
http://msdn.microsoft.com/en-us/library/aa197951(v=sql.80).aspx
How the comparison is done depends on the collation that you have chosen for the field. If you change the field to use a case sensetive collation, the comparisons will be case sensetive.
By default fields use the collation set for the database, but each field can have it's own collation setting.