Technical Article

Using UDFs to avoid cursors

,

Let's say you have 2 tables: a Contacts table and a PhoneNumbers table (which stores all the phone numbers for each contact).  You are asked to write a query that returns each contact's name and a comma-delimited string of phone numbers for each contact, something like this:

FirstName    LastName   PhoneNumbers
---------    --------   --------------------------
John         Smith      111-222-3333, 444-555-6666

Many developers would attempt to do this with a cursor.  While a cursor could certainly be coded to do the job, there is actually a more efficient way of doing this that doesn't require cursors or temp tables.

You would write a UDF that grabs the phone numbers, and then execute the UDF within a SELECT statement, as the following code demonstrates:

/*
Code to create and populate tables
*/
CREATE TABLE Contacts
(
  ContactID int IDENTITY PRIMARY KEY, 
  FirstName varchar(100),
  LastName varchar(100)
)

CREATE TABLE PhoneNumbers
(
  PhoneID int IDENTITY PRIMARY KEY,
  ContactID int,
  PhoneNumber varchar(50)
)

DECLARE @id int

INSERT INTO Contacts
VALUES ('John',  'Smith')

SELECT @id = @@IDENTITY

INSERT INTO PhoneNumbers
VALUES (@id, '111-222-3333')

INSERT INTO PhoneNumbers
VALUES (@id, '444-555-6666')

GO

/*
Code to create UDF for getting phone numbers
*/
CREATE FUNCTION GetPhones (@ContactID int)
RETURNS varchar(2000)

AS
BEGIN

DECLARE @phones varchar(2000)
SET @phones = ''

SELECT @phones = 
CASE @phones
   WHEN '' THEN ISNULL(PhoneNumber, '')
   ELSE @phones + ', ' + ISNULL(PhoneNumber, '')
END
FROM PhoneNumbers
WHERE ContactID = @ContactID

RETURN(@phones)

END

GO

/*
Code to execute function from SELECT statement
*/
SELECT FirstName, LastName, dbo.GetPhones(ContactID)
From Contacts

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating