【问题标题】:Table type parameter in a stored procedure cause operand type clash error存储过程中的表类型参数导致操作数类型冲突错误
【发布时间】:2013-09-24 08:50:23
【问题描述】:

我想给一个标识符数组作为存储过程的参数。

存储过程如下:

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...
    )

用户表类型如下:

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

当我从 SSMS 中的脚本调用存储过程时(我最初从 .NET 代码调用它时遇到同样的问题):

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

我得到了错误:

操作数类型冲突:int 与 IntegerList 不兼容

【问题讨论】:

    标签: sql-server-2008 stored-procedures user-defined-types


    【解决方案1】:

    我找到了答案:是表格类型参数的顺序导致了错误!

    表类型参数必须是存储过程参数中的第一个并且也是传递给存储过程调用的参数中的第一个!

    存储过程:

    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...
        )
    

    然后打电话:

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

    一个 sql server 错误还是我遗漏了什么?

    【讨论】:

    • 要么他们在 2008R2 中修复了这个问题,要么定义表类型的方式影响了它的使用。我实际上拥有相同的用户表类型,但 Value 列不可为空并且对其有 PK 约束。在我的 SP 中,表参数在它之前和之后都有其他参数。
    • 谢谢你 - 虽然直接使用表值参数直接调用存储过程不是首先在直接 SQL(管理工作室)中工作,但我在从 .Net 代码调用它时遇到了问题(实体框架 5 - System.Data.Entity.Database.SqlQuery ) 首先在存储的过程中重新排列表值参数 + 调用代码修复它!
    • @JamesS :我从 .NET 代码调用它时也遇到了问题。
    【解决方案2】:
      DECLARE @ErrMsg varchar(1000)
      DECLARE @ServiceDates ServiceDatesType
    
      INSERT @ServiceDates (indexId,unitOfDay,dayOfMonth,dateOfMonth)
      VALUES 
      (0,1,11,'9/11/2016 12:00:00 AM'),
      (1,1,12,'9/12/2016 12:00:00 AM'),
      (2,1,13,'9/13/2016 12:00:00 AM')   
    
    EXEC [usp_SaveValidate] 427,4,12,9,2016,@ErrMsg output,@ServiceDates  
    PRINT @ErrMsg
    */
    
    ALTER PROCEDURE [dbo].[usp_SaveValidate] (      
         @EpisodeNo INT 
        ,@ProviderId INT
        ,@ServiceId INT 
        ,@Month INT 
        ,@Year INT          
        ,@ErrorMessage VARCHAR(1000) OUTPUT 
        ,@ServiceDates ServiceDatesType ReadOnly
        )
    AS
    BEGIN
     -- Code Here
    END
    

    SQL SERVER 2012 - 表类型参数的位置无关紧要,您必须在传递数据时确保顺序,您可以检查上面的代码,其中表类型参数位于最后一个位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多