calling a function in T-SQL Dynamic SQL

maqskywalker
maqskywalker used Ask the Experts™
on
I'm using IN condition in where clause of T-SQL

I'm using the Employees table of the Northwind Sql Server database.

I have 4 queries I created.
I'm labeling the queries as Query 1a, Query 1b, Query 2a, Query 2b.
3 of the 4 queries work correctly.

I'm having a problem with Query 2b

Please see the code below.

This is the script to create the Employees table

USE [Northwind]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Employees](
	[EmployeeID] [int] NOT NULL,
	[LastName] [nvarchar](20) NOT NULL,
	[FirstName] [nvarchar](10) NOT NULL,
	[Title] [nvarchar](30) NULL,
	[TitleOfCourtesy] [nvarchar](25) NULL,
	[BirthDate] [datetime] NULL,
	[HireDate] [datetime] NULL,
	[Address] [nvarchar](60) NULL,
	[City] [nvarchar](15) NULL,
	[Region] [nvarchar](15) NULL,
	[PostalCode] [int] NULL,
	[Country] [nvarchar](15) NULL,
 CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED 
(
	[EmployeeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (1, N'Davolio', N'Nancy', N'Sales Representative', N'Ms.', CAST(N'1948-12-08 00:00:00.000' AS DateTime), CAST(N'1992-05-01 00:00:00.000' AS DateTime), N'507 - 20th Ave. E.
Apt. 2A', N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (2, N'Fuller', N'Andrew', N'Vice President, Sales', N'Dr.', CAST(N'1952-02-19 00:00:00.000' AS DateTime), CAST(N'1992-08-14 00:00:00.000' AS DateTime), N'908 W. Capital Way', N'Tacoma', N'WA', 98401, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (3, N'Leverling', N'Janet', N'Sales Representative', N'Ms.', CAST(N'1963-08-30 00:00:00.000' AS DateTime), CAST(N'1992-04-01 00:00:00.000' AS DateTime), N'722 Moss Bay Blvd.', N'Kirkland', N'WA', 98033, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (4, N'Peacock', N'Margaret', N'Sales Representative', N'Mrs.', CAST(N'1937-09-19 00:00:00.000' AS DateTime), CAST(N'1993-05-03 00:00:00.000' AS DateTime), N'4110 Old Redmond Rd.', N'Redmond', N'WA', 98052, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (5, N'Buchanan', N'Steven', N'Sales Manager', N'Mr.', CAST(N'1955-03-04 00:00:00.000' AS DateTime), CAST(N'1993-10-17 00:00:00.000' AS DateTime), N'14 Garrett Hill', N'London', NULL, 95624, N'UK')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (6, N'Suyama', N'Michael', N'Sales Representative', N'Mr.', CAST(N'1963-07-02 00:00:00.000' AS DateTime), CAST(N'1993-10-17 00:00:00.000' AS DateTime), N'Coventry House
Miner Rd.', N'London', NULL, 93722, N'UK')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (7, N'King', N'Robert', N'Sales Representative', N'Mr.', CAST(N'1960-05-29 00:00:00.000' AS DateTime), CAST(N'1994-01-02 00:00:00.000' AS DateTime), N'Edgeham Hollow
Winchester Way', N'London', NULL, 45648, N'UK')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (8, N'Callahan', N'Laura', N'Inside Sales Coordinator', N'Ms.', CAST(N'1958-01-09 00:00:00.000' AS DateTime), CAST(N'1994-03-05 00:00:00.000' AS DateTime), N'4726 - 11th Ave. N.E.', N'Seattle', N'WA', 98105, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (9, N'Dodsworth', N'Anne', N'Sales Representative', N'Ms.', CAST(N'1966-01-27 00:00:00.000' AS DateTime), CAST(N'1994-11-15 00:00:00.000' AS DateTime), N'7 Houndstooth Rd.', N'London', NULL, 98751, N'UK')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (10, N'Smith', N'John', N'Accountant', N'Mr.', CAST(N'1986-03-21 00:00:00.000' AS DateTime), CAST(N'2006-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (11, N'Long', N'Brad', N'Sales Representative', N'Mr.', CAST(N'1980-08-12 00:00:00.000' AS DateTime), CAST(N'2005-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (12, N'Simpson', N'Tom', N'Sales Manager', N'Mr.', CAST(N'1984-04-23 00:00:00.000' AS DateTime), CAST(N'2003-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (13, N'Van Houten', N'Morton', N'Accountant', N'Mr.', CAST(N'1981-09-12 00:00:00.000' AS DateTime), CAST(N'2007-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (14, N'Myers', N'Marvin', N'Tech Support', N'Mr.', CAST(N'1983-10-14 00:00:00.000' AS DateTime), CAST(N'2008-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')
INSERT [dbo].[Employees] ([EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country]) VALUES (15, N'Dodd', N'Fred', N'Sales Representative', N'Mr.', CAST(N'1985-05-24 00:00:00.000' AS DateTime), CAST(N'2008-11-15 00:00:00.000' AS DateTime), NULL, N'Seattle', N'WA', 98122, N'USA')

Open in new window


I saw this function called f_split at this link:
https://stackoverflow.com/questions/17481479/parse-comma-separated-string-to-make-in-list-of-strings-in-the-where-clause

This it the script for this function:

USE [Northwind]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE Function [dbo].[f_split]
(
    @param nvarchar(max), 
    @delimiter char(1)
)
returns @t table (val nvarchar(max), seq int)
as
begin
set @param += @delimiter

;with a as
(
    select cast(1 as bigint) f, charindex(@delimiter, @param) t, 1 seq
    union all
    select t + 1, charindex(@delimiter, @param, t + 1), seq + 1
    from a
    where charindex(@delimiter, @param, t + 1) > 0
)
insert @t
select substring(@param, f, t - f), seq from a
option (maxrecursion 0)
return
end

GO

Open in new window


Here are some reference queries:

Query 1a

DECLARE @EmployeeID INT
SET @EmployeeID = 1 
-------------------
SELECT [EmployeeID]
      ,[LastName]
      ,[FirstName]
      ,[Title]
      ,[TitleOfCourtesy]
      ,[BirthDate]
      ,[HireDate]
      ,[Address]
      ,[City]
      ,[Region]
      ,[PostalCode]
      ,[Country]
FROM [Northwind].[dbo].[Employees]
WHERE [EmployeeID] = @EmployeeID

Open in new window


So when I run the above query I get the following result.

 Query 1a result

Query 1b

This query is the Dynamic SQL version of query 1a.

DECLARE @EmployeeID varchar(1000)
SET @EmployeeID = 1 
-------------------
declare @mSQL char(8000)
-- Main Select --------------------------------------------------------------------------
Set @mSQL = 'SELECT [EmployeeID]
                     ,[LastName]
                     ,[FirstName]
                     ,[Title]
                     ,[TitleOfCourtesy]
                     ,[BirthDate]
                     ,[HireDate]
                     ,[Address]
                     ,[City]
                     ,[Region]
                     ,[PostalCode]
                     ,[Country]'
Set @mSQL = RTrim(@mSQL) + ' FROM Northwind.dbo.Employees'
-- WHERE clause --------------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' WHERE EmployeeID = ' + @EmployeeID
-- ORDER BY statement --------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' ORDER BY EmployeeID'
--print(@mSQL)
EXEC(@mSQL)

Open in new window


When I run this query I get this:

result of Query 1b

Query 2a

This query uses the udf called f_split
You feed the function a comma separated string list of values for a column and it returns the table records for those values

DECLARE @EmployeeIDList NVARCHAR(MAX)
SET @EmployeeIDList = '1,4,5'
-------------------
SELECT [EmployeeID]
      ,[LastName]
      ,[FirstName]
      ,[Title]
      ,[TitleOfCourtesy]
      ,[BirthDate]
      ,[HireDate]
      ,[Address]
      ,[City]
      ,[Region]
      ,[PostalCode]
      ,[Country]
FROM [Northwind].[dbo].[Employees] e
Where e.EmployeeID IN ( Select VAL AS empid From Northwind.dbo.f_split(@EmployeeIDList, ',') )

Open in new window


When I run this query I get this:

result of Query 2b
Query 2b

This query is the Dynamic SQL version of Query 2b


DECLARE @EmployeeIDList NVARCHAR(MAX)
SET @EmployeeIDList = '1,4,5'
-------------------
declare @mSQL char(8000)
-- Main Select --------------------------------------------------------------------------
Set @mSQL = 'SELECT [EmployeeID]
                     ,[LastName]
                     ,[FirstName]
                     ,[Title]
                     ,[TitleOfCourtesy]
                     ,[BirthDate]
                     ,[HireDate]
                     ,[Address]
                     ,[City]
                     ,[Region]
                     ,[PostalCode]
                     ,[Country]'
Set @mSQL = RTrim(@mSQL) + ' FROM Northwind.dbo.Employees'
-- WHERE clause --------------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' WHERE EmployeeID IN ' + @EmployeeIDList
-- ORDER BY statement --------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' ORDER BY EmployeeID'
--print(@mSQL)
EXEC(@mSQL)

Open in new window




The where clause in Query 2a looks like this:

Where e.EmployeeID IN ( Select VAL AS empid From Northwind.dbo.f_split(@EmployeeIDList, ',') )

How do change the where clause in Query 2b so it calls the f_split function?

The above code is what I got so far.
The result of Query 2b should be the same as Query 2a, I just want to use the f_split function in Dynamic SQL
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ste5anSenior Developer

Commented:
With the given parameters, there is absolutely no need for using the split function in the dynamic query (2b).

Author

Commented:
When I run this query I get this error.
Am I missing a character somewhere in the where clause?
F1.PNG
Senior Developer
Commented:
Yup, you forget the parentheses:

-- WHERE clause --------------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' WHERE EmployeeID IN ( ' + @EmployeeIDList + ' )'

Open in new window

Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
ste5an,

So you are saying I should do this instead? This worked:

DECLARE @EmployeeIDList NVARCHAR(MAX)
SET @EmployeeIDList = '1,4,5'
-------------------
declare @mSQL char(8000)
-- Main Select --------------------------------------------------------------------------
Set @mSQL = 'SELECT [EmployeeID]
                     ,[LastName]
                     ,[FirstName]
                     ,[Title]
                     ,[TitleOfCourtesy]
                     ,[BirthDate]
                     ,[HireDate]
                     ,[Address]
                     ,[City]
                     ,[Region]
                     ,[PostalCode]
                     ,[Country]'
Set @mSQL = RTrim(@mSQL) + ' FROM Northwind.dbo.Employees'
-- WHERE clause --------------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' WHERE EmployeeID IN (' + @EmployeeIDList + ')'
-- ORDER BY statement --------------------------------------------------------------------
Set @mSQL = RTrim(@mSQL) + ' ORDER BY EmployeeID'
--print(@mSQL)
EXEC(@mSQL)

Open in new window

ste5anSenior Developer

Commented:
Correct.

Author

Commented:
Thanks. Nice.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial