Function with return values - sql-server-2008

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

Related

MYSQL: Validate Input with Regular Expressions REGEX

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;

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

Calling functions within function in MySQL returns NULL

I don't understand why when I call my SQL Function inside another Function values are lost. Basically I have something like this:
CREATE FUNCTION `myCustomFunctionA`(paramOne INTEGER, paramTwo INTEGER) RETURNS INT(11)
BEGIN
DECLARE outputOne INT(11);
DECLARE outputTwo INT(11);
SET outputOne = myCustomFunctionB(paramOne);
SET outputTwo = myCustomFunctionB(paramTwo);
RETURN myCustomFunctionC(outputOne, outputTwo);
END
Please note that all of these functions return each an integer when called outside myCustomFunctionA. I.E: Running SELECT myCustomFunctionB(paramTwo); actually returns X value and same for paramOne. However when these functions are called inside myCustomFunctionA it's always returning NULL.
So far I tried to return directly paramOne and paramTwo and values are correct. But if I set function to return outputOne or outputTwo after running myCustomFunctionB then they'd also return NULL.
This seems to be something silly I'm missing but I can't see it so any help or tip in the right direction would be really apprecciated. Thanks.

Mysql recursive procedure

I have a table name css_diectory with 3 columns directory_id, directory-name and root_directory. I am storing hierarchical directory structure in this table. I have written a procedure to retrieve all the descendants given the directory_id. But it doesn't work. Can anyone please help me.
Here is the procedure
CREATE PROCEDURE getDescendants
(IN rootId varchar(32), INOUT desecendantsFolderId varchar(3200))
BEGIN
DECLARE endOfRecord INTEGER DEFAULT 0;
DECLARE folderId varchar(32) DEFAULT "";
DECLARE folderName varchar(32) DEFAULT "";
DECLARE folderCursor CURSOR FOR
Select directory_id, directory_name from css_directory where root_directory=rootId;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET endOfRecord = 1;
OPEN folderCursor;
getFolderId: LOOP
FETCH folderCursor INTO folderId, folderName;
IF endOfRecord = 1 THEN
LEAVE getFolderId;
END IF;
Call getDescendants(folderId,desecendantsFolderId);
SET desecendantsFolderId = CONCAT(folderId,",",desecendantsFolderId);
call getDescendants(folderId,desecendantsFolderId);
END LOOP getFolderId;
END
Edit: The output of this procedure is always a null set. It does not produce any error
I'm not 100% sure I follow what you're doing, but it looks like there's a problem here:
SET desecendantsFolderId = CONCAT(folderId,",",desecendantsFolderId);
When any argument to CONCAT() is null, then the return value is null. Presumably descendantsFolderId is initially null, and if so, I don't see where that would change.
There are several ways to remedy this, but here is one of them:
SET desecendantsFolderId = NULLIF(CONCAT_WS(",",folderId,desecendantsFolderId),"");
CONCAT_WS() is like CONCAT(), except the first argument is used as a separator amd null arguments beyond the first one are disregarded, and empty string is returned if all subsequent arguments are null. NULLIF() is probably not technically needed, based on the rest of the code, but will ensure that the final result of CONCAT_WS() will be turned back to null if the input args are indeed all null.

Case Insensitive REPLACE for MySQL

Is there a case insensitive Replace for MySQL?
I'm trying to replace a user's old username with their new one within a paragraph text.
$targetuserold = "#".$mynewusername;
$targetusernew = "#".$newusername;
$sql = "
UPDATE timeline
SET message = Replace(message,'".$targetuserold."', '".$targetusernew."')
";
$result = mysql_query($sql);
This is missing the instances where the old username is a different case. Example: replacing "Hank" with "Jack" in all the rows in my database will leave behind instances of "hank".
An easier way that works without any stored function:
SELECT message,
substring(comments,position(lower('".$targetuserold."') in message) ) AS oldval
FROM timeline
WHERE message LIKE '%".$targetuserold."%'
gives you the exact, case sensitive spellings of the username in all messages. As you seem to run that from a PHP script, you could use that to collect the spellings together with the corresponding IDs, and then run a simple REPLACE(message,'".$oldval.",'".$targetusernew."') on that. Or use the above as sub-select:
UPDATE timeline
SET message = REPLACE(
message,
(SELECT substring(comments,position(lower('".$targetuserold."') in message))),
'".$targetusernew."'
)
Works like a charm here.
Credits given to this article, where I got the idea from.
Here it is:
DELIMITER $$
DROP FUNCTION IF EXISTS `replace_ci`$$
CREATE FUNCTION `replace_ci` ( str TEXT,needle CHAR(255),str_rep CHAR(255))
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE return_str TEXT DEFAULT '';
DECLARE lower_str TEXT;
DECLARE lower_needle TEXT;
DECLARE pos INT DEFAULT 1;
DECLARE old_pos INT DEFAULT 1;
SELECT lower(str) INTO lower_str;
SELECT lower(needle) INTO lower_needle;
SELECT locate(lower_needle, lower_str, pos) INTO pos;
WHILE pos > 0 DO
SELECT concat(return_str, substr(str, old_pos, pos-old_pos), str_rep) INTO return_str;
SELECT pos + char_length(needle) INTO pos;
SELECT pos INTO old_pos;
SELECT locate(lower_needle, lower_str, pos) INTO pos;
END WHILE;
SELECT concat(return_str, substr(str, old_pos, char_length(str))) INTO return_str;
RETURN return_str;
END$$
DELIMITER ;
Usage:
$sql = "
UPDATE timeline
SET message = replace_ci(message,'".$targetuserold."', '".$targetusernew."')
";
My solution ultimately was that I cannot do a case insensitive Replace.
However, I did find a workaround.
I was trying to have a feature where a user can change their username. The system would then need to update wherever #oldusername was found in all the messages in the database.
The problem was... people wouldn't type other people's usernames in the correct case that it is found in the members table. So when the user would change their username, it wouldn't catch those instances of #oldSeRNAmE because of it not matching the case of the real format of the oldusername.
I don't have permission with my GoDaddy shared server to do this with a customized SQL function, so I had to find a different way.
My solution: Upon inserting new messages into the database, whenever a username is found in the new message, I have an UPDATE statement at that point to replace the username they typed with the correct formatted case that is found in the members table. That way, if that person ever wants to change their username in the future, all the instances of that username in the database will all be the same exact formatted case. Problem solved.