I have a function in SQL Server (version 2008) which converts a column data to Proper Case (make first letter of a string to upper case and rest to lower). The function works fine, however, there is a need for me to use upper case for data appearing as 'Rto.' There are several records in my table that has for example: 'Rto Dist Inc-Brantford', 'Rto Dist Inc-Orillia' and so on. Originally, the data was all upper case but since I used the function to convert all upper case to Proper case, 'RTO..' has also been converted to Proper Case. I would like to keep Rto in all upper case like this: RTO.
I have included my function below with the last part converting the Rto to RTO but this is where I am getting error message from SQL Server that says:
Msg 102, Level 15, State 1, Procedure ProperCase, Line 29
Incorrect syntax near '#Ret'.
My function:
GO
/****** Object: UserDefinedFunction [dbo].[ProperCase] Script Date: 2022-11-30 9:38:28 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[ProperCase](#Text as varchar(8000))
returns varchar(8000)
as
begin
declare #Reset bit;
declare #Ret varchar(8000);
declare #i int;
declare #c char(1);
if #Text is null
return null;
select #Reset = 1, #i = 1, #Ret = '';
while (#i <= len(#Text))
select #c = substring(#Text, #i, 1),
#Ret = #Ret + case when #Reset = 1 then UPPER(#c) else LOWER(#c) end,
#Reset = case when #c like '[a-zA-Z]' then 0 else 1 end,
#i = #i + 1
**if LEFT(#Ret, 3) = 'Rto'
#Ret = UPPER(#Text);**
return #Ret
end
The block of code in bold:
if LEFT(#Ret, 3) = 'Rto'
#Ret = UPPER(#Text);
was added by me to convert all data appearing as 'Rto.....' to RTO.....
Any guidance to make this code work properly is greatly appreciated
Thank you
I understand why you are using the while loop. It looks like you're trying to make the first character of each word into upper case. I would just add an IF to change the loop variables before entering the while loop. Something like this:
ALTER function [dbo].[ProperCase](#Text as varchar(8000))
returns varchar(8000)
as
begin
declare #Reset bit;
declare #Ret varchar(8000);
declare #i int;
declare #c char(1);
if #Text is null
return null;
select #Reset = 1, #i = 1, #Ret = '';
--Special handling for strings starting with "RTO".
if LEFT(#Text,3) = 'rto'
select #Reset = 1, #i = 4, #Ret = UPPER(LEFT(#Text,3));
while (#i <= len(#Text))
select #c = substring(#Text, #i, 1),
#Ret = #Ret + case when #Reset = 1 then UPPER(#c) else LOWER(#c) end,
#Reset = case when #c like '[a-zA-Z]' then 0 else 1 end,
#i = #i + 1
return #Ret
end
Related
we are having to ID some data coming from a bad import and any help would be appreciated.
For instance a string like below and identifier char for the charindex.
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
The issue we are having is that we can run our test against a hard coded string like the one above and get the result of 'over'. we have tried to put it in a while loop and then we get 'over','or','under'. The Expected Result for us would be only returning 'over', 'under' and not the or.
Our first go at a test was something like below just to see try and split:
DECLARE #InputString Nvarchar(MAX)
DECLARE #IdentifierChar NCHAR(1)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
declare #FirstID int
declare #SecondID int
declare #Length int
declare #TargetString Nvarchar(MAX)
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,1)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
Like I said then we literally just threw it in a hard coded loop and set the value of the substring to the last position of the identifier of the specialcharacter just to test and see how the charindex was splitting out the strings between the quotes and we did not think about it getting the 'or' as well.
so here is the dirty loop:
Set #COUNT = 0
Set #Length = 0
WHILE(#COUNT)<3
BEGIN
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,#Length)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
SET #COUNT = #COUNT+1
Set #Length =#SecondID
END
There's probably a better way to parse this out, but here's my minimal modification to your code to make it work, with comments where I changed things:
DECLARE #InputString Nvarchar(MAX)
DECLARE #IdentifierChar NCHAR(1)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
declare #FirstID int
declare #SecondID int
declare #Length int
declare #TargetString Nvarchar(MAX)
declare #COUNT int -- added this missing from your code above
Set #COUNT = 0
Set #Length = 0
WHILE(#COUNT)<2 -- only need 2 here now
BEGIN
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,#Length)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
SET #COUNT = #COUNT+1
Set #Length =#SecondID+1 -- added one
print #TargetString -- so we can see what it finds
END
Your main issue was updating #Length at the bottom of your loop -- when you thought you were pointing PAST the double quote after "over", you were actually pointing right at it and finding it a second time as an open-quote before " or ".
Here's a User Defined Function that I wrote and keep in my toolbox. This is a slightly off-label use, but it should work well for you.
If we consider this string to be five substrings, delimited by the four double-quote characters, then we can split on those just take substrings 2 and 4. (Getting a third or fourth quoted value would be as easy as getting substrings 6 or 8) Trying to get an element that doesn't exist will just return a NULL.
After executing the CREATE statement below, which will create the dbo.SPLIT_LIST function, you can call it like this:
declare #InputString varchar(255)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
select dbo.SPLIT_LIST(#InputString, '"', 2, ''),
dbo.SPLIT_LIST(#InputString, '"', 4, '')
And you'll get your two output values. What's nice about a function like this is you can just throw it in your select statements and operate over many records at a time, instead of per each.
CREATE function dbo.SPLIT_LIST(
#string nvarchar(max),
#delimiter nvarchar(50),
#i int,
#text_qualifier nvarchar(1)
)
returns nvarchar(max)
/*
returns a selected element from a delimited list
select dbo.SPLIT_LIST_w_Qualifier('"twenty,one","twenty,two","twenty,three"', ',', 2,'"')
returns: 'twenty,two'
Note: can ignore embedded text qualifiers
*/
as
BEGIN
declare #value nvarchar(max),
#d_length int,
#next_delimiter nvarchar(51),
#q_length int, --length of the text qualifier
#trim int,
#using_qualifier int
set #d_length = len(#delimiter)
set #q_length = len(#text_qualifier)
set #string = ltrim(rtrim(#string))
--works by chopping off the leading value from the string each round
while #i > 0 and #string is not null and len(#string) > 0
begin
--if the remaining #string starts with the text qualifier,
--then the currently parsed value should end with the text qualifier+delimiter
if left(#string,1) = #text_qualifier
begin
set #using_qualifier = 1
--chop off leading qualifier
set #string = ltrim(right(#string,(len(#string)-len(#text_qualifier))))
end
else
begin
set #using_qualifier = 0
end
if (#using_qualifier = 0) -- If we are NOT using a text qualifier for this element
begin
if (charindex(#delimiter, #string) > 0) --If there is a remaining delimiter
begin
set #value = ltrim(rtrim(left(#string, charindex(#delimiter, #string)-1)))
set #string = ltrim(rtrim(right(#string, len(#string)-charindex(#delimiter, #string) - #d_length + 1)))
end
else --no remaining delimiters
begin
set #value = #string
set #string = null
end
end
else -- If we ARE using a text qualifier for this element
begin
if (charindex((#text_qualifier+#delimiter), #string) > 0) --If there is a remaining qualifier+delimiter
begin
set #value = ltrim(rtrim(left(#string, charindex((#text_qualifier+#delimiter), #string)-1)))
set #string = ltrim(rtrim(right(#string, len(#string)-charindex((#text_qualifier+#delimiter), #string) - #d_length - #q_length + 1)))
end
else --no remaining qualifier+delimiters
begin
--Does the remaining string END with the text qualifier?
if (charindex(REVERSE(#text_qualifier), REVERSE(#string)) = 1)
begin
set #value = ltrim(rtrim(left(#string, len(#string)-#q_length)))
set #string = null
end
else if (charindex((#text_qualifier), #string) > 0) --Is there a remaining qualifier at all?
begin
set #value = ltrim(rtrim(left(#string, charindex((#text_qualifier), #string)-1)))
set #string = null
end
else --no final closing qualifier
begin
set #value = #string
set #string = null
end
end
end
set #i = #i - 1
--print #value
end
if #i = 0 return #value --should exit here
return NULL --a parse too far exists here
END
Depending on the size of your data set and the complexity of your overall query, you could use a recursive CTE:
;with inputStr as (select 'The quick brown fox jumped "over" or "under" or "around" the log' as s)
,cte as (
select right(s,len(s) - charindex('"',s) + 1) as s --get the first occurence of "
from inputStr
union ALL
select right(right(s,len(s)-1),len(s) - charindex('"',s) + 1) as s --get the second occurence of " in the above string
from cte
where charindex('"',s) > 0 --where " exists
)
select left(s,charindex('"',right(s,len(s)-1))+1) as quoted --select from the first " to the second "
from cte
where (len(s) - len(replace(s,'"',''))) % 2 <> 1 --even number of "
and left(s,charindex('"',right(s,len(s)-1))+1) like '"%"'
Just wanted to update. I continued to toy around with the code and got something to work in case anyone wants to use similar logic in the future. This did what we discussed above.
DECLARE #TargetString NVARCHAR(MAX)
DECLARE #stringLen int
DECLARE #splitTbl TABLE(siteId NVARCHAR(MAX))
DECLARE #idChar NCHAR(1)
SET #TargetString = 'The quick brown fox jumped "over" or "under" the "log"'
SET #stringLen = CHARINDEX(' ', #TargetString)
SET #idChar = '"'
WHILE CHARINDEX(' ', #TargetString) > 0
BEGIN
SET #stringLen = CHARINDEX(' ', #TargetString);
INSERT INTO #splitTbl
SELECT SUBSTRING(#TargetString,1,#stringLen - 1);
SET #TargetString = SUBSTRING(#TargetString, #stringLen + 1,
LEN(#TargetString));
END
DECLARE #buildResults NVARCHAR(MAX)
INSERT INTO #splitTbl
SELECT #TargetString
DECLARE #buildLike NVARCHAR(MAX)
SET #buildLike = '%'+#idChar+'%'
SELECT #buildResults = COALESCE(#buildResults + ', ', '')
+SUBSTRING(siteId, 2, lEN(siteId) - 2)
FROM #splitTbl
WHERE siteId LIKE #buildLike
I am trying to convert a column which is in upper case to proper case but with exceptions like certain acronyms, abbreviations. I am following the below code to implement that. But looks like this will be an ongoing process and so, I want to create a table with the exceptions in order to make it easy to clean the data and I want to be able to call the exceptions table from the function. It would be great if anyone can help me with any codes they have which is similar to this or any ideas on how to implement it.
ALTER FUNCTION [dbo].[Business_ProperCase]
(#Text AS VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
-- declare some variables
DECLARE #Reset BIT; DECLARE #Ret VARCHAR(8000); DECLARE #i INT;
DECLARE #c0 CHAR(1); DECLARE #c1 CHAR(1); DECLARE #c2 CHAR(1);
DECLARE #CaseLen INT;
DECLARE #CaseExceptions VARCHAR(8000);
DECLARE #CaseValue VARCHAR(8000);
-- Set some default values
SELECT #Reset = 1, #i=1, #Ret = '';
-- only apply if all characters are already in uppercase
IF (UPPER(#Text)=#Text COLLATE Latin1_General_CS_AI)
BEGIN
-- add a leading and trailing space to indicate word delimiters (bol & eol)
SET #Text = ' ' + #Text + ' ';
-- cycle through each character,
-- if non-alpha, uppercase next alpha character.
-- if alpha then lowercase subsequent alphas.
WHILE (#i <= LEN(#Text))
SELECT
#c0=SUBSTRING(#Text,#i-2,1), #c1=SUBSTRING(#Text,#i-1,1), #c2=SUBSTRING(#Text,#i,1),
#Ret = #Ret + CASE WHEN #Reset=1 THEN UPPER(#c2) ELSE LOWER(#c2) END,
#Reset = CASE
WHEN #c0 = ' ' AND #c1 = 'M' AND #c2 = 'c' THEN 1
WHEN #c0 = ' ' AND #c1 IN ('D', 'I', 'O') AND #c2 = '''' THEN 1
WHEN #c2 LIKE '[a-zA-Z'']' THEN 0 -- Apply LOWER to any character after alphas or apostrophes
ELSE 1 -- Apply UPPER to any character after symbols/punctuation
END,
#i = #i +1
-- add a trailing space in case the previous rule changed this.
SET #Ret = #Ret + ' ';
-- custom exceptions: this search is case-insensitive and will
-- replace the word to the case as it is written in the list.
-- NOTE: this list has to end with a comma!
SELECT #i=0, #CaseLen=0,
#CaseExceptions = 'ABS,LLC,MD,MBA,MA,
--Want to create a table for these exceptions and call them from this function
-- Loop through exception cases
WHILE CHARINDEX(',', #CaseExceptions, #i+1)>0
BEGIN
-- get the delimited word
SET #CaseLen = CHARINDEX(',', #CaseExceptions, #i+1) - #i
SET #CaseValue = SUBSTRING(#CaseExceptions, #i, #CaseLen)
-- replace it in the original text
SET #Ret = REPLACE(#Ret, ' '+#CaseValue+' ', ' '+#CaseValue+' ')
-- get position of next word
SET #i = CHARINDEX(',', #CaseExceptions, #i+#CaseLen) +1
END
-- remove any leading and trailing spaces
SET #Ret = LTRIM(RTRIM(#Ret));
-- capitalize first character of data irrespective of previous rules
SET #Ret = UPPER(SUBSTRING(#Ret,1,1)) + SUBSTRING(#Ret,2,LEN(#Ret));
END
ELSE
BEGIN
-- return the string unaffected if it is not in uppercase
SET #Ret=#Text
END
RETURN #Ret
END
Create a table (I use TITLE_CASE_EXCEPTION as my example) with a column EXCEPTION
Then it is data driven from there.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[GUI].[fn_TITLE_CASE]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [GUI].[fn_TITLE_CASE]
GO
CREATE FUNCTION [GUI].[fn_TITLE_CASE]
(
#STRING VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
SET QUOTED_IDENTIFIER OFF
DECLARE #RESET BIT
DECLARE #_OUT_STRING VARCHAR(MAX)
DECLARE #I INT
DECLARE #C CHAR(1)
DECLARE #CASE_LEN INT = 0
DECLARE #CASE_EXCEPTIONS VARCHAR(MAX) = ''
DECLARE #CASE_VALUE VARCHAR(MAX) = ''
IF #STRING IS NULL
RETURN NULL
IF #STRING = ''
RETURN #STRING
SELECT #STRING = LOWER(RTRIM(#STRING)), #RESET = 1, #I = 1, #_OUT_STRING = ''
WHILE (#I <= LEN(#STRING))
SELECT
#C = SUBSTRING(#STRING, #I, 1),
#_OUT_STRING = #_OUT_STRING + CASE WHEN #RESET = 1 THEN UPPER(#C) ELSE #C END,
#RESET = CASE WHEN #C LIKE '[a-zA-Z'']' THEN 0 ELSE 1 END,
#I = #I + 1
SELECT #I = 0, #_OUT_STRING = #_OUT_STRING + ' '
SELECT #CASE_EXCEPTIONS = #CASE_EXCEPTIONS + RTRIM(EXCEPTION) + ',' FROM [LOOKUP].TITLE_CASE_EXCEPTION
WHILE CHARINDEX(',', #CASE_EXCEPTIONS, #I + 1) > 0
BEGIN
-- get the delimited word
SET #CASE_LEN = CHARINDEX(',', #CASE_EXCEPTIONS, #I + 1) - #I
SET #CASE_VALUE = SUBSTRING(#CASE_EXCEPTIONS, #I, #CASE_LEN)
-- replace it in the original text
SET #_OUT_STRING = REPLACE(#_OUT_STRING, ' ' + #CASE_VALUE + ' ', ' ' + #CASE_VALUE + ' ')
-- get position of next word
SET #I = CHARINDEX(',', #CASE_EXCEPTIONS, #I + #CASE_LEN) + 1
END
RETURN RTRIM(#_OUT_STRING)
END
GO
Here's an example for you to reference:
declare #s varchar(256) = 'This is a SQL test';
declare #t table (ignore varchar(256) not null);
insert into #t (ignore) values ('SQL');
declare #pos int = 1;
declare #nextpos int;
declare #w varchar(256);
while #pos <= len(#s)
begin
set #nextpos = charindex(' ', #s + ' ', #pos);
set #w = substring(#s, #pos, #nextpos - #pos);
if not exists (select 1 from #t where ignore = #w)
set #s = stuff(
#s, #pos, #nextpos - #pos,
stuff(lower(#w), 1, 1, upper(left(#w, 1)))
);
set #pos = #nextpos + 1;
select #s;
end
To answer the original request.. set up a table "Exceptions" with a single column ConcatList of type nvarchar (100) and add the exceptions to this table... then create a view with to concatenate them together...
create table exceptions (ConcatList nvarchar(100))
create view [dbo].vExceptions
as
Select distinct
substring(
(
Select ','+ up.ConcatList AS [text()]
From exceptions up
ORDER BY up.ConcatList
For XML PATH ('')
), 2, 4000) [exceptions]
From exceptions p
Here is a slightly enhanced version of the stored procedure from the question.
(although an admittedly inelegant solution) to account for:
Lower case words (of, the, an, etc)
Hhyphenated acronyms
Exceptions that are immediately preceeded or followed with a dash or comma.
alter FUNCTION [dbo].[Business_ProperCase]
(#Text AS VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
-- declare some variables
DECLARE #Reset BIT; DECLARE #Ret VARCHAR(8000); DECLARE #i INT;
DECLARE #c0 CHAR(1); DECLARE #c1 CHAR(1); DECLARE #c2 CHAR(1);
DECLARE #CaseLen INT;
DECLARE #CaseExceptions VARCHAR(8000);
DECLARE #CaseValue VARCHAR(8000);
-- Set some default values
SELECT #Reset = 1, #i=1, #Ret = '';
-- only apply if all characters are already in uppercase
IF (UPPER(#Text)=#Text COLLATE Latin1_General_CS_AI)
BEGIN
-- add a leading and trailing space to indicate word delimiters (bol & eol)
SET #Text = ' ' + #Text + ' ';
-- cycle through each character,
-- if non-alpha, uppercase next alpha character.
-- if alpha then lowercase subsequent alphas.
WHILE (#i <= LEN(#Text))
SELECT
#c0=SUBSTRING(#Text,#i-2,1), #c1=SUBSTRING(#Text,#i-1,1), #c2=SUBSTRING(#Text,#i,1),
#Ret = #Ret + CASE WHEN #Reset=1 THEN UPPER(#c2) ELSE LOWER(#c2) END,
#Reset = CASE WHEN #c0 = ' ' AND #c1 = 'M' AND #c2 = 'c' THEN 1
WHEN #c0 = ' ' AND #c1 IN ('D', 'I', 'O') AND #c2 = '''' THEN 1
WHEN #c2 LIKE '[a-zA-Z'']' THEN 0 -- Apply LOWER to any character after alphas or apostrophes
ELSE 1 -- Apply UPPER to any character after symbols/punctuation
END,
#i = #i +1
-- add a trailing space in case the previous rule changed this.
SET #Ret = #Ret + ' ';
-- custom exceptions: this search is case-insensitive and will
-- replace the word to the case as it is written in the list.
-- NOTE: this list has to end with a comma!
SELECT #i=0, #CaseLen=0,
#CaseExceptions = exceptions from vExceptions
--Want to create a table for these exceptions and call them from this function
-- Loop through exception cases
WHILE CHARINDEX(',', #CaseExceptions, #i+1)>0
BEGIN
-- get the delimited word
SET #CaseLen = CHARINDEX(',', #CaseExceptions, #i+1) - #i
SET #CaseValue = SUBSTRING(#CaseExceptions, #i, #CaseLen)
if (#CaseValue = 'OF' or #CaseValue = 'AND' or #CaseValue ='THE' or #CaseValue='FOR')
begin
--replace with lower case 'of', 'and', 'the', 'for'
SET #Ret = REPLACE(#Ret, ' '+#CaseValue+' ', ' '+lower(#CaseValue)+' ')
end
else
begin
if (CHARINDEX(' '+ #CaseValue +' ', #Ret)>0 )
begin
-- replace it in the original text
SET #Ret = REPLACE(#Ret, ' '+#CaseValue+' ', ' '+#CaseValue+' ')
end
else if (CHARINDEX(' '+#CaseValue+',', #Ret)>0 )
begin
--replace text (with no spaces around it)
SET #Ret = REPLACE(#Ret, ' '+#CaseValue+',', ' '+#CaseValue+',')
end
else if (CHARINDEX(' '+#CaseValue+'-', #Ret)>0 )
begin
--replace text (with no spaces around it)
SET #Ret = REPLACE(#Ret, ' '+#CaseValue+'-', ' '+#CaseValue+'-')
end
else if (CHARINDEX('-'+#CaseValue+' ', #Ret)>0 )
begin
--replace text (with no spaces around it)
SET #Ret = REPLACE(#Ret, '-'+#CaseValue+' ', '-'+#CaseValue+' ')
end
else if (CHARINDEX(','+#CaseValue+' ', #Ret)>0 )
begin
--replace text (with no spaces around it)
SET #Ret = REPLACE(#Ret, ','+#CaseValue+' ', '-'+#CaseValue+' ')
end
end
-- get position of next word
SET #i = CHARINDEX(',', #CaseExceptions, #i+#CaseLen) +1
END
-- remove any leading and trailing spaces
SET #Ret = LTRIM(RTRIM(#Ret));
-- capitalize first character of data irrespective of previous rules
SET #Ret = UPPER(SUBSTRING(#Ret,1,1)) + SUBSTRING(#Ret,2,LEN(#Ret));
END
ELSE
BEGIN
-- return the string unaffected if it is not in uppercase
SET #Ret=#Text
END
RETURN #Ret
END
Create a table (I use ExceptionsTable as my example) with a column WordExcepts. Then add the following after your last DECLARE at the top of the page:
DECLARE #sql nvarchar(2000);
SET #sql = 'N select WordExcepts from ExceptionsTable'
Then down below adjust your exceptions to be:
#CaseExceptions = #sql
Just add to your table as needed and they get filtered out of the function.
I want to toggle case of entire string.
I am able to do for characters, not for string.
DECLARE #Char AS VARCHAR(1)
SET #Char='a'
IF ASCII(#Char)>=97 AND ASCII(#Char) <=122
PRINT UPPER(#Char)
IF ASCII(#Char)>=65 AND ASCII(#Char) <=90
PRINT LOWER(#Char)
How, I can change case for entire string?
For Ex. "AbCdE", I want to change it to "aBcDe".
You can do it by creating functions:
First make function for one character:
CREATE FUNCTION ToggleChar
(
#Char VARCHAR(1)
)
RETURNS VARCHAR(1)
AS
BEGIN
RETURN CHAR(ASCII(UPPER(#Char))+ASCII(LOWER(#Char))-ASCII(#Char))
END
Then, create function for string:
CREATE FUNCTION ToggleCase
(
#Str VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #ResultStr VARCHAR(MAX)
SET #ResultStr=''
WHILE ( #Str<>'')
BEGIN
SET #ResultStr=#ResultStr + [dbo].[ToggleChar](#Str)
SET #Str= SUBSTRING(#Str,2,LEN(#Str))
END
RETURN #ResultStr
END
Now, use this function to toggle string.
SELECT dbo.ToggleCase('AbCdE') AS ToggleString
Try this:
DECLARE #Name VARCHAR(10) = 'SaMplE'
DECLARE #Count INT = 1
WHILE #Count <= LEN(#Name)
BEGIN
SET #Name = STUFF(#Name, #Count, 1,
CASE
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 97 AND 122 THEN
UPPER(SUBSTRING(#Name,#Count,1))
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 65 AND 90 THEN
LOWER(SUBSTRING(#Name,#Count,1))
END)
SET #Count = #Count + 1
END
SELECT #Name
I'm getting this error on a SQL user defined function:
An expression of non-boolean type specified in a context where a
condition is expected, near ')'.
For this:
UPDATE LMI_Contact
SET Phone = NULL
WHERE dbo.LMI_IsSingleCharacterRepeated(Phone, '0')
where the function can be created using:
-- ***this will also find NULL and empty string values***
CREATE FUNCTION LMI_IsSingleCharacterRepeated (#string varchar(max), #char char(1))
RETURNS bit
AS
BEGIN
DECLARE #index int
DECLARE #len int
DECLARE #currentChar char(1)
SET #index = 1
SET #len= LEN(#string)
WHILE #index <= #len
BEGIN
SET #currentChar = SUBSTRING(#string, #index, 1)
IF #currentChar = #char
SET #index= #index+ 1
ELSE
RETURN 0
END
RETURN 1
END;
GO
This function is for checking if a string is any specified single character, repeated.
You must use comparison operators against functions even if the return type is bit.
UPDATE LMI_Contact
SET Phone = NULL
WHERE dbo.LMI_IsSingleCharacterRepeated(Phone, '0') = 1
Try This
CREATE FUNCTION LMI_IsSingleCharacterRepeated (#str varchar(max), #char char(1))
RETURNS BIT
AS
BEGIN
DECLARE #indx int
DECLARE #len int
DECLARE #currentChar char(1)
SET #indx = 1
SET #len= LEN(#str)
WHILE #indx <= #len
BEGIN
SET #currentChar = SUBSTRING(#str, #indx, 1)
IF #currentChar = #char
SET #indx= #indx+ 1
ELSE
RETURN 0
END
RETURN 1
END;
GO
You need to modify the where clause of your query as:
UPDATE LMI_Contact
SET Phone = NULL
WHERE dbo.LMI_IsSingleCharacterRepeated(Phone, '0') = 1
How to check upper case existence length in a string using Sql Query?
For Eg:
1.KKart - from this string the result should be 2, because it has 2 upper case letters.
2.WPOaaa - from this string the result should be 3, because it has 3 upper case letters.
Thanks in advance
There is no built-in T-SQL function for that.
You can use a user-defined function like this one:
CREATE FUNCTION CountUpperCase
(
#input nvarchar(50)
)
RETURNS int
AS
BEGIN
declare #len int
declare #i int
declare #count int
declare #ascii int
set #len = len(#input)
set #i = 1
set #count = 0
while #i <= #len
begin
set #ascii = ascii(substring(#input, #i, 1))
if #ascii >= 65 and #ascii <= 90
begin
set #count = #count +1
end
set #i = #i + 1
end
return #count
END
Usage (with the examples from your question):
select dbo.CountUpperCase('KKart') returns 2.
select dbo.CountUpperCase('WPOaaa') returns 3.
How about something like this :
SELECT len(replace(my_string_field,'abcdefghijklmnopqrstuvwxyz','')) as 'UpperLen'
FROM my_table
The principle is simply to replace all lower case char by nothing and counts the remaining.