I want to convert/ cast these operators ( '/' and '*') if this is possible. Maybe you know how that works or you know what the internal coding of division and multiplication is?! Maybe then I can continue with that?
What I want to do is, based on the last number of the current system time, I want to decide if that number is odd or even, and then do a multiplication or division in the next calculations.
CREATE FUNCTION CalculateFactor()
RETURNS NVARCHAR(50)
AS
BEGIN
DECLARE #time DATETIME2(7)
DECLARE #length INT
DECLARE #value NVARCHAR(20)
DECLARE #operator NVARCHAR(20)
SET #time = SYSDATETIME()
SELECT #length = LEN(#time)
SELECT #value = RIGHT(#time, 1);
IF (#value % 2 = 0)
SET #operator = '*'
ELSE SET #operator = '/'
DECLARE #SQL NVARCHAR(20)
SET #SQL = '10' + #operator + '2' --I get only 10 / 2 and 10 * 2 because that are strings and that is why I cannot get a result of the operation, but I want 5 and 20
RETURN #SQL
END
GO
I have a column of type *NVARCHAR which holds SQL statement snippets instead of the final values. So for example one of the fields holds the following snippet:
CAST(#originalValue * -1 AS INT)
What I am trying to accomplish is to use these SQL snippets to be inserted into stored procedure code latter on. To validate the functionality I have created the following very simple example to set an integer value to (5) and use the above SQL snippet within dynamic SQL statement to invert this value (5) into (-5).
DECLARE #originalValue AS INT = 5
DECLARE #fianalValue AS INT
DECLARE #sql AS NVARCHAR(50)
DECLARE #value AS NVARCHAR(50) = 'CAST(#originalValue * -1 AS INT)'
SET #sql = 'SELECT #fianalValue = '+CAST(#value AS NVARCHAR(100))+''
exec sp_executesql #sql, N'#fianalValue INT OUTPUT', #fianalValue = #fianalValue OUTPUT
PRINT '#fianalValue: ' + CAST(#fianalValue AS VARCHAR(50))
However, I am getting an error. I have tried in a few different approaches but something is not lining up. Thank for help.
Try this
DECLARE #originalValue AS INT = 5
DECLARE #fianalValue AS INT
DECLARE #sql AS NVARCHAR(50)
DECLARE #value AS NVARCHAR(50) = 'CAST('+convert(varchar(20),#originalValue)+' * -1 AS INT)'
SET #sql = 'SELECT #fianalValue = '+CAST(#value AS NVARCHAR(100))+''
exec sp_executesql #sql, N'#fianalValue INT OUTPUT', #fianalValue = #fianalValue OUTPUT
PRINT '#fianalValue: ' + CAST(#fianalValue AS VARCHAR(50))
I have an asp.net application that uses SQL Server 2005. In this application I want to create a function that returns unique reference numbers for new Inquiry Id.
I read about UNIQUEIDENTIFIER but it has a specific format like 1548C3E02-2D73-4244-8787-D45AC590519A.
I want output like 1703-HJIF-2012. Here first have combination of current datepart like date and month, second is random string which auto generate and third one is year part of current date. I don't have any idea how I could create such a function and how I would be calling this function from a stored procedure and get result string from function with this required format.
here some one posted me this function but this generates spaces instead of 0 :
create function UniqueRefNum (#r1 float, #r2 float, #r3 float, #r4 float)
returns char(14)
begin
-- Not sure if rand() might return 1.0
-- If it does, the conversion code below would produce a character that's not an
-- uppercase letter so let's avoid it just in case
if #r1 = 1.0 set #r1 = 0
if #r2 = 1.0 set #r2 = 0
if #r3 = 1.0 set #r3 = 0
if #r4 = 1.0 set #r4 = 0
declare #now datetime
set #now = getdate() -- or getutcdate()
declare #m char(2)
if month(#now) < 10
set #m = '0' + month(#now)
else
set #m = month(#now)
declare #d char(2)
if day(#now) < 10
set #d = '0' + day(#now)
else
set #d = day(#now)
return #m + #d + '-' +
char(65 + cast(#r1 * 26 as int)) +
char(65 + cast(#r2 * 26 as int)) +
char(65 + cast(#r3 * 26 as int)) +
char(65 + cast(#r4 * 26 as int)) +
'-' + cast(year(#now) as varchar)
end
You then call the function from your stored procedure like this:
declare #uniqueRef char(14)
set #uniqueRef = dbo.UniqueRefNum(rand(), rand(), rand(), rand())
---------------Updated-----------------------------
it's generates out put is like that :
4 24-HHBH-2014
and i want output something like this :
2404-HHBH-2014
DDMM-XXXX-YYYY
You need to cast the day/month values to char before concatenating the strings.
declare #m char(2)
if month(#now) < 10
set #m = '0' + cast(month(#now) as char(1))
else
set #m = month(#now)
declare #d char(2)
if day(#now) < 10
set #d = '0' + cast(day(#now) as char(1))
else
set #d = day(#now)
The thing is that the string in '0' + month(#now) is converted to integer and then the two numbers are added up.
my problem is pretty simple. I get a value from a sql select which looks like this:
ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG
and I need it like this:
AR,AM,AU,BE,BA,BR,BG,CN,DK,DE,EE,FO,FI,FR,GE,GR,IE,IS,IT,JP,YU,CA,KZ,KG
The length is different in each dataset.
I tried it with format(), stuff() and so on but nothing brought me the result I need.
Thanks in advance
With a little help of a numbers table and for xml path.
-- Sample table
declare #T table
(
Value nvarchar(100)
)
-- Sample data
insert into #T values
('ARAMAU'),
('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG')
declare #Len int
set #Len = 2;
select stuff(T2.X.value('.', 'nvarchar(max)'), 1, 1, '')
from #T as T1
cross apply (select ','+substring(T1.Value, 1+Number*#Len, #Len)
from Numbers
where Number >= 0 and
Number < len(T1.Value) / #Len
order by Number
for xml path(''), type) as T2(X)
Try on SE-Data
Time to update your resume.
create function DontDoThis (
#string varchar(max),
#count int
)
returns varchar(max)
as
begin
declare #result varchar(max) = ''
declare #token varchar(max) = ''
while DATALENGTH(#string) > 0
begin
select #token = left(#string, #count)
select #string = REPLACE(#string, #token, '')
select #result += #token + case when DATALENGTH(#string) = 0 then '' else ',' end
end
return #result
end
Call:
declare #test varchar(max) = 'ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG'
select dbo.DontDoThis(#test, 2)
gbn's comment is exactly right, if not very diplomatic :) TSQL is a poor language for string manipulation, but if you write a CLR function to do this then you will have the best of both worlds: .NET string functions called from pure TSQL.
I believe this is what QQping is looking for.
-- select .dbo.DelineateEachNth('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',2,',')
create function DelineateEachNth
(
#str varchar(max), -- Incoming String to parse
#length int, -- Length of desired segment
#delimiter varchar(100) -- Segment delimiter (comma, tab, line-feed, etc)
)
returns varchar(max)
AS
begin
declare #resultString varchar(max) = ''
-- only set delimiter(s) when lenght of string is longer than desired segment
if LEN(#str) > #length
begin
-- continue as long as there is a remaining string to parse
while len(#str) > 0
begin
-- as long as know we still need to create a segment...
if LEN(#str) > #length
begin
-- build result string from leftmost segment length
set #resultString = #resultString + left(#str, #length) + #delimiter
-- continually shorten result string by current segment
set #str = right(#str, len(#str) - #length)
end
-- as soon as the remaining string is segment length or less,
-- just use the remainder and empty the string to close the loop
else
begin
set #resultString = #resultString + #str
set #str = ''
end
end
end
-- if string is less than segment length, just pass it through
else
begin
set #resultString = #str
end
return #resultString
end
With a little help from Regex
select Wow=
(select case when MatchIndex %2 = 0 and MatchIndex!=0 then ',' + match else match end
from dbo.RegExMatches('[^\n]','ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',1)
for xml path(''))
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