MySQL Case Statement Unknown Cloumn in field list - mysql

Below is the Case statement
Select CASE
WHEN TRIM('##MDM_COLUMN##')<>'UNSPECIFIED'
THEN table.##MDM_COLUMN##
ELSE NULL
END AS mdm_id
from
table
THE ##MDM_COLUMN## is a run-time parameter which gets replaced accordingly
if ##MDM_COLUMN## = 'UNSPECIFIED' the query is failing saying
Unknown column table.UNSPECIFIED in field list
It looks like the behavior of CASE statement is, check the complete statement for syntax and validity before executing,
So is there any other way to overcome this behavior I need

Related

Variables in mysql initialized with string datatype

In Mysql, user variables are taking string values when declared inside select statement.
I have a table named 'a' with one column named 'amount' as shown below
amount
100
1000
1000
111115000000062760
111115000000062765
111115000000062770
111115000000062775
111115000000062780
Consider that I want to display null for amount values that are repeating in this table in the inserted order.
I've written the below query to achieve the same :
select
CASE
WHEN (#x != amount) THEN amount
END result,
CASE
WHEN ((#x) != amount) THEN #x:=amount
END dummy
from (select amount, #x:=0 x from a) q;
I'm creating a variable named '#x' in innermost query with default value as 0. When processing each row, I'm taking that row's 'amount' value and setting in the variable. Hence, in next row, I'll use the variable to hold previous row's data.
Using current and previous amount values, I'll only show the data that differ.
problem :
When I execute the query, I got the below output :
This is wrong as only 3rd row must have NULL values. 5th and 6th rows must have values. But, When I execute the query again, I got the below output :
This is the correct result. When subsequently executing the query, it always works fine. Only when it is executed for the first time after connecting to DB, this issue occurs.
Debugging :
I've tried setting #x's value before executing the query and it works fine. But, I want to know why it wouldn't work if I set it inside the select query.
I tried printing #x's values in the query and the only difference between the first query result and subsequent query results is alignment of #x's values. I think #x is considered as a string (as it is left aligned) in the first query. Hence, it breaks when comparing with certain bigint values.
When checking the documentation, it is mentioned that referring to a variable that has not been initialized will be taken as 'string'
If you refer to a variable that has not been initialized, it has a value of NULL and a type of string.
I believe this is what's happening here. After first query, the variable probably got declared with 'integer' type which made it work in subsequent queryies.
Is it not possible to provide the variable's datatype inside select statement? Kindly advise.
No, to specify the type of your user defined variable you MUST declare it outside of the SELECT statement.
As you have already pointed out the MySQL documentation specifically mentions that you MUST declare the variable first:
9.4 User-Defined Variables
If you refer to a variable that has not been initialized, it has a value of NULL and a type of string.
Beginning with MySQL 8.0.22, a reference to a user variable in a prepared statement has its type determined when the statement is first prepared, and retains this type each time the statement is executed thereafter. Similarly, the type of a user variable employed in a statement within a stored procedure is determined the first time the stored procedure is invoked, and retains this type with each subsequent invocation.
This is very clear, either you formally declare the variable first, or it will be a string that is initialized with a value of NULL.
So just declare the variable first, you can declare variables within your inline SQL scripts, so don't try to fight it, either declare your variable first, or modify your query to use the variable as a string, either by casting amount to a string in the inner most query or cast #x to your numeric type in the comparison:
select
CASE
WHEN (CAST(#x as SIGNED) != amount) THEN amount
END result,
CASE
WHEN (CAST(#x as SIGNED) != amount) THEN #x:=amount
END dummy
from (select amount, #x:=0 x from a) q;

ERROR 1292 (22007): Truncated incorrect INTEGER value: 'the first non-integer result from my table' when using an update stmt

I am trying to run a select statement of a string column to set out alphanumeric values free of pure integars using the following statement:
select some_col_1 from some_table where some_col_1 = 'some value' and length(cast(some_col_1 as unsigned)) != length(some_col_1)
Whereas, I am trying to update some other column based on that condition using update statement,
My problem is, whenever I attempt to run the select statement, it is being successfully executed, meanwhile when I essentially use an update statement only gives some kind of unexpected error which is: ERROR 1292 (22007): Truncated incorrect INTEGER value: 'the first non-integer result from my table'.
I just can't figure out why it is doing this. Is there any experts who can see anything odd in my update statement? I am using mysql server version 8.0 and my update stmt precisely goes as follows:
update some_table set some_col_2 = true where some_col_1 = 'some value' and length(cast(some_col_1 as unsigned)) != length(some_col_1)
Your support with this would be very highly appreciated,
Thank you in advance,
What you are running into is mysql's sloppy way of implementing STRICT_TRANS_TABLES mode, which is intended to give an error when trying to set a value to something that has to be modified to meet the column's specification.
mysql chose to implement this by making things like cast or date parsing just give errors, instead of warnings, when done in a data modification statement, even when those expressions weren't what was actually attempted to be stored.
You can either disable STRICT_TRANS_TABLES mode for the duration of your update:
set session sql_mode=replace(##sql_mode,'STRICT_TRANS_TABLES','');
update ...
or use an alternate way of detecting your case that doesn't involve something that triggers a warning, or under STRICT_TRANS_TABLES, an error. For instance:
update some_table set some_col_2=true where some_col_1 not regexp '^([1-9][0-9]*|0)$';

MYSQL data to long for non-existent column

I keep getting this error for an insert into ... update query, the problem, this column 'str' does not exist in the table being updated, or any of the tables I'm pulling data from, and it's not in the query.
Error Code: 1406. Data too long for column 'str' at row 215710
I'm totally stumped here. It this a mysql bug? I went as far as to isolate the query to just one column, still got this error.
UPDATE 1:
I just tried updating with a manual value, on one column only set to longtext. I'm still getting the exact same error.
UPDATE 2:
Major update, I isolated the problem down to the select query, the original error implied a table column, however, it seems to be pointing to what I assume is some kind of temp table column for the following row. When I yanked this out of the query, it worked. Ironically, this is the same column I did my one column test with where I manually entered an value in the update on duplicate key part of my query.
CONCAT_WS('', UC_Words(`name`), ' | ', UC_Words(`city`), ' ', UC_Words(`state`), ' ', UC_Words(`country`), CONCAT('|---|',`name-key`)) AS `owner-data`
I'm currently using lots of GROUP_CONCAT's, but I have already adjusted the length. Is there a parameter for CONCAT_WS length? NOTE: UC_Words is a custom function. This could possibly be a culprit, still need to test it...
UPDATE 3:
The error appears to be a result of the UC_Words function. The 'str' is the name field in that function. Type was set to VARCHAR 255, which was too short.
MySQL will truncate any insert value that exceeds the specified column width.
to make this without error try Switch your MySQL mode to not use STRICT.
EDIT:
To change the mode
This can be done in two ways:
Open your "my.ini" file within the MySQL installation directory, and look for the text "sql-mode".
Find:
Code:
Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Replace with:
Code:
Set the SQL mode to strict
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Or
You can run an SQL query within your database management tool, such as phpMyAdmin:
Code:
SET ##global.sql_mode= '';
The error appears to be a result of the UC_Words function. The 'str' is the name field in that function. Type was set to VARCHAR 255, which was too short.

Lua mySQL update statements and where clauses

So I'm trying to run an update with LuaSQL and mySQL, and seem to be stuck in one place. Whenever I try to update, the WHERE clause always fails on me, stating that the column doesn't exist. However, the column is correct, and the output gives a different column name. This is the update clause and what comes of it after running it
status,errorString = assert(conn:execute[[UPDATE Users SET count=count+1 WHERE userID = user#id50589297]]))
lua: test3.lua:16: LuaSQL: error executing query. MySQL: Unknown column 'user' in 'where clause'
stack traceback:
[C]: in function 'assert'
test3.lua:16: in main chunk
[C]: in ?
You're missing quotes around your string user#id50589297, it's trying to parse it as a column identifier.
status, err = assert(
conn:execute[[UPDATE Users SET count=count+1 WHERE userID='user#id50589297']]))

mysql wont raise error when sub query in IN clause return empty resultset?

when i write query with empty IN clause it raised an error.
e.g select city where id in()
And if i write any sub query in IN clause which return empty resultset then it wont raise error.
e.g select city where id in(select id where name='abc')
where sub query return empty resultset.
Can Anybody tell me what happen behind it??
i have read this but not convincing answer.
Visit Empty IN clause parameter list in MySQL
When you write IN() you make a syntax error.
When you write some sub query the syntax is correct and no error are detected. In other words the empty result set cannot be detected by the parser ans so no message.