MySQL Substring and Mid Parsing Bug - php

There is an interesting bug -for me-.
Please follow the query i executed.
everything is normal.
mysql> select hex(current_user());
Result : 726F6F74406C6F63616C686F7374
everything is normal.
mysql> select substring(hex(current_user()),1,15);
Result : 726F6F74406C6F6
i added null string to second and third parameter of substring method. everything is normal.
mysql> select substring(hex(current_user()),''+1,''+15);
Result : 726F6F74406C6F6
when i add null string to firs parameter of substring.. there is return only 726.:S i was expecting same result of my latest query.
mysql> select substring(hex(current_user())+'',1,15);
Result : 726
mysql> select substring(hex(current_user())+'',2,15);
Result : 26
mysql> select substring(hex(current_user())+'',3,15);
Result : 6
mysql> select substring(hex(current_user())+'',4,15);
Result : NULL
I tested with Mysql 5.0.95 and 5.1.61 and same issue..! i tested same query with mid function instead of substring.. same again.
Any idea ? i was working on some kind of Web Application Firewall rule bypass and i realized to that bug.

It's converting HEX to integer (by taking characters from HEX until the first non-numerical character: 726) when you apply '+' operator. And empty string is converted (to integer: 0) also.
Example:
''+1 => 0+1=1
726F6F74406C6F63616C686F7374+'' => 726+0 = 726
concat() function should be used for concatenating strings.

You should be using concat if you want reliable results...
SELECT hex(current_user()),
hex(current_user())+'',
substring(hex(current_user())+'',1,15),
concat(hex(current_user()), ''),
substring(concat(hex(current_user()), ''),1,15);

Related

how to get from mysql using in same sequence using laravel?

I have this record in my database
| 29 | Mac 190:193:194:195:196:197:198:199:200 |
the last column name is
path_address
if I have a string like this
190:193:194:195
I want MySQL to select the path_address that has same sequence
so I used this command
$query_data = $module_model::where('path_address','LIKE',"$structure%")->limit(7)->get();
where structure is :190:193:194:195 and it is working fine, but what is happening is that if I have string like this
190:193:194:195:197
it is also return mac as a result of this query ,
how can I set my query to bring the string that have same sequence only and stop if it has broken sequence , so the accepted sequence will be like this
190
190:193
190:193:194
190:193:194:195
190:193:194:195:196 and so on
but theses sequence must be rejected
190:194
190:193:194:196
190:193:196
190:193:194:195:196:198 etc .
For example, you may use
WHERE path_address LIKE '$structure%'
OR '$structure' LIKE CONCAT(path_address, '%')
First condition will return rows where path_address is not shorter than $structure, second - where it is not longer respectively.
fiddle

mySQL Workbench Error: Syntax Error, unexpected single quotes

I was trying to make a SQL statement in PHP, to convert a string into a time(6). But I have tried everything, for the last 12 hours, and have not made an inch of progress. I have tried these statements, all yield the same error.
UPDATE scheduling SET start='03:42PM' WHERE activityid=2;
UPDATE scheduling SET start=CONVERT(TIME(6),'03:42PM');
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'15:42'));
The error is
Syntax Error: unexpected '03:42PM'(single quoted text)"
I do not know how to fix this, the table exists, and i have sucesfully got other info using statements like SELECT activityid=2 FROM xxxxxx.scheudling
I guess I have two questions, either answer would work.
In my PHP document, how would I convert a string I get in from an Android Studio volley to a date. (I get the variable correctly, with $start=$_Post("start"), so that works, but I cant convert it into a time. I looked online, and tried everything that looked like it work work.
Conversion through SQL Code, I already tried CAST and CONVERT, neither works. My start column is type TIME(6).
I recommend testing expressions using a SELECT statement.
Firstly, the MySQL CONVERT function arguments are flipped around backwards.
The syntax is CONVERT(expr,type)
And type is supplied as a keyword, not a string literal. For example:
SELECT CONVERT('235',SIGNED)
To convert to a TIME datatype
SELECT CONVERT( '15:42' ,TIME(6)) // => 15:42:00.000000
The 'PM' part of the string literal will be ignored.
SELECT CONVERT( '03:42PM' ,TIME(6)) // => 03:42:00.000000
We can use the STR_TO_DATE function to return a TIME value from a string that contains the AM/PM indicator
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
And there's no need to cast that to TIME(6), we can do this:
UPDATE scheduling
SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p')
WHERE activityid = 2
The STR_TO_DATE function is documented here:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date
The format patterns for STR_TO_DATE are documented here, under DATE_FORMAT:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
FOLLOWUP
Demonstration:
setup
USE test;
CREATE TABLE scheduling (activityid INT PRIMARY KEY, start TIME(6));
-- 0 row(s) affected
INSERT INTO scheduling (activityid) VALUES (2);
-- 1 row(s) affected
execute the update statement in the answer above
UPDATE scheduling SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p') WHERE activityid = 2 ;
-- 1 row(s) affected
results
SELECT * FROM scheduling WHERE activityid = 2;
-- activityid start
-- ---------- ---------------
-- 2 15:42:00.000000
SECOND FOLLOWUP
Use same sql_mode setting reported by OP:
SET ##sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
Test:
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
returns
(NULL)
But this more complicated expression:
SELECT TIME(STR_TO_DATE(CONCAT(CURRENT_DATE(),' ', '03:42PM' ),'%Y-%m-%d %h:%i%p'))
returns
15:42:00
The more complicated expression is a workaround to avoid behavior imposed by the STRICT_TRANS_TABLES and NO_ZERO_DATE in the sql_mode.

MYSQL LIKE different behaviors for different languages, all tables utf8

I have three tables each with 3 columns, they are identical to each other. Only difference is se_words created with mysql GUI and the other two are created programmatically thrue sql inside mysql GUI.
se_words
en_words
es_words
-> id, name, user
I want to find words through the last 3 chars.
SELECT * FROM `es_words` WHERE word LIKE '%nar' // returns empty results (should be at least 500-1000+)
SELECT * FROM `en_words` WHERE word LIKE '%ate' // returns empty results (should be at least 500-1000+)
SELECT * FROM `se_words` WHERE word LIKE '%ens' // returns 1000+ results
The big problem is that en_words and es_words which are utf8 (same as se_words) always returns empty result.
I have changed it to latin, utf8_bin, utf8_unicode_ci, latin_spanish_ci etc but it doesnt matter. Still gives empty result
but
if I change the sql code to just 1 char and procent sign on both sides, the code gives a result.
SELECT * FROM `es_words` WHERE word LIKE '%a%' // returns 10000+ results
SELECT * FROM `en_words` WHERE word LIKE '%a%' // returns 10000+ results
How come same sqlcode different tables returns different result when all columns has multiply values which should be returned on LIKE search?
edit
Few of the words that should be returned upon LIKE search
es_words
abadernar,abaldonar,abanar,abandonar,abarrenar
en_words
aagate,abacate,abacinate,abalienate,abbate
From the code with trimmed variables
SELECT w.id, w.word, w.user
FROM en_words AS w
WHERE w.word LIKE '%gel' ORDER BY LENGTH(word) ASC LIMIT 0,500
Looks like an \r followed from the dictonary. Could only see it through an SQL DUMP. PHP would not show it at all.
I hope it solves the problem for you in the future who encounter it
(943, 'abridgments\r', 0),
(944, 'abrikosov\r', 0),
(945, 'abrikossov\r', 0),
(946, 'abril\r', 0),
(947, 'abrim\r', 0),
(948, 'abrin\r', 0),
(949, 'abris\r', 0),
(950, 'abristle\r', 0),

How to trim special characters from a sql query?

trim() is used to clear all the whitespaces. Now, instead of clearing white spaces, I want to eleminate all special characters from the 'username'. Is there any function like trim() for eliminating special characters??
My sql query is like
Select value from table_name where trim(username) = 'ABCD'
and it returns null value. But there are some values related to 'ABCD' and it displays all the entries when i execute the query
select value from table_name where username like '%ABCD%'
there are nothing else like visible in 'username' field. Is there any solution for this?
MySQL does not have such kind of functionality to remove special characters. Instead you can use replace function (if you know what are special characters).
replace("your column name",'_','')
See example :
Select value from table_name where REPLACE(trim(username$),"$","");
this if you want to replace the $ with an empty char
Try this function:
Create Function [dbo].[RemoveNonAlphaCharacters](#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare #KeepValues as varchar(50)
Set #KeepValues = '%[^a-z]%'
While PatIndex(#KeepValues, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#KeepValues, #Temp), 1, '')
Return #Temp
End
Call it like this:
Select dbo.RemoveNonAlphaCharacters('abc1234def5678ghi90jkl')
Once you understand the code, you should see that it is relatively simple to change it to remove other characters, too. You could even make this dynamic enough to pass in your search pattern.
refer this link:https://stackoverflow.com/a/22684392/3242978

How can I pass a comma-separated list of integers from PHP as a parameter to a stored procedure in SQL Server 2008?

Hopefully I'm going about this the right way, if not I'm more than open to learning how this could be done better.
I need to pass a comma separated list of integers (always positive integers, no decimals) to a stored procedure. The stored procedure would then use the integers in an IN operator of the WHERE clause:
WHERE [PrimaryKey] IN (1,2,4,6,212);
The front-end is PHP and connection is made via ODBC, I've tried wrapping the parameter in single quotes and filtering them out in the stored procedure before the list gets to the query but that doesn't seem to work.
The error I'm getting is:
Conversion failed when converting the varchar value '1,2,4,6,212' to data type int.
I've never done this before and research so far has yielded no positive results.
Firstly, let's use a SQL Function to perform the split of the delimited data:
CREATE FUNCTION dbo.Split
(
#RowData nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Data nvarchar(100)
)
AS
BEGIN
Declare #Cnt int
Set #Cnt = 1
While (Charindex(#SplitOn,#RowData)>0)
Begin
Insert Into #RtnValue (data)
Select
Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
Set #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
Set #Cnt = #Cnt + 1
End
Insert Into #RtnValue (data)
Select Data = ltrim(rtrim(#RowData))
Return
END
To use this, you would simply pass the function the delimited string as well as the delimiter, like this:
SELECT
*
FROM
TableName
WHERE
ColumnName IN (SELECT Data FROM dbo.Split(#DelimitedData, ','))
If you still have issues, due to the datatype, try:
SELECT
*
FROM
TableName
WHERE
ColumnName IN (SELECT CONVERT(int,Data) FROM dbo.Split(#DelimitedData, ','))
You can pass a comma separate list of values. However, you cannot use them as you like in an in statement. You can do something like this instead:
where ','+#List+',' like '%,'+PrimaryKey+',%'
That is, you like to see if the value is present. I'm using SQL Server syntax for concatenation because the question is tagged Microsoft.

Categories