Table type parameter in a stored procedure cause operand type clash error

Dude Pascalou picture Dude Pascalou · Sep 24, 2013 · Viewed 21.4k times · Source

I want to give an array of identifiers as argument to a stored procedure.

The stored procedure looks like :

ALTER PROCEDURE [dbo].[SearchPerson]
    @personType INT = NULL,
    @city NVARCHAR(64) = NULL,
    @siteIds IntegerList READONLY,
    -- some other params...
AS
    SELECT
        -- some fields...
    FROM dbo.PersonView AS pv
    WHERE
    (
        (@personType IS NULL OR pv.PersonType = @personType) AND
        (@city IS NULL OR pv.City LIKE '%' + @city + '%') AND
        (pv.SiteId in (SELECT si.Value FROM @siteIds AS si)) AND
        -- some other params filter...
    )

The user table type looks like :

CREATE TYPE [dbo].[IntegerList] AS TABLE(
    [Value] [int] NULL
)

When I call the stored procedure from a script in SSMS (I originally have the same problem calling it from .NET code) :

DECLARE @siteIds AS IntegerList,
@personType AS INT = 1
INSERT INTO @siteIds VALUES (1)
EXEC [dbo].[SearchPerson] @personType, @siteIds

I got the error :

Operand type clash: int is incompatible with IntegerList

Answer

Dude Pascalou picture Dude Pascalou · Sep 24, 2013

I found the answer : it was the order of the table type parameter that caused the error !

The table type parameter must be the first in the stored procedure parameters AND ALSO in the arguments passed to the stored procedure call !

The stored procedure :

ALTER PROCEDURE [dbo].[SearchPerson]
    @siteIds IntegerList READONLY, -- THIS PARAMETER HAS TO BE THE FIRST !
    @personType INT = NULL,
    @city NVARCHAR(64) = NULL,
    -- some other params...
AS
    SELECT
        -- some fields...
    FROM dbo.PersonView AS pv
    WHERE
    (
        (@personType IS NULL OR pv.PersonType = @personType) AND
        (@city IS NULL OR pv.City LIKE '%' + @city + '%') AND
        (pv.SiteId in (SELECT si.Value FROM @siteIds AS si)) AND
        -- some other params filter...
    )

And the call :

DECLARE @siteIds AS IntegerList,
@personType AS INT = 1
INSERT INTO @siteIds VALUES (1)
EXEC [dbo].[SearchPerson] @siteIds, @personType -- PUT @siteIds FIRST !

A sql server bug or am I missing something ?