Removing space sql server 2008 - tsql

I am trying to write a stored procedure in sql server 2008,I need to remove unwanted spaces in the entries of my table.I categorized the entries in my table to 3 types.My store procedure should remove the spaces around single letter,like,
A G M words to AGM words
words A G M words to words AGM words
A G words to AG words
I tried following stored procedure.
CREATE proc At1 #name nvarchar(100)
as
declare #start int
declare #temp1 nvarchar(100)
declare #temp nvarchar(100)
declare #NthPosition int
declare #N int
set #N=LEN(#name)
set #start=1
set #temp1=''
set #temp=''
set #NthPosition=charindex(' ',#name,#start)
if(#NthPosition<>0)
begin
while (#NthPosition<>0 and #N<>0)
begin
set #temp1=SUBSTRING(#name,#start,#NthPosition-1)
if(#temp<>'')
begin
if(len(#temp1)=1)
begin
set #temp=(#temp+#temp1)
end
else
begin
set #temp=(#temp+' '+#temp1)
end
end
else
begin
set #temp=#temp1
end
set #start=#NthPosition+1
set #N=#N-#NthPosition
set #NthPosition=0
set #NthPosition=CHARINDEX(' ',#name,#start)
end
end
else
begin
select #name
end
select #temp
GO
and i used ,
exec At1 'apple A G M mango'
My expected result: apple AGM mango
But my actual result:apple
I am unable to figure out where the error is..Any suggestions in this regard is more helpful.
I tried to use computed column that would clear the space and i was able to find solution only for pattern #3.I am unable to frame a computed column definition suitable for all the 3 patterns..... Please share your thoughts that will be helpful to me

I think this covers all the cases:
CREATE proc At1 #Name nvarchar(100)
as
declare #New nvarchar(100)
declare #SpacePos int
declare #Single bit
select #New = '',#Single = 0
select #Name = LTRIM(#Name)
while LEN(#name) > 0
begin
set #SpacePos = CHARINDEX(' ',#Name)
if #SpacePos = 0 --No more spaces in the string
begin
select #New = #New + CASE WHEN #Single = 1 and LEN(#Name) > 1 THEN ' ' ELSE '' END + #Name,
#Name = ''
end
else if #SpacePos = 2 --Single character "word"
begin
select #New = #New + SUBSTRING(#Name,1,1),
#Name = SUBSTRING(#Name,3,100),
#Single = 1
end
else --Multi-character word
begin
select #New = #New + CASE WHEN #Single = 1 THEN ' ' ELSE '' END + SUBSTRING(#Name,1,#SpacePos),
#Name = SUBSTRING(#Name,#SpacePos+1,100),
#Single = 0
end
end
select #New
go
And the examples:
exec At1 'apple A G M mango'
exec At1 'A G M words'
exec At1 'words A G M'
Produces:
apple AGM mango
AGM words
words AGM
(As a simplifying assumption, I assumed I was okay to remove any leading spaces from the original string. I also assume there are no double spaces in the string. If neither of those assumptions is accurate, a bit more work is required)

There might be a little more simpler approach to this, use replace instead of looping through everything and use the substring method.
But then again, you also might look at your input. How does this "processor" knows what a word is? For a matter of fact, the word applea (apple a) might not be a word you are looking for, where this processor potentially will see it as a word (theoretical)
The best thing you can do is to separate your input, for example with an semicolon ";". Then you can use a split functionallity to make those values into a table (for example look at this post : T-SQL: split and aggregate comma-separated values). Next you can use the replace function on it.
You get something like this
select replace(s.value, ' ' , ''), * from split(#value) as s

Related

DB2: Split a general result-string in columns by delimiter

In DB2 I have one result-string, e.g. like
Color|Product|Category|Price|...
Now I like to generate four (or n) columns containing each string-token split by the pipe
Col1 Col2 Col3 Col4 Col...
Color Product Category Price ...
I am looking for a general solution with arbitrarily number of cols.
The use of this result is to use it in a UNION with another SELECT-Query.
Any ideas?
Where do you want to present this output? via the DB2CLP ou another program.
If you want to retrieve the values in another program, it depends how the program manage the output, and you just put tabulation when scanning the output.
For example, for Java
System.out.println(col1+"\t"+col2+"\t"+col3);
On the other side, if you want to retrieve the values in DB2CLP or a similar shell, an your string is retrieved from the database with these pipes, you should created a scalar function to process the field before returning it to the user.
You will need functions like
Length http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000818.html
Concat http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000781.html or ||
Posstr http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000835.html
The best way is to create a recursive function, that iterates for each token. The basic case is when the string is empty or the string does not finish by a pipe. The recursive case is when the string has pipe.
The process is to read the characters (into a variable) until the first pipe. If a pipe is detected, the quantity of spaces to simulate a tab are added, and then the same function is called with the trailing string.
You should pass the string to read, and the already processed string.
The Function could be like this
function.sql
CREATE OR REPLACE MODULE TEST#
ALTER MODULE TEST PUBLISH
FUNCTION PROCESS (
STRING varchar(255),
NEW_STRING varchar(255)
) RETURNS varchar(255)
#
ALTER MODULE TEST ADD
FUNCTION PROCESS (
STRING varchar(255),
NEW_STRING varchar(255)
) RETURNS varchar(255)
PROC: begin
DECLARE IND INT;
DECLARE LEN INT;
DECLARE MODU INT;
DECLARE CHARS INT;
DECLARE TAB INT DEFAULT 8;
DECLARE PRE VARCHAR(255);
DECLARE POS VARCHAR(255);
SET IND = POSSTR(STRING, '|');
IF (IND <> 0) THEN
SET PRE = SUBSTR(STRING, 1, IND - 1);
SET POS = SUBSTR(STRING, IND + 1);
SET NEW_STRING = TEST.PROCESS (POS, NEW_STRING);
SET PRE = TRIM(PRE);
SET LEN = LENGTH(PRE);
SET MODU = MOD(LEN, TAB);
IF (MODU <> 0) THEN
SET CHARS = TAB - MODU;
WHILE (CHARS <> TAB) DO
SET PRE = CONCAT (PRE, ' ');
SET CHARS = CHARS + 1;
END WHILE;
END IF;
ELSE
SET PRE = STRING;
END IF;
RETURN CONCAT (PRE, COALESCE(NEW_STRING,''));
end PROC#
Compilation and execution
db2 -td# -f function.sql ; db2 "values test.process('Color|Product|Category|Price|...','')"
1
-----------------------------------------
Color Product CategoryPrice ...
1 record(s) selected.

TSQL: Determine number of columns returned by Stored Procedure

This probably has been asked before, but I was unable to find a satisfying answer.
I need to insert results of a stored procedure into a temporary table, something like:
INSERT INTO #TEMP EXEC MY_SP
I don't know in advance how many columns the SP will return, so I need to prepare my #TEMP table (via dynamic ALTER .. ADD commands) to add columns to match SP resultset.
Assumption is - SP accepts no parameters and number of columns is always the same. But how do I determine that number in pure TSQL outside of SP so I can store it for example into a variable?
Tough one, especially if someone else is denying you the necessary permissions to run e.g. OPENROWSET.
Have you considered unpacking/script the SP and add its contents directly to your T-SQL? In this way you can modify and adapt it however you may want.
Otherwise, if you could explain more about the SP:
What does the SP do?
What kind of information does it output? One-N columns, - how many rows?
Is it slow/fast? (Could we perhaps use a brute-force [try-catch] approach)?
How does it determine the columns to output and how often does that change?
Can you pre-determine the columns in any way? (So that you may use an INSERT #temp EXEC sp_getData syntax).
Best of luck!
It's a bit awkward, but you can do something like:
SELECT * INTO #temp
FROM OPENROWSET('SQLOLEDB','Data Source=MyServer;Trusted_Connection=yes;Integrated Security=SSPI', 'EXECUTE MyDB.MySchema.MyProcedure #MyParm=123')
I've requested an EXECUTE INTO syntax, like SELECT INTO to avoid having to know the shape of the stored proc output in advance, but it was rejected
Let me say from the start that if I had to do this I would try find a way to do it outside the SQL environment or something else, because the solution I am providing is not a good way to do this, but it works. So I am not saying that this is a good idea.
I have a sp called test:
CREATE PROCEDURE Test
AS
SELECT 1 as One, 2 as Two
To execute this dynamically I do the following:
DECLARE #i int
SET #i = 1;
DECLARE #SUCESS bit
SET #SUCESS = 0
WHILE(#SUCESS = 0)
BEGIN
DECLARE #proc VARCHAR(MAX)
DECLARE #count int
SET #count = 1
SET #proc = 'DECLARE #t TABLE ( c1 varchar(max) '
WHILE #count < #i
BEGIN
SET #proc = #proc + ', c' + CONVERT(varchar, #count + 1) + ' varchar(max) '
print #proc
SET #count = #count + 1
END
SET #proc = #proc + '); INSERT INTO #t EXEC Test'
BEGIN TRY
EXEC(#proc);
SET #SUCESS = 1
END TRY
BEGIN CATCH
SET #i = #i+1
END CATCH
END
SET #proc = #proc + '; SELECT * into ##t FROM #t '
EXEC( #proc )
SELECT * from ##t
This is a poor solution to your problem because you have lost the data type of your columns, their names etc.
I don't understand the syntax, and this probably isn't the best way, but someone seems to have done this with converting to xml and parsing it: Dynamic query results into a temp table or table variable

T-SQL VARCHAR(MAX) Truncated

DECLARE #str VARCHAR (MAX);
SELECT #str = COALESCE(#str + CHAR(10), '') +
'EXECUTE CreateDeno ' + CAST(ID AS VARCHAR)
FROM GL_To_Batch_Details
WHERE TYPE = 'C' AND
Deno_ID IS NULL;
--PRINT #str;--SELECT #str;
**EXEC(#str);**
EDITED
Does EXECUTE statement truncate strings to 8,000 chars like PRINT? How can I execute a dynamic SQL statement having more than 8,000 chars?
Any suggestion would be warmly appreciated.
PRINT is limited to 8k in output.
There is also an 8k limit in SSMS results pane.
Go to
tools -> options -> query results
to see the options.
To verify the length of the actual data, check:
SELECT LEN(#str)
When concatenating strings and the result is of type VARCHAR(MAX) and is over 8000 characters, at least one parameter and/or element being used in the concatenation need to be of the VARCHAR(MAX) type otherwise truncation will occur in the resultant string and will not be executable in an EXEC statement.
Example:
DECLARE #sql AS VARCHAR(MAX);
/* DECLARE #someItem AS VARCHAR(100); -- WILL CAUSE TRUNCATION WHEN #sql HAS LEN > 8000 */
DECLARE #someItem AS VARCHAR(MAX); -- All string variables need to be VARCHAR(MAX) when concatenating to another VARCHAR(MAX)
SET #someItem = 'Just assume the resulting #sql variable goes over 8000 characters...';
SET #sql = 'SELECT Something FROM Somewhere WHERE SomeField = ''' + #someItem + '''';
EXEC (#sql);
--PRINT #sql;
More information on MSDN.
"If the result of the concatenation of strings exceeds the limit of
8,000 bytes, the result is truncated. However, if at least one of the
strings concatenated is a large value type, truncation does not
occur."
The default length of a varchar is 30 characters:
CAST (ID AS VARCHAR)
Is it possible that id is longer than 30 characters?
The PRINT command is certainly limited to 8000 chars, irrespective of the length of the output (or whether it is varchar(max)). To work around this you need to output the string in chunks of <8000 chars
Update: In answer to your edit, exec doesn't limit the string length. I've put together the following example to show this:
DECLARE #str VARCHAR (MAX);
;WITH CTE_Count AS
(
select counter = 1
union all
select counter = counter+1
from CTE_Count
Where counter < 2000
)
SELECT
#str=COALESCE(#str + CHAR (10) ,
'' ) + 'select value=' + CAST (counter AS VARCHAR)
from
CTE_Count
Option (MAXRECURSION 0)
PRINT len(#str);--SELECT #str;
exec (#str)
Running this prints the length as 34892 chars, and all 2000 execute statements do run (be warned, it may take a few mins!)
It happens when you concatenate literals if one is not a varchar(max) the result ill be "implicit casted" to varchar(8000).
To generate a literal varchar(max) all parts must be varchar(max).
Note: It happened to me doing updates on varchar(max) columns, never tested with the EXEC command.
Also as noted in previous answers the print command holds a limit but you can try selecting that variable instead of printing it. (also ther's a limit on that select length you can configure on MS-SMS)
I also wanted to see what I was sending to Exec, and was confused by the PRINT limit. Had to write a proc to print in chunks.
CREATE PROCEDURE [dbo].[KFX_PrintVarcharMax]
#strMax varchar(max)
AS
BEGIN
SET NOCOUNT ON;
DECLARE
#index int = 0,
#start int = 1,
#blkSize int = 2000;
WHILE #Start < LEN(#strMax)
BEGIN
IF #start + #blkSize >= LEN(#strMax)
BEGIN
-- If remainder is less than blocksize print the remainder, and exit.
PRINT SUBSTRING(#strMax, #start, #blkSize)
BREAK;
END
-- Else find the next terminator (beyond the blksize)
SET #index = CHARINDEX(CHAR(10), #strMax, #start + #blkSize);
if #index >= #start
BEGIN
PRINT SubString(#strMax, #start, #index - #start + 1)
SET #start = #index + 1;
SET #blkSize = CASE WHEN #start + 2000 < LEN(#strMax) THEN 2000
ELSE LEN(#strMax) - #start + 1 END
END
ELSE
BEGIN
-- No char(10) found. Just print the rest.
PRINT SUBSTRING(#strMax, #start, LEN(#strMax))
BREAK;
END
END
END

Parameterised stored proc

I'm writing a parameterized stored proc. I know that you can set the parameter value such that it displays all the results when the parameter is not mentioned in the execute command.. But i'm unable to recall how that is achieved. Any help is highly appreciated... Please..
I'd recommend parameterized dynamic sql (sp_executesql)
Going this route, you can discard any irrelevant parameter when building your where clause.
Example procedure:
create proc dbo.SearchForStuff
(
#Id int = 0
,#Description varchar(100) = ''
)
as
begin
set nocount on;
declare #select nvarchar(max) = '
select
s.*
from Stuff as s'
declare #where varchar(max) = ''
if isnull(#ID,0) != 0 begin
set #where += case #where when '' then ' where ' else ' and ' end + 's.Id = #Id'
end
if isnull(#Description,'') != '' begin
set #where += case #where when '' then ' where ' else ' and ' end + 's.[Description] = #Description'
end
set #select += #where
exec sp_executesql
#select
,N'
,#Id int = 0
,#Description varchar(100) = '''''
,#Id
,#Description
end
Usage:
exec SearchForStuff #Id = 1, #Description = 'omg' -- Returns every item where Id is 1 and Description is 'omg'
exec SearchForStuff #Id = 1 -- Returns every item where Id is 1
exec SearchForStuff #Description = 'omg' -- Returns every item where Description is 'omg'
exec SearchForStuff --returns every item
In this fashion your final query is not littered with useless conditions. Further, you can get a bit more granular than I did here. Based upon which parameters were passed, you can tailor your where/join clauses to take advantage of your indexes such that you get the best possible performance. The only drawback is a slight loss of readability (imo).
You can make your WHERE conditions like this:
WHERE (#myParam IS NULL OR #myParam = someValue)
You may be able to use OPTION (RECOMPILE) is SQL2008SP1+ (or similar, don't know other options) in the sproc, depending on your RDBMS, to get this to be performant.
Method from Erland Sommarskog:
http://www.sommarskog.se/dyn-search-2008.html#static
From the link:
"The effect of all the #x IS NULL clauses is that if that input parameter is NULL, then that AND-condition is always true. Thus, the only conditions that are in effect are those where the search parameter has a non-NULL value.
As far as maintainability goes, it's difficult to think of a better solution for the search conditions at hand. It's compact, easy to read and to extend. And performance? Very good as long as you include the query hint OPTION (RECOMPILE). This hint forces the query to be recompiled each time, in which case SQL Server will use the actual variable values as if they were constants."
If it is an int you can use
SELECT X,Y
FROM T
WHERE C BETWEEN COALESCE(#P, -2147483648) AND COALESCE(#P, 2147483647)
The definitive article on the subject

T-SQL function for generating slugs?

Quick check to see if anyone has or knows of a T-SQL function capable of generating slugs from a given nvarchar input. i.e;
"Hello World" > "hello-world"
"This is a test" > "this-is-a-test"
I have a C# function that I normally use for these purposes, but in this case I have a large amount of data to parse and turn into slugs, so it makes more sense to do it on the SQL Server rather than have to transfer data over the wire.
As an aside, I don't have Remote Desktop access to the box so I can't run code (.net, Powershell etc) against it
Thanks in advance.
EDIT:
As per request, here's the function I generally use to generate slugs:
public static string GenerateSlug(string n, int maxLength)
{
string s = n.ToLower();
s = Regex.Replace(s, #"[^a-z0-9s-]", "");
s = Regex.Replace(s, #"[s-]+", " ").Trim();
s = s.Substring(0, s.Length <= maxLength ? s.Length : maxLength).Trim();
s = Regex.Replace(s, #"s", "-");
return s;
}
You can use LOWER and REPLACE to do this:
SELECT REPLACE(LOWER(origString), ' ', '-')
FROM myTable
For wholesale update of the column (the code sets the slug column according to the value of the origString column:
UPDATE myTable
SET slug = REPLACE(LOWER(origString), ' ', '-')
This is what I've come up with as a solution. Feel free to fix / modify where needed.
I should mention that the database I'm currently developing against is case insensitive hence the LOWER(#str).
CREATE FUNCTION [dbo].[UDF_GenerateSlug]
(
#str VARCHAR(100)
)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE #IncorrectCharLoc SMALLINT
SET #str = LOWER(#str)
SET #IncorrectCharLoc = PATINDEX('%[^0-9a-z ]%',#str)
WHILE #IncorrectCharLoc > 0
BEGIN
SET #str = STUFF(#str,#incorrectCharLoc,1,'')
SET #IncorrectCharLoc = PATINDEX('%[^0-9a-z ]%',#str)
END
SET #str = REPLACE(#str,' ','-')
RETURN #str
END
Mention to: http://blog.sqlauthority.com/2007/05/13/sql-server-udf-function-to-parse-alphanumeric-characters-from-string/ for the original code.
I know this is an old thread, but for future generation, I found one function that deals even with accents here:
CREATE function [dbo].[slugify](#string varchar(4000))
RETURNS varchar(4000) AS BEGIN
declare #out varchar(4000)
--convert to ASCII
set #out = lower(#string COLLATE SQL_Latin1_General_CP1251_CS_AS)
declare #pi int
--I'm sorry T-SQL have no regex. Thanks for patindex, MS .. :-)
set #pi = patindex('%[^a-z0-9 -]%',#out)
while #pi>0 begin
set #out = replace(#out, substring(#out,#pi,1), '')
--set #out = left(#out,#pi-1) + substring(#out,#pi+1,8000)
set #pi = patindex('%[^a-z0-9 -]%',#out)
end
set #out = ltrim(rtrim(#out))
-- replace space to hyphen
set #out = replace(#out, ' ', '-')
-- remove double hyphen
while CHARINDEX('--', #out) > 0 set #out = replace(#out, '--', '-')
return (#out)
END
Here's a variation of Jeremy's response. This might not technically be slugifying since I'm doing a couple of custom things like replacing "." with "-dot-", and stripping out apostrophes. Main improvement is this one also strips out all consecutive spaces, and doesn't strip out preexisting dashes.
create function dbo.Slugify(#str nvarchar(max)) returns nvarchar(max)
as
begin
declare #IncorrectCharLoc int
set #str = replace(replace(lower(#str),'.',' dot '),'''','')
-- remove non alphanumerics:
set #IncorrectCharLoc = patindex('%[^0-9a-z -]%',#str)
while #IncorrectCharLoc > 0
begin
set #str = stuff(#str,#incorrectCharLoc,1,' ')
set #IncorrectCharLoc = patindex('%[^0-9a-z -]%',#str)
end
-- remove consecutive spaces:
while charindex(' ',#str) > 0
begin
set #str = replace(#str, ' ', ' ')
end
set #str = replace(#str,' ','-')
return #str
end
I took Jeremy's response a couple steps further by removing all consecutive dashes even after spaces are replaced, and removed leading and trailing dashes.
create function dbo.Slugify(#str nvarchar(max)) returns nvarchar(max) as
begin
declare #IncorrectCharLoc int
set #str = replace(replace(lower(#str),'.','-'),'''','')
-- remove non alphanumerics:
set #IncorrectCharLoc = patindex('%[^0-9a-z -]%',#str)
while #IncorrectCharLoc > 0
begin
set #str = stuff(#str,#incorrectCharLoc,1,' ')
set #IncorrectCharLoc = patindex('%[^0-9a-z -]%',#str)
end
-- replace all spaces with dashes
set #str = replace(#str,' ','-')
-- remove consecutive dashes:
while charindex('--',#str) > 0
begin
set #str = replace(#str, '--', '-')
end
-- remove leading dashes
while charindex('-', #str) = 1
begin
set #str = RIGHT(#str, len(#str) - 1)
end
-- remove trailing dashes
while len(#str) > 0 AND substring(#str, len(#str), 1) = '-'
begin
set #str = LEFT(#str, len(#str) - 1)
end
return #str
end
-- Converts a title such as "This is a Test" to an all lower case string such
-- as "this-is-a-test" for use as the slug in a URL. All runs of separators
-- (whitespace, underscore, or hyphen) are converted to a single hyphen.
-- This is implemented as a state machine having the following four states:
--
-- 0 - initial state
-- 1 - in a sequence consisting of valid characters (a-z, A-Z, or 0-9)
-- 2 - in a sequence of separators (whitespace, underscore, or hyphen)
-- 3 - encountered a character that is neither valid nor a separator
--
-- Once the next state has been determined, the return value string is
-- built based on the transitions from the current state to the next state.
--
-- State 0 skips any initial whitespace. State 1 includes all valid slug
-- characters. State 2 converts multiple separators into a single hyphen
-- and skips trailing whitespace. State 3 skips any punctuation between
-- between characters and, if no additional whitespace is encountered,
-- then the punctuation is not treated as a word separator.
--
CREATE FUNCTION ToSlug(#title AS NVARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #retval AS VARCHAR(MAX) = ''; -- return value
DECLARE #i AS INT = 1; -- title index
DECLARE #c AS CHAR(1); -- current character
DECLARE #state AS INT = 0; -- current state
DECLARE #nextState AS INT; -- next state
DECLARE #tab AS CHAR(1) = CHAR(9); -- tab
DECLARE #lf AS CHAR(1) = CHAR(10); -- line feed
DECLARE #cr AS CHAR(1) = CHAR(13); -- carriage return
DECLARE #separators AS CHAR(8) = '[' + #tab + #lf + #cr + ' _-]';
DECLARE #validchars AS CHAR(11) = '[a-zA-Z0-9]';
WHILE (#i <= LEN(#title))
BEGIN
SELECT #c = SUBSTRING(#title, #i, 1),
#nextState = CASE
WHEN #c LIKE #validchars THEN 1
WHEN #state = 0 THEN 0
WHEN #state = 1 THEN CASE
WHEN #c LIKE #separators THEN 2
ELSE 3 -- unknown character
END
WHEN #state = 2 THEN 2
WHEN #state = 3 THEN CASE
WHEN #c LIKE #separators THEN 2
ELSE 3 -- stay in state 3
END
END,
#retval = #retval + CASE
WHEN #nextState != 1 THEN ''
WHEN #state = 0 THEN LOWER(#c)
WHEN #state = 1 THEN LOWER(#c)
WHEN #state = 2 THEN '-' + LOWER(#c)
WHEN #state = 3 THEN LOWER(#c)
END,
#state = #nextState,
#i = #i + 1
END
RETURN #retval;
END
To slug with Vietnamese unicode
CREATE function [dbo].[toslug](#string nvarchar(4000))
RETURNS varchar(4000) AS BEGIN
declare #out nvarchar(4000)
declare #from nvarchar(255)
declare #to varchar(255)
--convert to ASCII dbo.slugify
set #string = lower(#string)
set #out = #string
set #from = N'ýỳỷỹỵáàảãạâấầẩẫậăắằẳẵặéèẻẽẹêếềểễệúùủũụưứừửữựíìỉĩịóòỏõọơớờởỡợôốồổỗộđ·/_,:;'
set #to = 'yyyyyaaaaaaaaaaaaaaaaaeeeeeeeeeeeuuuuuuuuuuuiiiiioooooooooooooooood------'
declare #pi int
set #pi = 1
--I'm sorry T-SQL have no regex. Thanks for patindex, MS .. :-)
while #pi<=len(#from) begin
set #out = replace(#out, substring(#from,#pi,1), substring(#to,#pi,1))
set #pi = #pi + 1
end
set #out = ltrim(rtrim(#out))
-- replace space to hyphen
set #out = replace(#out, ' ', '-')
-- remove double hyphen
while CHARINDEX('--', #out) > 0 set #out = replace(#out, '--', '-')
return (#out)
END