I have this code which is currently returning 0 regardless if the string contains the substring or not. It should return 1 if the substring is found.
CREATE FUNCTION dbo.checkLetters (#MESSAGE VARCHAR)
RETURNS INTEGER
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE #value INTEGER;
IF #MESSAGE LIKE '%findMe%'
SET #value = 1
ELSE
SET #value = 0
RETURN #value
END;
I also tried using charindex in my IF statement to no avail. Am I missing something simple here?
Testing like so:
SELECT dbo.checkletters('dLHLd');
use (#MESSAGE VARCHAR(max)) as a input parameter. or instead of max specify the length, currently in your function it is only 1. That is the issue.
Modify your function as given below:
ALTER FUNCTION dbo.checkLetters (#MESSAGE VARCHAR(max))
RETURNS INTEGER
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE #value INTEGER;
DECLARE #ExpressionToFind VARCHAR(50)
SET #ExpressionToFind = 'findme'
IF #MESSAGE LIKE '%' + #ExpressionToFind + '%'
SET #value = 1
ELSE
SET #value = 0
RETURN #value
END;
The problem was in your input parameter.
Your function could be rewritten as:
CREATE FUNCTION dbo.checkLetters (#MESSAGE VARCHAR(MAX))
RETURNS BIT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN CAST(CHARINDEX('findMe', #MESSAGE) AS BIT);
END
CHARINDEX will find position of #MESSAGE in given string and if it's higher than 1, it will output 1 (bit operator).
Related
I am trying to print Alphabets by creating UDF scalar function.
Here is my code:
create function [dbo].[fnalphabets]()
returns varchar
as begin
declare #num int=65
while(#num<=90)
begin
set #num=#num+1
end
return char(#num)
end
when I am calling this function using
select dbo.fnalphabets()
It doesn't returns expected result. could anyone let me know what is wrong with my code?
No need of Loop or Function anything. Just take Spt_Values table from master database for numbers and do cast them to Char
SELECT CHAR(number)
FROM master.dbo.spt_values
WHERE type = 'p'
AND NUMBER BETWEEN 65
AND 90
ORDER BY NUMBER
Edit:
From Comments : UDF for the above code
Go
ALTER FUNCTION [dbo].[fnalphabets]()
RETURNS VARCHAR(MAX)
AS BEGIN
DECLARE #Alphabates VARCHAR(130)='';
SELECT #Alphabates = #Alphabates +CHAR(number) +'
'
FROM master.dbo.spt_values
WHERE type = 'p'
AND NUMBER BETWEEN 65
AND 90
ORDER BY NUMBER
RETURN #Alphabates
END
Try this: I changed its return varchar size here and declare variable to Store the alphabet string. and storing char values in it in while loop. as below and return the same alphabet string.
CREATE FUNCTION [dbo].[fnalphabets]()
RETURNS VARCHAR(MAX)
AS BEGIN
DECLARE #num INT=65
DECLARE #Alphabates VARCHAR(100)=''
WHILE(#num<=90)
BEGIN
SET #Alphabates=#Alphabates+char(#num)
SET #num=#num+1
END
RETURN #Alphabates
END
TRY THIS: you can use Table Valued Functions as below, it will give you each A-Z in separate rows:
CREATE FUNCTION [dbo].[fnalphabets]()
RETURNS #list TABLE (alphabet VARCHAR(10))
BEGIN
DECLARE #num INT=65
WHILE(#num<=90)
BEGIN
INSERT INTO #list SELECT CHAR(#num)
SET #num=#num+1
END
RETURN
END
SELECT * FROM [dbo].[fnalphabets]()
I wrote a user defined function which takes price as input parameter and returns if the input is greater than zero or not.
https://stackoverflow.com/editing-help
I have tried as follows.
create function fn_GreateCheck(#value int)
returns varchar(20)
as
begin
select case
when #value >0 then 'Greater'
when #value <0 then 'Lesser'
end
return #value
end
Please help me on this
Thanks.
Try something like this:
create function dbo.fn_GreateCheck(#value int)
returns varchar(20)
as
begin
declare #ret VARCHAR(20) = (case
when #value >0 then 'Greater'
when #value <0 then 'Lesser'
else 'Zero'
end)
return #ret
end
GO
select dbo.fn_GreateCheck (1000) --> Greater
select dbo.fn_GreateCheck (-10) --> Lesser
select dbo.fn_GreateCheck (0) --> Zero
select dbo.fn_GreateCheck (NULL) --> Zero
GO
A user defined function cannot return data to the client, so you have to catch the result in a variable and return the value. To return a result set, you have to define Table-value user defined function.
I have the following function to remove set of character from a given string:
ALTER function removalspchar(#Name varchar(30))
returns varchar(500)
As
Begin
declare #sub char(1)
while patindex('%[-:;&, ]%',#Name)>0
begin
set #sub=substring(#Name,patindex('%[-:;&, ]%',#Name),1)
set #Name = replace(#Name,#sub,'')
end
return #Name
End
select dbo.removalspchar('CORP - Sovereign & Public Finance')
But the ouput of the following function coming as : CORPSovereignPublicFina rather than CORPSovereignPublicFinance.
Can somebody let me know what I am doing incorrect or a better way to resolve this issue.
Perhaps, you should increase length of param (#Name varchar(30)) say (#Name varchar(100)).
I am trying to write a function which processes a column value and returns the value with everything before the '#' symbol.
I have managed to do this so far by using the following code:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4)
AS
BEGIN
DECLARE #staffinitals varchar(4)
SET #staffinitals = (SELECT substring(#staffcode,0, CHARINDEX('#',#staffcode)))
Return #staffinitials
END
Example result from function - Parameter in = ABC#123, Returns = ABC.
This works but then exclusively returns every result where the column contained an # value and the remaining results without the # are omitted. I.e. ABC#123 returns ABC but XYZ does not return anything.
How can I amend the code to give me both sets of values? I imagine I would have to put an 'IF' statement in there but I am unsure how to write it to get the results I want.
Many thanks in advance :)
Mike
You are almost there:
ALTER FUNCTION fnStaffCodeConvert (#staffcode varchar(10))
RETURNS VARCHAR(4)
AS
BEGIN
DECLARE #staffinitals AS VARCHAR(4)
if CHARINDEX('#',#staffcode) <> 0
SET #staffinitals = (SELECT substring(#staffcode,0, CHARINDEX('#',#staffcode)))
Else
SET #staffinitals = #staffcode
RETURN #staffinitals
END
You can do what you want with a case:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4);
AS
BEGIN
DECLARE #staffinitals varchar(4);
SET #staffinitals = (SELECT (case when #staffcode like '%#%'
then substring(#staffcode,0, CHARINDEX('#',#staffcode)
else #staffcode
end));
Return #staffinitials;
END
But wait, you can simplify this further:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4)
AS
BEGIN
DECLARE #staffinitals varchar(4)
SELECT #staffinitials = (case when #staffcode like '%#%'
then substring(#staffcode,0, CHARINDEX('#',#staffcode)
else #staffcode
end);
Return #staffinitials;
END;
I have the following code to cast nvarchar to integer:
cast(#value as int)
However I have no control of the parameter #value, hence the code might fail. Is there anyway to check if a cast is possible before doing a cast?
Well, in SQL Server 2012 you could use the new TRY_CAST(), but with SQL Server 2008, you should be able to use ISNUMERIC(), and then include handling for values that do not pass that test.
I've recently answered a question about this and using ISNUMERIC to CAST to an INT won't work by itself. Reason being, ISNUMERIC returns true for non integer numbers (1.5) for example.
Here was a recent answer on the subject:
https://stackoverflow.com/a/14692165/1073631
Consider adding an additional check using CHARINDEX with ISNUMERIC, or what I prefer, use a Regular Expression to validate the data.
And here is a Fiddle demonstrating the problem with using ISNUMERIC on it's own. And the Fiddle using a regular expression instead that works.
DECLARE #Test nvarchar(10)
SET #Test = '1.5'
--Works
SELECT CASE WHEN #Test NOT LIKE '%[^0-9]%' THEN CAST(#Test as int) ELSE 0 END
-- Produces Error
SELECT CASE WHEN ISNUMERIC(#Test) = 1 THEN CAST(#Test as int) ELSE 0 END
Good luck.
I generally use the following, it seems to cover all the situations.
SELECT CASE WHEN 1 = ISNUMERIC(#value + '.0') THEN CAST(#value as int) ELSE 0 END
It takes advantage of the fact that "ISNUMERIC" will not allow two periods. The "TRY_CAST" in SQL Server 2012+ is a much better solution though.
The proper test is:
select (case when isnumeric(val) = 1 and val not like '%e%' and val not like '%.%'
then cast(val as int)
end)
The function isnumeric() returns 1 for anything that looks like a float, so you have to be careful.
You can also use what I consider to be a peculiarity of SQL Server. You can cast the floating value 1.23 to an int, but you cannot cast the string value. So, the following also works:
select (case when isnumeric(val) = 1
then cast(cast(val as float) as int)
end)
Maybe we can do something like this:
declare #value as nvarchar(10) = 'A';
begin try
select cast(#value as int);
end try
begin catch
-- do something
end catch
Use a procedure with a TRY CATCH block to suppress errors
i.e.
CREATE PROCEDURE p_try_cast
#type nvarchar(MAX),
#value nvarchar(MAX)
AS
BEGIN
BEGIN TRY
DECLARE #sql varchar(MAX)
DECLARE #out_table TABLE(value varchar(MAX))
SET #sql = 'SELECT CONVERT(varchar(max), CAST(''' + #value + ''' AS ' + #type + '))'
INSERT #out_table
EXECUTE (#sql)
IF EXISTS ( SELECT 1 FROM #out_table WHERE value = #value)
RETURN 1
RETURN 0
END TRY
BEGIN CATCH
RETURN 0
END CATCH
END
GO
Now you can call that with the passed string and desired type and the proc returns 1 for success and 0 for failure
DECLARE #ret int
-- This returns 0 - Fail
EXEC #ret = p_try_cast 'integer', '1.5'
-- This returns 1 - Success
EXEC #ret = p_try_cast 'integer', '1.5'
-- This returns 0 - Fail
EXEC #ret = p_try_cast 'char(4)', 'HELLO'
-- This returns 1 - Success
EXEC #ret = p_try_cast 'char(4)', 'HELL'