Function to check if a string contains uppercase characters? - sql-server-2014

I need to create a SQL Server function to check if an input string contains any uppercase characters. If yes then it should return "OK". If no It should return "NOT OKAY".
When the below statements are executed, it should return the expected values as below.
PRINT dbo.CheckStringOfUpperAlphaOK('abc') -- Expected: "NOT OK"
PRINT dbo.CheckStringOfUpperAlphaOK('ABC') -- Expected: "OK"
this is what i tried, but i do not know to specify the return values as mentioned above.
CREATE FUNCTION CheckStringOfUpperAlphaOK (#String varchar(MAX))
RETURNS VARCHAR(6)
AS
BEGIN
Declare #KeepValues as varchar(50)
Set #KeepValues = '%[^ ][A-Z]%'
While PatIndex(#KeepValues collate Latin1_General_Bin, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#KeepValues collate
Latin1_General_Bin, #Temp) + 1, 0, ' ')
RETURN #Temp
END

How about this? I just simply compare the #String parameter to a (simplified) pattern that checks for an uppercase character - and based on that index, I define the return values and return the appropriate response:
CREATE FUNCTION CheckStringOfUpperAlphaOK(#String varchar(MAX))
RETURNS VARCHAR(6)
AS
BEGIN
DECLARE #UpperCasePos BIGINT
SELECT #UpperCasePos = PATINDEX('%[A-Z]%' collate Latin1_General_Bin, #String)
DECLARE #Response VARCHAR(6)
IF #UpperCasePos > 0
SET #Response = 'OK'
ELSE
SET #Response = 'NOT OK'
RETURN #Response
END

If you want to know if the string contains at least one upper-case character, why not do a case-sensitive comparison with the lower-caser version of the string?
CREATE FUNCTION CheckStringOfUpperAlphaOK
(
#STR VARCHAR(MAX)
)
RETURNS VARCHAR(6)
AS
BEGIN
RETURN CASE
WHEN #STR = LOWER(#STR) COLLATE Latin1_General_Bin THEN 'NOT OK'
ELSE 'OK'
END
END
;

Related

Is it possible to search of a text in SSRS via Filters?

I would like to have a multiple values Paramter with text1, text2, text3
SSRS should only show me the rows that contain one or all of this Parameter values in a column.
I notice you can set a filter in a Dataset or the tablix. The problem is I do not have something a function that do both LIKE and IN
Do you someone have an idea?
I tried already the LIKE function and the VALUE =”*”+”Parameters!PAR.Value”+”*”.
It did work, but not on a multiple values parameter.
I don't think you will be able to do this using dataset filters using a multi-value parameter.
However, you should be able to change your dataset query to handle this.
CREATE PROC myProc (#myParameter varchar(1000))
AS
SELECT * FROM myTable t
JOIN string_split(#myParameter, ',') p on t.myColumn like '%' + p.value + '%'
When you pass the parameter to the stored proc you can use the following expression
=JOIN(Parameters!myParameter.Value, ",")
This will simply join each of your parameter values into a single comma separated string string ready to pass to the procedure.
If you do not have a version of SQL Server that support string_split
Hers's the code to create one. There are smaller versions around on the internet but this one was designed to handle special cases as well as the typical single character delimiters.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [Split](#sText varchar(8000), #sDelim varchar(20) = ' ')
RETURNS #retArray TABLE (idx smallint Primary Key, value varchar(8000))
AS
BEGIN
DECLARE #idx smallint,
#value varchar(8000),
#bcontinue bit,
#iStrike smallint,
#iDelimlength tinyint
IF #sDelim = 'Space'
BEGIN
SET #sDelim = ' '
END
SET #idx = 0
SET #sText = LTrim(RTrim(#sText))
SET #iDelimlength = DATALENGTH(#sDelim)
SET #bcontinue = 1
IF NOT ((#iDelimlength = 0) or (#sDelim = 'Empty'))
BEGIN
WHILE #bcontinue = 1
BEGIN
--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.
IF CHARINDEX(#sDelim, #sText)>0
BEGIN
SET #value = SUBSTRING(#sText,1, CHARINDEX(#sDelim,#sText)-1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET #iStrike = DATALENGTH(#value) + #iDelimlength
SET #idx = #idx + 1
SET #sText = LTrim(Right(#sText,DATALENGTH(#sText) - #iStrike))
END
ELSE
BEGIN
--If you can't find the delimiter in the text, #sText is the last value in
--#retArray.
SET #value = #sText
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Exit the WHILE loop.
SET #bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE #bcontinue=1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(#sText)>1
BEGIN
SET #value = SUBSTRING(#sText,1,1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
SET #idx = #idx+1
SET #sText = SUBSTRING(#sText,2,DATALENGTH(#sText)-1)
END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT #retArray (idx, value)
VALUES (#idx, #sText)
SET #bcontinue = 0
END
END
END
RETURN
END
GO
To test this try something like
select * from Split('abc,def,ghi', ',')
which will return

how does mysql user defined function know a selected row was found?

a MYSQL user defined function selects a row from a table. How does the UDF code determine if the selected row was found in the table?
CREATE FUNCTION snippetFolder_folderPath(folder_id int)
RETURNS varchar(512)
BEGIN
declare vFolder_id int;
declare vParent_id int;
declare vPath varchar(512) default '';
declare vFolderName varchar(256) default '';
set vFolder_id = folder_id;
build_path:
while (vFolder_id > 0) do
/* -------- how to know this select statement returns a row?? ---------- */
select a.parent_id, a.folderName
into vParent_id, vFolderName
from SnippetFolder a
where a.folder_id = vFolder_id;
if vPath = ' ' then
set vPath = vFolderName;
else
set vPath = concat_ws( '/', vFolderName, vPath );
end if ;
set vFolder_id = vParent_id;
end while ;
return vPath;
END
https://dev.mysql.com/doc/refman/8.0/en/select-into.html says:
If the query returns no rows, a warning with error code 1329 occurs (No data), and the variable values remain unchanged.
So you could declare a continue handler on warnings, something like the example from the documentation:
BEGIN
DECLARE i INT DEFAULT 3;
DECLARE done INT DEFAULT FALSE;
retry:
REPEAT
BEGIN
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
SET done = TRUE;
END;
IF done OR i < 0 THEN
LEAVE retry;
END IF;
SET i = i - 1;
END;
UNTIL FALSE END REPEAT;
END
I'll leave it to you to read the documentation and adapt that example to your table and your loop.
Alternatively, if you're using MySQL 8.0 you can use recursive common table expression:
CREATE FUNCTION snippetFolder_folderPath(vFolder_id int)
RETURNS varchar(512)
BEGIN
DECLARE vPath varchar(512) DEFAULT '';
WITH RECURSIVE cte AS (
SELECT folderName, parent_id, 0 AS height
FROM SnippetFolder WHERE folder_id = vFolder_id
UNION
SELECT f.folderName, f.parent_id, cte.height+1
FROM SnippetFolder AS f JOIN cte ON cte.parent_id = f.folder_id
)
SELECT GROUP_CONCAT(folderName ORDER BY height DESC SEPARATOR '/')
INTO vPath
FROM cte;
RETURN vPath;
END
The recursive CTE result is all the ancestors of the row matching vFolder_id, and then one can use GROUP_CONCAT() to concatenate them together as one string.

Replace character in a string with space

I need the following output in SQL server 2008
problem is to remove numbers from string
i.e column name is associated_id which is nvarchar type and value could be (23,34,45)
But I want the following result (23,45).
May this help
CREATE FUNCTION [dbo].[GetAlphabetFromAlphaNumeric]
(#strAlphaNumeric VARCHAR(500))
RETURNS VARCHAR(500)
AS
BEGIN
DECLARE #intAlpha INT
SET #intAlpha = PATINDEX('%[0-9]%', #strAlphaNumeric)
BEGIN
WHILE #intAlpha > 0
BEGIN
SET #strAlphaNumeric = STUFF(#strAlphaNumeric, #intAlpha, 1, '' )
SET #intAlpha = PATINDEX('%[0-9]%', #strAlphaNumeric )
END
END
RETURN ISNULL(#strAlphaNumeric,0)
END

MySQL replace only first occurence in text field/column

I wrote a function to replace first occurence in MySQL Text colum, but it's a little bit complicated...
UPDATE
table_name
SET
column=CONCAT(
LEFT(column,LOCATE('some string', column)-1),
CONCAT(substring(column, LOCATE('some string', column) + $length),
'new string'))
Where $length is length of string, that we want to replace. If we use php it is strlen() function but in MySQL it would be CHAR_LENGTH() function.
Do you know better way to replace only first match in text columns ?
You could use TRIM:
UPDATE table_name SET column = TRIM(LEADING 'some string' FROM column);
assuming 'some string' does not have more than 1 consecutive occurrence at the start of the contents of 'column'.
So, it would work if column contained:
"some string foo some string"
but not for:
"some string some string foo some string"
Edit - Added MySQL function to simplify process
I can't see an alternative to the mechanism you are using, but executing it could be simplified by creating a function in MySQL (if you have the privilege):
delimiter $$
create function replace_first(
p_text_to_search varchar(255),
p_text_to_replace varchar(255)
)
returns varchar(255)
begin
declare v_found_pos int(11);
declare v_found_len int(11);
declare v_text_with_replacement varchar(255);
select locate(p_text_to_replace, p_text_to_search)
into v_found_pos;
select char_length(p_text_to_replace)
into v_found_len;
select concat(
left(p_text_to_search, v_found_pos-1),
mid(p_text_to_search, (v_found_pos + v_found_len))
)
into v_text_with_replacement;
return v_text_with_replacement;
end$$
delimiter ;
then you can call it using:
select replace_first('bar foo foo baz foo', 'foo');
result:
'bar foo baz'
I have created function can replace any index of text:
/************** REPLACE_TEXT_OF_INDEX ***************/
DROP FUNCTION IF EXISTS REPLACE_TEXT_OF_INDEX;
DELIMITER $$
CREATE FUNCTION REPLACE_TEXT_OF_INDEX(_text VARCHAR(3072), _subText VARCHAR(1024), _toReplaceText VARCHAR(1024), _index INT UNSIGNED)
RETURNS VARCHAR(3072)
BEGIN
DECLARE _prefixText, _sufixText VARCHAR(3072);
DECLARE _starIndex INT;
DECLARE _loopIndex, _textIndex INT UNSIGNED DEFAULT 0;
IF _text IS NOT NULL AND LENGTH(_text) > 0 AND
_subText IS NOT NULL AND LENGTH(_subText) > 0 AND
_toReplaceText IS NOT NULL AND _index > 0 THEN
WHILE _loopIndex < LENGTH(_text) AND _textIndex < _index DO
SELECT LOCATE(_subText, _text, _loopIndex + 1) INTO _loopIndex;
IF _loopIndex > 0 THEN
SET _textIndex = _textIndex + 1;
ELSE
SET _loopIndex = LENGTH(_text) + 1;
END IF;
END WHILE;
IF _textIndex = _index THEN
SELECT LOCATE(_subText, _text, _loopIndex) INTO _starIndex;
SELECT SUBSTRING(_text, 1, _starIndex -1) INTO _prefixText;
SELECT SUBSTRING(_text, _starIndex + LENGTH(_subText), LENGTH(_text)) INTO _sufixText;
RETURN CONCAT(_prefixText, _toReplaceText, _sufixText);
END IF;
END IF;
RETURN _text;
END;
$$
DELIMITER ;
SELECT REPLACE_TEXT_OF_INDEX('WORD1 WORD2 WORD3 WORD4 WORD5', 'WORD', '*',1);

mysql replace regular expression what ever in the braces in a string

Below are the few rows of a column data in my mysql database
Data
test(victoryyyyy)king
java(vaaaarrrryy)side
(vkittt)sap
flex(vuuuuu)
k(vhhhhyyy)kk(abcd)k
In all rows there is random string that starts with
(v
and ends with
)
My task :- I have to replace all string from '(v' to ')' with empty space ( that is ' ') I shouldn't touch other values in the braces , in the above case I should not replace (abcd) in the last row
I mean for the above example the result should be
test king
java side
sap
flex
kkk(abcd)k
Could any one please help me ?
Thank You
Regards
Kiran
Mysql doesn't support regexes for replace tasks.
So you can only use string functions to find and substr necessary part.
I wrote my own function for this and it is working . Thanks every one .
drop FUNCTION replace_v;
CREATE FUNCTION replace_v (village varchar(100)) RETURNS varchar(100)
DETERMINISTIC
BEGIN
DECLARE a INT Default 0 ;
DECLARE lengthofstring INT Default 0 ;
DECLARE returnString varchar(100) Default '' ;
DECLARE charString varchar(100) Default '' ;
DECLARE found char(1) default 'N';
declare seccharString varchar(100) Default '' ;
set lengthofstring = length(village);
simple_loop: LOOP
SET a=a+1;
set charString=substr(village,a,1);
if(charString = '(') then
set seccharString=substr(village,a+1,1);
if( seccharString = 'v' || seccharString = 'V' || seccharString = 'p' || seccharString = 'P'
|| seccharString = 'm' || seccharString = 'M' ) then
set found='y';
end if;
end if ;
if(found='n') then
set returnString = concat (returnString,charString);
end if;
if(charString = ')') then
set found='n';
end if ;
IF a>=lengthofstring THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
if ( found = 'y') then
set returnString =village;
end if;
RETURN (replace( returnString,'&', ' '));
END