I can't find a specific answer to this question online. If I take a tinyint field and cast it like so: '(DT_STR,2,1252)some_id' what happens with the single digit numbers? Does a 7 become '7' or '7 '?
I found some documentation on the MSDN site that the string is null terminated and truncates, but it didn't specifically say what happens to an int that is shorter than the cast.
Thanks!
In scenarios like this, I find it's easier to just test and observe.
OLE DB Source
Simple query that ensures we have the correct data type
SELECT cast(10 AS tinyint) AS src
UNION ALL SELECT cast(2 AS tinyint) AS src
Derived Column
Cast our tinyint to a string and add something at the end to view whether it's left or right padded.
(DT_STR,2,1252) [src] + "X"
LEN((DT_STR,2,1252)src + "X")
Results
I was actually surprised, I'd have expected it to be right padded but that's not case.
src Concated Length
10 10X 3
2 2X 2
Related
I like to use the result from another query to address the column name. For this I like to use CONCAT(). But somehow it don't work; when I run this line I get 0 rows back:
SELECT * FROM cover WHERE CONCAT('c','9') = 1;
When I don't make use of CONCAT() it work perfectly:
SELECT * FROM cover WHERE c9 = 1;
And also CONCAT() seems to work. With this I get a result:
SELECT CONCAT('c','9');
I tried all solution from this question:
MySQL select with CONCAT condition
like this one, but i always got 0rows back:
SELECT * FROM (
SELECT id, CONCAT('c', '9') as target
FROM cover) base
WHERE target = "1"
My MySQL Version is; 10.1.16-MariaDB
It is bad schema design to splay an array across a bunch of columns. And, as you are discovering, it is hard to use the columns. Build another table for the c values.
Or...
With lots of 0/1 "columns", consider SET or BIGINT UNSIGNED; either will hold up to 64 boolean flags in a tiny fraction of the space. And, with different code, BLOB could be used.
To extract bit 22 from a BIGINT, ((col >> 22) & 1) will give you 0 or 1.
Consider using a case when, since the number of options is known beforehand (you can only access columns that exist):
SELECT id
FROM cover
WHERE case ?
when 1 then c1
when 2 then c2
when 9 then c9
end = 1
... where the question mark would be the provided value, like 9 in your example.
I am not new to MySQL but a strange situation happened in my code today coincidently which got me surprised. Can someone explain why this gives me identical results?
SELECT * FROM `products` WHERE id = 12
and
SELECT * FROM `products` WHERE id = '12ABC'
In both cases I get the same result with the same record being selected. I would expect that second one would return me nothing?! My ID field is int(11) unsigned with auto_increment flag turned on.
From MySQL docs:
When an operator is used with operands of different types, type conversion occurs to make the operands compatible
Documentation
So basically, '12ABC' is cast to 12.
MySQL has to make a conversion to make a compare betwen 2 different types. It tries to make the string to an int and get the digits from the string starting from the beginning.
It you had for instance
'ABC12'
the result of the string conversion to int would be 0
I just happened upon an interesting case of data type casting in MySQL. Consider the following queries:
SELECT * FROM (SELECT 0 AS col) AS t WHERE t.col=123; #Yields 0 rows
SELECT * FROM (SELECT 0 AS col) AS t WHERE t.col="123"; #Yields 0 rows
SELECT * FROM (SELECT 0 AS col) AS t WHERE t.col="0"; #Yields 1 row, col=0
SELECT * FROM (SELECT 0 AS col) AS t WHERE t.col="abc"; #Yields 1 row, col=0
Lines 1, 2, and 3 seem logical to me. But on line 4, why, oh why, dear SQL, do you so eagerly cast "abc" to be equal to 0?!
I mean, I get it - "abc" isn't an integer, so 0 makes the most sense... Is there a scenario in which this behavior is actually useful? As far as I can tell, it likely just leads to bugs (as it did on our application)...
Perhaps there's a MySQL "mode" that enables warnings for automatic type-casting like this?
MySQL does implicit type casting for strings in a numeric context. The leading numeric characters of the string are converted to a number, so a string such as 'abc' gets converted to 0.
This can be very handy because this conversion does not cause an error (an explicit conversion would).
The moral is simple: When comparing constants to columns, make the column the same type as the column. That is, don't compare strings and numbers, lest something unexpected happen.
This is definitely the way MySQL works.
When you use a comparison that compares a numeric object to a string constant, the string gets cast as an integer. MySQL tries to interpret the string as an number, like this:
'0123abc' gets the value 123.
'1abc' gets the value 1.
'abc' gets the value 0.
What use is this? It comes in handy in ORDER BY clauses if you need numeric text strings ordered in numeric order with '112abc' after '12abc'.
Is it ok to enclose all values in SQL statement with single quotes ? For example:
This is simple table called books:
id | title
1 | Some book name
2 | Second book name
Is it OK to write statement like this:
SELECT * FROM books WHERE id = '1'
I've tested that query in SQL server 2008 and MySQL 5 and it works good, but I am curious is there any performance issue, because ID field is acctualy integer.
And second question is it OK to write statement like this:
SELECT * FROM books WHERE id = N'1'
N prefix is used in SQL server for UTF-8 fields, but I've tested that in SQL server and MySQL and both worked OK. I don't know if SQLite support N prefix, because I didn't test that.
The reason why I am asking this is because I am building database class that will work with popular SQL databases (SQL Server, MySQL, SQLite and maybe MS Access), so when performing selecting, inserting or updating data I don't have to worry about field datatype. I can always enclose value with N'Some value', but I am curious is this correct and is there any performance issues?
In SQL Server, you can get an implicit conversion when doing this. Sometimes it won't affect the plan or have noticeable impacts on performance, but sometimes it might. They are generally deemed to be bad. Inspect the plans for these two queries against AdventureWorks2012:
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID = 43659;
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID = '43659';
The latter contains a CONVERT_IMPLICIT (hover over the tooltip for the CI seek).
You also want to be very careful about switching between VARCHAR and NVARCHAR - in some cases this can be dreadful for performance, depending on the underlying data type and whether the literal has the N prefix.
Long story short: don't do this. Write your ORM thingy so that it understands the different data types and handles them appropriately.
SELECT ... WHERE int_type = '123' is fine to do. SQL will convert '123' to an integer once and be done with it.
However, SELECT ... WHERE char_type = 123 is no okay, because SQL will have to convert every cell into an integer. See that char_type = '0123' and char_type = '00123' will also match. So it has to do more work.
Thanks to #MartinSmith for pointing out a resource for precedence in casting: http://msdn.microsoft.com/en-us/library/ms190309.aspx
Here's an example bug in MySQL that says the implicit typecast from quoted string of digits to an integer causes a severe performance issue: http://bugs.mysql.com/bug.php?id=43319
It's best to not quote numbers.
SQL Server and MySQL both perform implicit type conversions, but it doesn't make it a good practice; use the appropriate native type when you can. This will let you avoid trying to spot the difference between:
SELECT * FROM books WHERE id = '1'
and
SELECT * FROM books WHERE id = 'l'
and
SELECT * FROM books WHERE id = 'O'
and
SELECT * FROM books WHERE id = '0'
(that's a one, a lower case L, a capital 'o', and a zero respectively)
Wondering what's wrong with comparing BIGINT column values with '1'. Exactly, why this isn't producing any results:
SELECT * FROM table WHERE col = '1'
while this works just fine (i.e. returns non-empty result).
SELECT * FROM table WHERE col = 1
Thanks
If you are comparing an integer, you do not need quotes around it.
This appears to possibly be an unresolved bug.
See MySQL Bugs
You don't need to use quotes in comparing with Int or BigInt.
But I am getting result even I am comparing with quotes.
See this fiddle