MYSQL: Validate Input with Regular Expressions REGEX - mysql

i have one question with regard to MYSQL. I want to create a function that is able to check whether an Input is given in a specific format.
The output should be in the following shape:
***x x (a) n (n) (n) (n)
with :
x = letters and numbers
n = numbers
a = letters
brackets = optional Values***
So my Solution until now is this (User 'Nick' helped me):
CREATE FUNCTION validate_number(testnumber VARCHAR(7))
RETURNS INT
DETERMINISTIC
RETURN testnumber REGEXP '^[[:alnum:]]{2}[[:alpha:]]?[[:digit:]]{1,4}$';
And this approach works for most cases.
But when i enter a value that exceeds the possible amount of elements (max elements = 7) i get no result.
example:
validate_number('00A00002345')
=> no result.
Do you guys have an idea what the problem is?
Thank you very much in advance.

you are actually pointing out the solution of the problem :)
just change VARCHAR(7) to something bigger VARCHAR(2000)

When I run your function, I get the error:
select validate_number('00A00002345')
Data too long for column 'testnumber' at row 1
You can add a length to the varchar.
CREATE FUNCTION validate_number (
in_testnumber VARCHAR(32000)
)
Or, use text:
CREATE FUNCTION validate_number (
in_testnumber text
)
RETURNS INT
DETERMINISTIC
BEGIN
RETURN (in_testnumber REGEXP '^[[:alnum:]]{2}[[:alpha:]]?[[:digit:]]{1,4}$');
END;

Related

Ada: operator with type conversion and rounding

I have a specific problem that I got some issues figuring out. I want to create an operator in Ada that can divide a float value with a character and then return as an integer.
I understand that the operator should be a function with "/" and some kind of type conversion from float value and a character to an integer. But how would the return value look like and which rounding of the float value would be appropriate?
update.
Let's say I would like to put in the float value -21.8 and the character '2'. The answer should be -11. I created a subprogram for this but I feel like the solution could be something more simple.
function "/"(Float_Val : in Float;
Ch : in Character) return integer is
begin
if Float_Val < Float(0) then return
(Integer(Float'Rounding(Float_Val)) - (Character'Pos(Ch) - (Character'Pos('0'))) + 1) / (Character'Pos(Ch) - (Character'Pos('0')));
else return
(Integer(Float'Rounding(Float_Val)) + (Character'Pos(Ch) - (Character'Pos('0'))) - 1) / (Character'Pos(Ch) - (Character'Pos('0')));
end if;
end "/";
and "/" is called in my main program by
Put(Float_Val / Ch, Width => 0);
I wouldn’t want to call this weird function "/", but if you must ... the skeleton body would be
function "/" (L : Float; R : Character) return Integer is
begin
-- this is where the magic happens
end "/";
I don’t see why you’d need to round L.
Without a bit more explanation as to what algorithm you want to use, that’s all I can say.
Update:
This seems to work quite well:
function "/" (L : Float; R : Character) return Integer
with Pre => R in '1' .. '9'
is
begin
return Integer (L) / (Character'Pos (R) - Character'Pos ('0'));
end "/";
See ARM 4.6(33).
To answer your question about rounding, and to fill in the "magic" in Simon's answer, you must explain better what you want to compute. For example, what should the result of 4.567 / "A" be? And what would do you do to compute it by hand?
Sounds to me like you want to translate something from a poor type language to the rich type language Ada.
If you like to do this the Ada way it will require some reverse engineering to find out what the types ‘integer‘, ‘float’, and ‘character‘ really means. Then I guess an explaining name for ‘/‘ will emerge.

sql create a function

Could someone please help me with this one?
So I need to write a user input function in which I need to concatenate two strings. When outputted, there must be a space between the two strings, note there is not a space in the two strings when inputting them. Test functions with the following, String 1: Spring, String 2: Break!
This is my solution:
create function concatenate(X CHAR,Y CHAR)
Returns CHAR(50)
Return concat(X, ' ', Y);
select concatenate('Spring','Break')
However, the problem is that sql only returns the first letter of each word, which is "S B". But I want it to be "Spring Break"
Any ideas on this one? Helps are very appreciated
Supply a length for the input parameters as well:
create function concatenate(X CHAR(24),Y CHAR(24))
Returns CHAR(50)
Return concat(X, ' ', Y);
select concatenate('Spring','Break')
You need to define the size when you declare the argument.
create function con(X char(50), Y char(50))
returns char(100)
You have to specify the size of CHAR(), otherwise it will use the default CHAR(1), and you can't get want you want.
eg:
create function hello(x char(10),y char(10))
returns char(30) deterministic
return concat(x,' ',y)`
select hello('Hello','World');
Hello World

SQL Server 2008: why doesn't BETWEEN handle strings which include the dash (-)?

My applications pulls rows from a table which contain a column = StringA. The user enters 2 parameters, From and Thru strings, and if she enters the same string in both, and the string has an embedded dash, it's not working.
Why doesn't the following return True where ColumnA and StringA = 'medi-care', but it does return true where ColumnA and StringA = 'medicare' (no dash)?
IF ColumnA between StringA and StringA...
I also tried:
IF ColumnA <= StringA and ColumnA >= StringA...
Is this a bug? I tried appending a 'z' to the Thru parameter string - still didn't work for the string with a dash embedded. Can you suggest a way to make this work?
Is it possible that you actually have an en dash or em dash in one of them but not the other. Often times it is very difficult to tell. Ex:
Declare #StringA varchar(20)
Declare #ColumnA VarChar(20)
Select #StringA = 'medi-care',
#ColumnA = 'medi—care'
Select 'They Match'
Where #StringA = #ColumnA
Note that in this example, #ColumnA actually has an en dash instead of a dash. If you look closely, you may be able to tell, but it is very difficult to notice a difference unless you are specifically looking for it.
It works for me. I ran this on SQL 2008R2:
DECLARE #Test TABLE (
ColA varchar(7)
);
INSERT INTO #Test (ColA) VALUES ('a-z');
SELECT * FROM #Test WHERE ColA BETWEEN 'a-z' AND 'a-z';
And I got the result of 'a-z'. There must be something else in your data that is causing the non-match. Blank spaces or other invisible characters.

Function with return values

I have written a function which takes the Name as input and returns Suffix.
I want to return the position of suffix in a name with a function.
How can i do that.
Could any one please help me doing it.
there is no need to create special function fot this. it already exists in t-sql.
its name is PATINDEX
Example:
declare #pat varchar(128)
set #pat = '_suf'
select login, Patindex('%'+#pat, login) as suffix_index from clients

number_format() with MySQL

hey i need a way to get a formated number from my column decimal(23,2) NOT NULL DEFAULT '0.00'
in php i could use this function number_format('1111.00', 2, ',', '.');
it would return 1.111,00 (in Germany we use , to define decimal numbers)
how would i do this in mysql? with string replaces?
http://blogs.mysql.com/peterg/2009/04/
In Mysql 6.1 you will be able to do FORMAT(X,D [,locale_name] )
As in
SELECT format(1234567,2,’de_DE’);
For now this ability does not exist, though you MAY be able to set your locale in your database my.ini check it out.
With performance penalty and if you need todo it only in SQL you can use the FORMAT function and 3 REPLACE :
After the format replace the . with another char for example #, then replace the , with a . and then the chararacter you choose by a , which lead you for your example to 1.111,00
SELECT REPLACE(REPLACE(REPLACE(FORMAT("1111.00", 2), ".", "#"), ",", "."), "#", ",")
You can use
SELECT round(123.4566,2) -> 123.46
FORMAT(X,D) Formats the number X to a format like '#,###,###.##', rounded to D decimal places, and returns the result as a string. If D is 0, the result has no decimal point or fractional part.
SELECT FORMAT(12332.123456, 4);
-> '12,332.1235'
Antonio's answer
CONCAT(REPLACE(FORMAT(number,0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))
is wrong; it may produce incorrect results!
For example, if "number" is 12345.67, the resulting string would be:
'12.346,67'
instead of
'12.345,67'
because FORMAT(number,0) rounds "number" up if fractional part is greater or equal than 0.5 (as it is in my example)!
What you COULD use is
CONCAT(REPLACE(FORMAT(FLOOR(number),0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))
if your MySQL/MariaDB's FORMAT doesn't support "locale_name" (see MindStalker's post - Thx 4 that, pal). Note the FLOOR function I've added.
At least as far back as MySQL 5.5 you can use format:
SELECT FORMAT(123456789.123456789,2);
/* produces 123,456,789.12 */
SELECT FORMAT(123456789.123456789,2,'de_DE');
/*
produces 123.456.789,12
note the swapped . and , for the de_DE locale (German-Germany)
*/
From the MySQL docs:
https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_format
Available locales are listed elsewhere in the docs:
https://dev.mysql.com/doc/refman/5.5/en/locale-support.html
CREATE DEFINER=`yourfunctionname`#`%` FUNCTION `money`(
`betrag` DECIMAL(10,2)
)
RETURNS varchar(128) CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
return(
select replace(format(cast(betrag as char),2),',',"'") as betrag
)
will creating a MySql-Function with this Code:
select replace(format(cast(amount as char),2),',',"'") as amount_formated
You need this:
CONCAT(REPLACE(FORMAT(number,0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))