MySQL string comparison without operator - inconsistency on the same server? - mysql

I found what is to me a really weird phenomenon. In my MySQL server which is version 5.0.92, I use a query as follows:
SELECT IF(thumb, thumb, image) AS thumb FROM blog WHERE id = 200;
Because I want to get the thumb value if it is not empty, otherwise the image value. Now in one database on this server, this works perfectly fine, just the way I want it to. But on another database on the exact same server, thumb always evaluates to false, even it is not empty, and the value for image is always selected.
I know that I can use thumb != '' and that does work on both databases but please someone tell me how this happened? Is this some kind of database-specific setting?

If thumb is string column then you should be using query something like:
SELECT IF(thumb IS NOT NULL AND thumb != '', thumb, image) AS thumb FROM blog WHERE id = 200;
Also check for the CHARACTER SET of both databases as string comparison depends on character set.
SHOW CREATE DATABASE db_name;
Database Character Set and Collation

Related

Unable to change the value of enum field in MySQL when manually typing a query

I have an enum column in a MySQL table called site_status:
From my understanding, updating the value of such a field is exactly the same process as changing value of a varchar or int or any other field.
The only "limitation" is that as a value I obviously have to set one from predefined values - as this is the nature of enum types. Right?
So I want to change site_status from LIVE to FREE:
I type:
update db_name.db_table set site_status = 'FREE' where site_id = 501;
Pretty easy query. Unfortunately does nothing. It also doesn't produce any error. Simply:
0 rows affected.
What am I doing wrong? When I manually click via GUI in Sequel Pro, the value is changed to FREE with no issues. I see a dropdown from which I pick another option.

MySQL REPLACE in UPDATE does not work properly

The following query:
select replace(`Abilities`, 'export_import', 'auto') from fl_account_types;
gives me 'auto,listings' correct replacement from Abilities column. However, when I execute:
update fl_account_types set `Abilities` = replace(`Abilities`, 'export_import', 'autos');
MySQL just omits 'export_import' string and replaces Abilities with 'listings' string.
What could be the reason?
The problem was that Abilities was of type SET and I was trying to replace with a value which was not listed in a definition of it. But I still do not understand why select replace works well and why MySQL do not throw an error.

Turn MySQL CHAR(1) columns into TINTINT

As a lead-in, I'd like to say I'm a heck of a PHP programmer--and no better versed in SQL than that role requires.
I have inherited a table with a legacy structure that uses CHAR(1) with a value of either 'Y' or blank (i.e. '') to indicate true and false.
I'd rather have the column type as TINYINT with 1 to indicate true and 0 to indicate false. (Booleans--I want booleans.) I want this in part because PHP makes casting 1 and 0 to true and false a lot easier. 'Y' v. '' is going to require more logic than I'm happy with, and eventually someone will forget they're not actually booleans and cause a mess.
So far, this is my approach:
Add a new column to the table for each of the old columns I'm trying to get rid of.
Use MySQL's IF structure to populate my new (TINYINT) columns appropriately
Kill the old columns and rename the new columns in their place
The columns are acting as foreign keys anywhere, and I'm completely isolated for other systems, so no worries there. My question is two-fold:
Firstly, is this the best approach? It seems to me there may be a better way of doing this. Is it possible to change the values in the current column and then change its type without risking losing my data?
Secondly, if I am on the right track, how do I turn this SELECT IF(strcmp(hardware.USER_HARDWARE_REQUEST, 'Y'), 0, 1) FROM hardware; into an update to store that value in another column?
You can use CASE also :
SELECT
CASE hardware.USER_HARDWARE_REQUEST WHEN 'Y' THEN 0 ELSE 1 END as 'result'
FROM hardware;
Alright, I think I've got it. I can go ahead and update the Y/'' values to 1/0 and then simply change the type.
Query I ended up using looks something like this UPDATE hardware SET SERVER_HARDWARE_REQUEST = (SELECT IF(strcmp(hardware.SERVER_HARDWARE_REQUEST, 'Y'), 0, 1));
Then I can simply change the type definition for the column and it works like magic.

MySQL: Where condition doesn't seem to work properly

I have a table called Traduction with these two rows :
francais |espagnol |allemand |anglais
-------------+-----------------+---------------+----------------
ORANGE litée |NARANJA ENCAJADA |ORANGEN GELEGT |ORANGE 1 LAYER
ORANGE LITEE |NARANJA ENCAJADA |ORANGEN GELEGT |ORANGE 1 LAYER
My query is :
SELECT * FROM T_TRADUCTION where francais= 'ORANGE LITEE';
This query returns two rows of the table, whereas it should return only the record with ORANGE LITEE value (not ORANGE litée).
I don't understand why.
Change your database collate to latin1_general_cs
Set your database DEFAULT CHARACTER to latin1
Now execute your query.
SELECT * FROM T_TRADUCTION where francais= 'ORANGE LITEE';
Try to correct it like this :
SELECT * FROM T_TRADUCTION where francais='ORANGE litée';
Best Regards.
Getting encoding right is tricky, there are too many layers: Browser,
Page,
PHP,
MySQL.
You need to check in what encoding the data flow at each layer.
Check HTTP headers, headers.
Check what's really sent in body of the request.
Don't forget that MySQL has encoding almost everywhere:
Database
Tables
Columns
Server as a whole
Client
Make sure that there's the right one everywhere.
From manual>
SET NAMES indicates what character set the client will use to send SQL statements to the server. Thus, SET NAMES 'cp1251' tells the server, “future incoming messages from this client are in character set cp1251.” It also specifies the character set that the server should use for sending results back to the client. (For example, it indicates what character set to use for column values if you use a SELECT statement.)

How to ignore case using breeze FilterQueryOp

I am using breeze to query data from the server and seem to be running into problems.
Is there a way to filter this data and ignore cases or making the value from the field a lower case?
Example:
var term = "john";
query = query.where("Name", "contains", Term);
The problem I am having is if the 'Name' field contains John with capital 'J', It return false but returns true if I change term to 'John'.
I know this is case issue but how can I make breeze ignore the casing? without using jquery.each.
Thanks. Any help will be greatly appreciated.
In my opinion there is a simpler approach to this.
By default OData is case sensitive, but nonetheless provides functions to transform a string to lower or upper case. So to fire a case-insensitive query to the server simply modify your code as follows:
var term = "john";
query = query.where("tolower(Name)", breeze.FilterQueryOp.Contains, term.toLowerCase());
Thus OData is told to transform the subject to lower case before comparing it to your search string, which has been converted to lower case before sending it to the server.
Ok, there are two parts to this. Breeze supports a LocalQueryComparisonOptions object that is used for all localQueries.
var lqco = new breeze.LocalQueryComparisonOptions({
name: "custom comparison options",
isCaseSensitive: false,
usesSql92CompliantStringComparison: true
});
// either apply it globally
lqco.setAsDefault();
// or to a specific MetadataStore
var ms = new breeze.MetadataStore({ localQueryComparisonOptions: lqco });
var em = new breeze.EntityManager( { metadataStore: ms });
You should set this once at the beginning of your application. In this example, all localQueries performed after this point will be case insensitive.
The problem is that unless your database is ALSO set to "match" these settings ( performing this differs by database vendor), then remote queries against the server will return different results then the same query applied locally.
Basically, Breeze cannot set the "server" side implementation, so the recommendation is usually to create a localQueryComparisons object that matches your server side database settings.
Hope this makes sense.
If anyone run into this problem on an Oracle DB, I added the code above from Jay Traband then modified a logon trigger to alter session variables for DB users.
Set the following values:
ALTER SESSION SET nls_comp = linguistic;
ALTER SESSION SET nls_sort = binary_ci
Hope this helps someone out. I love Breeze!!!