calling a function in T-SQL Dynamic SQL

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
LVL 1
maqskywalkerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ste5anSenior DeveloperCommented:
With the given parameters, there is absolutely no need for using the split function in the dynamic query (2b).
0
maqskywalkerAuthor Commented:
When I run this query I get this error.
Am I missing a character somewhere in the where clause?
F1.PNG
0
ste5anSenior DeveloperCommented:
Yup, you forget the parentheses:

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

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Powerful Yet Easy-to-Use Network Monitoring

Identify excessive bandwidth utilization or unexpected application traffic with SolarWinds Bandwidth Analyzer Pack.

maqskywalkerAuthor 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

0
ste5anSenior DeveloperCommented:
Correct.
0
maqskywalkerAuthor Commented:
Thanks. Nice.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
SQL

From novice to tech pro — start learning today.