Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 help writing sql function

Author  Topic 

ahmad7_8
Starting Member

4 Posts

Posted - 2011-07-20 : 05:38:31
i want to send a name (collection of words) and fixed length

and the function will add this mark "_" before the last letter to any word in the name

finally hole name will be = length i send but there exception

any word in name , the letter befor the last is one of those letter will ignored (ignor the word) and we will make the addition to the other valid word


exception group is : "a b c d e f g"
and symbol to add is "_"

example
"computer disk good" = 30
x = lengthname("computer disk good",30)

returned result will be "computer dis______k goo______d"

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2011-07-20 : 06:29:27
sorry not fully clear on your requirement. can you explain how you got last output?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2011-07-20 : 13:02:24
Hi.

Well this isn't something you should do in the database but it was interesting

Here's a (broken, completely horrible, slow) version

IF OBJECT_ID('test.split') IS NOT NULL DROP FUNCTION test.split
GO

CREATE FUNCTION test.split (@splitOn CHAR(1), @string VARCHAR(8000))
RETURNS TABLE AS RETURN (
WITH splits AS (
SELECT
1 AS [index]
, 1 AS [Start]
, CHARINDEX(@splitOn, @string) AS [Stop]
UNION ALL SELECT
sp.[index] + 1
, sp.[stop] + 1
, CHARINDEX(@splitOn, @string, sp.[Stop] + 1) AS [Stop]
FROM
splits AS sp
WHERE
sp.[Stop] > 0
)
SELECT
[index]
, SUBSTRING(@string, [start], CASE WHEN [stop] > 0 THEN [stop] - [start] ELSE 8000 END) AS [split]
FROM splits
)
GO

DECLARE @exceptions TABLE ([letter] CHAR(1))
INSERT @exceptions SELECT 'a' UNION SELECT 'b' UNION SELECT 'c' UNION SELECT 'd' UNION SELECT 'e' UNION SELECT 'f' UNION SELECT 'g'


DECLARE @testCases TABLE ([phraseID] INT IDENTITY(1,1), [phrase] VARCHAR(4000), [FinalLength] INT)
INSERT @testCases
SELECT 'computer disk good', 30
UNION SELECT 'foo bar', 10
UNION SELECT 'a b', 5
UNION SELECT 'the quick brown fox jumped over the lazy dog', 101


DECLARE @workTable TABLE (
[phraseID] INT
, [phrase] VARCHAR(8000)
, [split] VARCHAR(8000)
, [splitOrder] INT
, [splitLength] INT
, [padCandidate] BIT
, [FinalLength] INT
, [CurrentLength] INT
, [addUnderscores] INT
)
INSERT @workTable
SELECT
tc.[phraseID]
, tc.[phrase]
, sp.[split]
, sp.[index]
, LEN(sp.[split])
, CASE WHEN LEFT(RIGHT(sp.[split], 2) , 1) IN ( SELECT [letter] FROM @exceptions ) THEN 0 ELSE 1 END AS [adjust]
, tc.[FinalLength]
, LEN(tc.[phrase])
, NULL
FROM
@testCases AS tc
CROSS APPLY test.split (' ', tc.[phrase]) AS sp


UPDATE w SET
[addUnderscores] = ([FinalLength] - [CurrentLength]) / p.[parts]
FROM
@workTable AS w
CROSS APPLY (
SELECT COUNT([phraseID]) AS [parts]
FROM @workTable AS w2
WHERE w2.[phraseID] = w.[phraseID] AND w2.[padCandidate] = 1
)
AS p
WHERE
w.[padCandidate] = 1

SELECT * FROM @workTable

UPDATE w SET
[split] = LEFT([split], LEN([split]) - 1) + REPLICATE('_', [addUnderscores]) + RIGHT([split], 1)
FROM
@workTable As w
WHERE
w.[addUnderscores] IS NOT NULL

SELECT * FROM @workTable


SELECT
[phrase]
, [FinalLength]
, [padded]
, LEN([padded]) AS [Final Padded Length]
FROM
(
SELECT
tc.[phrase]
, tc.[FinalLength]
, RTRIM(pad.[padded]) AS [padded]
FROM
@testCases AS tc
OUTER APPLY (
SELECT [split] + ' '
FROM @workTable AS w
WHERE w.[phraseID] = tc.[phraseID]
ORDER BY w.[splitOrder]
FOR XML PATH ('')
)
AS pad ([padded])
)
AS p

Results:


phrase FinalLength padded Final Padded Length
--------------------------------------------- ----------- --------------------------------------------------------------------------------------------------- --------------------
a b 5 a b 3
computer disk good 30 computer dis______k goo______d 30
foo bar 10 fo___o bar 10
the quick brown fox jumped over the lazy dog 101 th_________e quick brow_________n fo_________x jumped over th_________e laz_________y do_________g 98

As you can see it's horrible. There is probably a better way using quirky updates but really -- don't do this in the db.

Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2011-07-20 : 13:03:44
Oh -- btw I'm not even going to try and support this -- this code is a complete mess and you shouldn't do this. It was just fun to write it

Do something else. Anything else.

Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

ahmad7_8
Starting Member

4 Posts

Posted - 2011-07-20 : 14:52:47
Wow that's great job but how i call it and pass what i want
.. do i must create some table or not
... sorry im new and u do great job friend
Go to Top of Page

ahmad7_8
Starting Member

4 Posts

Posted - 2011-07-20 : 15:24:05
i want like this
select test.split('computer disk good',30)
result
computer dis______k goo______d
Go to Top of Page

ahmad7_8
Starting Member

4 Posts

Posted - 2011-07-21 : 03:18:18
any idea
Go to Top of Page
   

- Advertisement -