User Defined Functions, the way to a SQL Developers heart. As you can tell from the title in this article we will be looking at User Defined Functions in MSSQL 2005 (I will soon write one for SQL 2005, as they have have added much more functionality for us to use). In this we will also look at a couple User Defined Functions that I find invaluable in my development life.
User Defined Functions are an intrical part of becoming a professional, efficient SQL programmer. These functions make it possible to write almost scalar code, and allowing for complex calculations without cluttering your stored procedures. The benefits of using User-Defined functions are countless. We can use these functions in so many different places, unlike the traditional Stored Procedure. Having the ability to have a function to act like a table gives the developer the ability to break complex logic into smaller, more maintainable pieces of code.
The ability to pass parameters into these objects (UDF's are database objects, much like classes in, say C#) makes the User Defined Function (UDF) not only invaluable but also an extremely powerful tool for a SQL developer.
There are three types of functions that you can create:
CREATE FUNCTION dbo.udfFormatCurrency (@value decimal(20,2),@dollar_sign BIT = NULL)
RETURNS VARCHAR(20)
AS
BEGIN
DECLARE @results VARCHAR(20)
DECLARE @negative BIT
SELECT @negative = CASE WHEN @value < 0 THEN 1 ELSE 0 END
IF @dollar_sign IS NULL SET @dollar_sign = 0
IF @negative = 1 SET @value = -1 * @value
SET @results = CONVERT(VARCHAR, ISNULL(@value, 0))
DECLARE @before VARCHAR(20), @after VARCHAR(20)
IF CHARINDEX ('.', @results )>0
BEGIN
SET @after = SUBSTRING(@results, CHARINDEX ('.', @results ), LEN(@results))
SET @before = SUBSTRING(@results,1, CHARINDEX ('.', @results )-1)
END
ELSE
BEGIN
SET @before = @results
SET @after = ''
END
-- after every third character:
DECLARE @counter INT
IF LEN(@before) > 3
BEGIN
SET @counter = 3
while @counter > 1 AND @counter < LEN(@before)
BEGIN
SET @before = SUBSTRING(@before, 1 ,LEN(@before) - @counter) + ',' + RIGHT(@before,@counter)
SET @counter = @counter + 4
END
END
SET @results = @before + @after
IF @negative = 1 SET @results = '-' + @results
RETURN CASE WHEN @dollar_sign = 1 THEN '$' + @results ELSE @results END
END
CREATE FUNCTION dbo.udfFormatPhoneNumber(@PhoneNumber NVARCHAR(60))
RETURNS NVARCHAR(60)
AS
BEGIN
DECLARE @Length INT
DECLARE @TempStr NVARCHAR(30)
--Strip all non-numeric characters from string
WHILE PATINDEX('%[^0-9]%', @PhoneNumber) > 0
SET @PhoneNumber = REPLACE(@PhoneNumber, SUBSTRING(@PhoneNumber,PATINDEX('%[^0-9]%', @PhoneNumber),1),'')
SET @Length = LEN(@PhoneNumber)-10
--Remove a leading "1" if exists (15555551212)
IF SUBSTRING(@PhoneNumber,1,1) ='1' and LEN(@PhoneNumber) >10
BEGIN
SET @PhoneNumber=SUBSTRING(@PhoneNumber,2,LEN(@PhoneNumber) -1)
END
--Format our phone number to the (555) 555-1212 format
SET @TempStr = @PhoneNumber
SET @PhoneNumber = '(' + SUBSTRING(@PhoneNumber,1,3)+ ')' + SUBSTRING(@PhoneNumber,4,3) + '-'+ SUBSTRING(@PhoneNumber,7,4)
-- Returns Value
RETURN @PhoneNumber
END
CREATE FUNCTION udfParseDelimitedString
(
@source VARCHAR(8000)
,@delimiter VARCHAR(100) = ',' --default to comma delimited.
)
RETURNS @parsed TABLE (pos INT identity(1,1),i_value INT ,n_value NUMERIC(18,3),t_value VARCHAR(2000))
AS
BEGIN
DECLARE @continue INT
,@start INT
,@length INT
,@pos INT
,@int INT
,@num NUMERIC(18,3)
,@txt VARCHAR(2000)
,@del_length tinyINT
IF LEN(@source) = 0
BEGIN
SET @continue = 0 -- force early exit
END
ELSE
BEGIN
-- parse the original @source array INTo a temp table
SET @continue = 1
SET @start = 1
SET @source = RTRIM( LTRIM( @source))
SET @length = DATALENGTH( RTRIM( LTRIM( @source)))
SET @del_length = LEN(@delimiter)
END
WHILE @continue = 1
BEGIN
SET @pos = CHARINDEX( @delimiter ,(SUBSTRING( @source, @start ,((@length - @start) + @del_length))))
IF @pos > 0 -- delimeter(s) found, get the value
BEGIN
SET @txt = LTRIM(RTRIM( SUBSTRING( @source, @start ,(@pos - 1)) ))
IF ISNUMERIC(@txt) = 1
BEGIN
set @int = CAST( CAST(@txt AS NUMERIC) AS INT)
set @num = CAST( @txt AS NUMERIC(18,3))
END
ELSE
BEGIN
set @int = NULL
set @num = NULL
END
SET @start = @pos + @start + (@del_length- 1)
END
ELSE -- No more delimeters, get last value
BEGIN
SET @txt = LTRIM(RTRIM( SUBSTRING( @source, @start ,((@length - @start) + @del_length)) ))
IF ISNUMERIC(@txt) = 1
BEGIN
set @int = CAST( CAST(@txt AS NUMERIC) AS INT)
set @num = CAST( @txt AS NUMERIC(18,3))
END
ELSE
BEGIN
set @int = NULL
set @num = NULL
END
SELECT @continue = 0
END
INSERT INTO @parsed VALUES( @int, @num, @txt )
END
RETURN
END
SELECT
COlumn1,
Column2,
Column3
FROM
Table1
WHERE
ID IN (SELECT i_value FROM db.udfParseDelimitedString('1,23,104,99'))
CREATE FUNCTION dbo.udfTrimString (@value VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
--variable to hold the final result
DECLARE @Trimmed_Value VARCHAR(8000)
--user LTRIM & RTRIM to set the vaoue of our final result
SET @Trimmed_Value = RTRIM(LTRIM(@value))
--return the trimmed string
RETURN @Trimmed_Value
END
GO
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)