How to pass string parameter with `IN` operator in stored procedure SQL Server 2008

后端 未结 4 959
陌清茗
陌清茗 2020-12-01 11:40

I have a stored procedure when I execute it I got error

Conversion failed when converting the varchar value \'+@dptId+\' to data type int

相关标签:
4条回答
  • 2020-12-01 11:50
    ALTER PROCEDURE dbo.sp_Custom_Select_ClientVisit
    (
        @ClientVisitId int = Null,
        @ClientId int = Null,
        @PersonId int = Null,
        @ProductId int = Null,
    
        @VisitDateFrom datetime = Null,
        @VisitDateTo datetime = Null,
    
        @eVisitStatusIn varchar(100) = Null,
        @eVisitStatus int = Null,
        @eStatus int = Null,
        @eStatusNot int = Null
    )
    AS
    
    create table #IDs
    (
        Id   int
    )
    
    Declare @delimiter varchar
    Set @delimiter = ',' 
    
    DECLARE @index int
    SET @index = -1
    
    WHILE (LEN(@eVisitStatusIn) > 0)
      BEGIN 
        SET @index = CHARINDEX(@delimiter , @eVisitStatusIn) 
        IF (@index = 0) AND (LEN(@eVisitStatusIn) > 0) 
          BEGIN  
            INSERT INTO #IDs VALUES (@eVisitStatusIn)
              BREAK 
          END 
        IF (@index > 1) 
          BEGIN  
            INSERT INTO #IDs VALUES (LEFT(@eVisitStatusIn, @index - 1))  
            SET @eVisitStatusIn = RIGHT(@eVisitStatusIn, (LEN(@eVisitStatusIn) - @index)) 
          END 
        ELSE
          SET @eVisitStatusIn = RIGHT(@eVisitStatusIn, (LEN(@eVisitStatusIn) - @index))
        END
    
    Select 
        ClientVisit.ClientVisitId,      ClientVisit.eStatus,
        ClientVisit.VisitTime,          ClientVisit.VisitReason,
        ClientVisit.eVisitStatus,       ClientVisit.VisitSummary,
    
        Client.ClientId,        Client.InstituteName, 
        Client.PersonName as ClientPersonName,      Client.eStatus as ClienteStatus,
    
        Person.PersonId, Person.FirstName as ExecutiveFirstName, Person.LastName as ExecutiveLastName,
        Person.FirstName + ' ' + Person.LastName as ExecutiveName,
    
        p.ProductId, p.ParentProductId,
        p.ProductName, p.Description as ProductDescription,
        p.eStatus ProducteStatus,
    
        Case When ClientVisit.eVisitStatus = 1 Then 'Pending'
             When ClientVisit.eVisitStatus = 2 Then 'Completed'
             When ClientVisit.eVisitStatus = 3 Then 'Cancelled' End As VisitStatus,
    
        Case When ClientVisit.eStatus = 1 Then 'Active'
             When ClientVisit.eStatus = 2 Then 'Deactive'
             When ClientVisit.eStatus = 3 Then 'Deleted' End As Status
    
    
    From AC_ClientVisit as ClientVisit
        INNER Join Com_Client Client On Client.ClientId = ClientVisit.ClientId
        INNER Join Com_Person Person On Person.PersonId = ClientVisit.ExecutiveId
        INNER Join Com_Product p On p.ProductId = Client.RootProductId
    
    Where
        (@ClientVisitId         IS NULL OR ClientVisit.ClientVisitId        = @ClientVisitId)
    AND (@ClientId              IS NULL OR Client.ClientId                  = @ClientId)
    AND (@PersonId              IS NULL OR Person.PersonId                  = @PersonId)
    AND (@ProductId             IS NULL OR p.ProductId                      = @ProductId)
    
    AND (@VisitDateFrom         IS NULL OR @VisitDateFrom                   <= ClientVisit.VisitTime)
    AND (@VisitDateTo           IS NULL OR @VisitDateTo                     >= ClientVisit.VisitTime)   
    
    AND (@eVisitStatusIn        IS NULL OR ClientVisit.eVisitStatus IN(SELECT i.Id FROM #IDs AS i))
    AND (@eVisitStatus          IS NULL OR ClientVisit.eVisitStatus             = @eVisitStatus)
    AND (@eStatus               IS NULL OR ClientVisit.eStatus              = @eStatus)
    AND (@eStatusNot            IS NULL OR ClientVisit.eStatus              <> @eStatusNot)
    RETURN
    
    0 讨论(0)
  • 2020-12-01 11:58

    Here's how I solved it: Working SQL Fiddle

    First I have create a function which splits the string value i.e. '1,2,4,5'

    Split function:

    CREATE  FUNCTION fn_Split(@text varchar(8000), @delimiter varchar(20) = ' ')
    RETURNS @Strings TABLE
    (   
      position int IDENTITY PRIMARY KEY,
      value varchar(8000)  
    )
    AS
    BEGIN
    
    DECLARE @index int
    SET @index = -1
    
    WHILE (LEN(@text) > 0)
      BEGIN 
        SET @index = CHARINDEX(@delimiter , @text) 
        IF (@index = 0) AND (LEN(@text) > 0) 
          BEGIN  
            INSERT INTO @Strings VALUES (@text)
              BREAK 
          END 
        IF (@index > 1) 
          BEGIN  
            INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))  
            SET @text = RIGHT(@text, (LEN(@text) - @index)) 
          END 
        ELSE
          SET @text = RIGHT(@text, (LEN(@text) - @index))
        END
      RETURN
    END
    

    Later in my query I use that split function

    declare @startdate1 varchar(100) ='20120201'
    declare @enddate1 varchar(100)='20130601'
    declare @dptId varchar(100)='3,4'
    
    select * from dummy
    where DateJoining >=@startdate1 and DateJoining < @enddate1 
      and departmentID IN (SELECT Value FROM fn_Split(@dptId, ','));
    
    0 讨论(0)
  • 2020-12-01 12:03

    Try using sp_executesql as the answer. Not the most efficient but it works

    ALTER PROCEDURE [dbo].[uspTestReportData_GetBySerial] 
        @SerialNumbers nvarchar(200)
    AS
    BEGIN
        SET NOCOUNT ON;
        declare @sql nvarchar(200)
    
        set @sql = 'SELECT * from MyTable WHERE  Serial_Number in (' + @SerialNumbers + ')'
        execute sp_executesql @sql                    
    
    END
    
    0 讨论(0)
  • 2020-12-01 12:03

    Simply, you can do the following SELECT:

    SELECT M.REG_NO, T.TYPE_ID 
        FROM MAIN AS M 
            INNER JOIN CLASSIFICATION AS C 
                ON M.REG_NO = C.REG_NO
            INNER JOIN TYPE AS T 
                ON T.TYPE_ID = C.TYPE_ID
        WHERE (','+@Types+',') LIKE '%,' +T.TYPE_ID+ ',%'
    
    0 讨论(0)
提交回复
热议问题