There are many posts online and on stack overflow talking about solving the issue of case insensitive likes. I guess this is due to these peoples database being by default case sensitive.
Sql server by default uses a case insensitive collation, so i would never have that problem by default.
But unfortunately, I have the opposite problem. I need to do a one off case sensitive equals or like.
I cannot set the collation of the table, so would ideally run some sql like this
WHERE Column COLLATE Latin1_General_CS_AS = 'CaseSensitive'
As far as i can see, i dont understand why an InsensitiveLike has been implmeneted as surely we could have just done something like this
.Where(x=> x.Column.ToLower() == variable.ToLower())
But my issue is not able to be worked around in any other way that doing the above collaction change.
It would be nice if this was built in rather than having to write sql queries.
Have i missed something or is there really no way to do this?
Related
I am creating a php page for a team of application testers who need to frequently see the content of a oracle database as part of the testing process. The page takes the sql query from a text area and uses oci8 libraries to execute it against the database.
However as the command describe (short desc) is a feature of Oracle SQL*Plus, I am trying to emulate it's functionality inside a sql query. Here's what I've come up with until now-
SELECT column_name "Name",
CASE WHEN nullable = 'Y' THEN 'NULL'
WHEN nullable = 'N' THEN 'NOT NULL'
END AS "Null",
concat(concat(concat(data_type,'('),data_length),')') "Type"
FROM all_tab_columns
WHERE table_name='{$TABLE}'
This seems to be working for most of the tables, but not for "v$database" or "v$instance". I understand that the references to these system views are not present inside "all_tab_columns" and the users will not be searching for them, but I want the query to work for all tables and views just for the sake of completeness.
So if anyone can suggest a better way, please guide me.
You can use dbms_sql.describe_columns2 to get the same information as describe does.
It needs quite some effort to get it actually working: you have to parse the statement and get the metadata from it. The nice thing is: it works for virtually any query. Even for views, or queries that contain calculated columns, joins, etc.
Recently, I have been tasked with some major refactoring of a project coded prior to my arrival. Part of this refactoring involves going through some stored procedures and cleaning them up and make some general changes to their behavior. I recently came across the following statement:
IF
CASE
WHEN EXISTS
(
SELECT *
FROM users
WHERE Username = 'admin'
) THEN 1
ELSE 0
END <> 0
//Do something here
After starring at this piece of code for a while and doing a little research, I eventually came to the conclusion that the logic of the code above can be accomplished by writing:
IF EXISTS (
SELECT *
FROM users
WHERE Username = 'admin'
)
//Do something here
So my question is this: what would be the advantage to using the case statement? It seems bulkier than the if statement, and less readable too. Is there a compatibility advantage that I'm not seeing? Or am I wrong in saying that these two queries are equivalent, and are there cases where they will behave differently?
As a side note, I'm not terribly concerned in the performance advantages of using CASE statements over if statements. But for those who found themselves on this page looking for just that, there's a good answer here about it.
Maintainability if one can assume tha more than one condition will be needed over a relatively short timeframe.
Pretty much the only reason I can come up with ;)
There's a lot of misinformation in some of the comments here. Fortunately you did change it to an "IF" statement, but for future viewers of this page:
See #damien-the-unbeliever's first comment on question here: MS SQL - CASE vs IF performance
See forum topic (just the top few posts) here: http://www.sqlservercentral.com/Forums/Topic1206250-392-1.aspx
Basically, the IF/ELSE statements and CASE expressions are two fundamentally different parts of the language, and are not used interchangeably. IF/ELSE is for control-flow within a batch or stored-procedure; CASE is for "choosing" a data-value within a SELECT or similar operation.
How to make LINQ case sensitive and NOT case sensitive depending on the situation?
I'm using sql server 2008 and Entity Framework 4.0.
I changed the COLLATION to make SQL Server case sensitive. so that for scenarios like these:
query = query.Where(x => x.Username == username);
it works great.
However I need to be able to pull out data from db ignoring case when searching by subject (or name or similar) like so:
query = query.Where(x => (x.Name.Contains(Name)));
which doesn't work when record is "TestString" and i'm looking for "test" or "Test" or similar. How would i make it so that when it would find a text or part of a string in a text?
thanks
LINQ has no concept of case sensitivity, it only cares about boolean evaluation. So if you want to ignore case, you should do something like:
query = query.Where(x => (x.Name.ToLower().Contains(Name.ToLower())));
Chances are you will want to pass a CultureInfo to ToLower() (or use ToLowerInvariant()), and you might want to cache the result of Name.ToLower() so as to not have to perform that operation a potentially large number of times, but this should get you started.
query = query.Where(x => string.Equals(x.Name, Name, StringComparison.CurrentCultureIgnoreCase));
Read my reply to this:
String.Equals() not working as intended
It isn't the reply you wanted, probably :-)
Ah... and if you have to convert to the same case to make comparisons, ToUpper is better than ToLower. Don't ask me why. But you can read here: Case insensitive string compare in LINQ-to-SQL
Queryable.Contains has an overload taking an IEqualityComparer<T> used for comparision. See msdn. If you supply a case insensitive comparer, this should work - I'm quite sure there is one in the framework already.
I'm having problems with our MSSQL database set to any of the Turkish Collations. Becuase of the "Turkish I" problem, none of our queries containing an 'i' in them are working correctly. For example, if we have a table called "Unit" with a column "UnitID" defined in that case, the query "select unitid from unit" no longer works because the lower case "i" in "id" differs from the defined capital I in "UnitID". The error message would read "Invalid column name 'unitid'."
I know that this is occurring because in Turkish, the letter i and I are seen as different letters. However, I am not sure as to how to fix this problem? It is not an option to go through all 1900 SPs in the DB and correct the casing of the "i"s.
Any help would be appreciated, even suggestions of other collations that could be used instead of Turkish but would support their character set.
Turns out that the best solution was to in fact refactor all SQL and the code.
In the last few days I've written a refactoring app to fix up all Stored procs, functions, views, tablenames to be consistent and use the correct casing eg:
select unitid from dbo.unit
would be changed to
select UnitId from dbo.Unit
The app also then goes through the code and replaces any occurrences of the stored proc and its parameters and corrects them to match the case defined in the DB. All datatables in the app are set to invariant locale (thanks to FXCop for pointing out all the datatables..), this prevents the calls from within code having to be case sensitive.
If anyone would like the app or any advice on the process you can contact me on dotnetvixen#gmail.com.
I developed so many systems with Turkish support and this is well known problem as you said.
Best practice to do change your database settings to UTF-8, and that's it. It should solve the all problem.
You might run into problems if you want to support case-sensitivity in (ı-I,i-İ) that can be a problematic to support in SQL Server. If the whole entrance is from Web ensure that is UTF-8 as well.
If you keep your Web UTF-8 input and SQL Server settings as UTF-8 everything should goes smoothly.
Perhaps I don't understand the problem here, but is this not more likely because the database is case sensitive and your query is not? For example, on Sybase I can do the following:
USE master
GO
EXEC sp_server_info 16
GO
Which tells me that my database is case-insensitive:
attribute_id attribute_name attribute_value
16 IDENTIFIER_CASE MIXED
If you can change the collation that you're using then try the Invariant locale. But make sure you don't impact other things like customer names and addresses. If a customer is accustomed to having case insensitive searching for their own name, they won't like it if ı and I stop being equivalent, or if i and İ stop being equivalent.
Can you change the database collation to the default: this will leave all your text columns with the Turkish colllation?
Queries will work but data will behave correctly. In theory...
There are some gotchas with temp tables and table variables with varchar columns: you'll have to add COLLATE clauses to these
I realize you don't want to go through all the stored procedures to fix the issue but maybe you'd be OK to use a refactoring tool to solve the problem. I say take a look at SQL Refactor. I didn't use it but looks promising.
Changing the Regional Settings of your machine to English(US) completely saves the day!
We are porting an app which formerly used Openbase 7 to now use MySQL 5.0.
OB 7 did have quite badly defined (i.e. undocumented) behavior regarding case-sensitivity. We only found this out now when trying the same queries with MySQL.
It appears that OB 7 treats lookups using "=" differently from those using "LIKE": If you have two values "a" and "A", and make a query with WHERE f="a", then it finds only the "a" field, not the "A" field. However, if you use LIKE instead of "=", then it finds both.
Our tests with MySQL showed that if we're using a non-binary collation (e.g. latin1), then both "=" and "LIKE" compare case-insensitively. However, to simulate OB's behavior, we need to get only "=" to be case-sensitive.
We're now trying to figure out how to deal with this in MySQL without having to add a lot of LOWER() function calls to all our queries (there are a lot!).
We have full control over the MySQL DB, meaning we can choose its collation mode as we like (our table names and unique indexes are not affected by the case sensitivity issues, fortunately).
Any suggestions how to simulate the OpenBase behaviour on MySQL with the least amount of code changes?
(I realize that a few smart regex replacements in our source code to add the LOWER calls might do the trick, but we'd rather find a different way)
Another idea .. does MySQL offer something like User Defined Functions? You could then write a UDF-version of like that is case insesitive (ci_like or so) and change all like's to ci_like. Probably easier to do than regexing a call to lower in ..
These two articles talk about case sensitivity in mysql:
Case Sensitive mysql
mySql docs "Case Sensitivity"
Both were early hits in this Google search:
case sensitive mysql
I know that this is not the answer you are looking for .. but given that you want to keep this behaviour, shouldn't you explicitly code it (rather than changing some magic 'config' somewhere)?
It's probably quite some work, but at least you'd know which areas of your code are affected.
A quick look at the MySQL docs seems to indicate that this is exactly how MySQL does it:
This means that if you search with col_name LIKE 'a%', you get all column values that start with A or a.