сохраненный процесс - выполнение запроса с предложением NOT IN where - PullRequest
0 голосов
/ 01 марта 2011

у меня есть хранимая процедура

Create PROCEDURE abc      
  @sRemovePreviouslySelectedWhereClause nvarchar(max)
AS
BEGIN

SELECT * 
      FROM table 
     WHERE nId NOT IN (@sRemovePreviouslySelectedWhereClause)

END;

Параметр @sRemovePreviouslySelectedWhereClause может иметь значения, такие как 0,1. Но это не с сообщением об ошибке:

Сбой преобразования при преобразовании значения nvarchar '0,1' в тип данных int.

Есть ли другой способ добиться этого, кроме динамических запросов?

Ответы [ 5 ]

2 голосов
/ 02 марта 2011

Сначала создайте функцию разбиения, которая разбивает строку с разделителями на таблицу:

CREATE FUNCTION [dbo].[Split]
(   
 @String varchar(max)
,@Delimiter char
)
RETURNS @Results table
(
 Ordinal int
,StringValue varchar(max)
)
as
begin

    set @String = isnull(@String,'')
    set @Delimiter = isnull(@Delimiter,'')

    declare
     @TempString varchar(max) = @String
    ,@Ordinal int = 0
    ,@CharIndex int = 0

    set @CharIndex = charindex(@Delimiter, @TempString)
    while @CharIndex != 0 begin     
        set @Ordinal += 1       
        insert @Results values
        (
         @Ordinal
        ,substring(@TempString, 0, @CharIndex)
        )       
        set @TempString = substring(@TempString, @CharIndex + 1, len(@TempString) - @CharIndex)     
        set @CharIndex = charindex(@Delimiter, @TempString)
    end

    if @TempString != '' begin
        set @Ordinal += 1 
        insert @Results values
        (
         @Ordinal
        ,@TempString
        )
    end

    return
end

Затем измените предложение where следующим образом:

select
 t.*
from [yourTable] t
where t.[ID] not in (select cast([StringValue] as int) from dbo.Split(@sRemovePreviouslySelectedWhereClause,','))
1 голос
/ 01 марта 2011
Create FUNCTION [dbo].[fn_Split] (  
@List nvarchar(2000),   @SplitOn nvarchar(5)
 )   
RETURNS @RtnValue table  ( 
    Value nvarchar(100) ) 
 AS   
BEGIN 
While (Charindex(@SplitOn,@List)>0) 
Begin  
Insert Into @RtnValue (value)
 Select    Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1))) 
Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List)) 
End  
Insert Into @RtnValue (Value)
    Select Value = ltrim(rtrim(@List))

    Return 
END

**********
Create PROCEDURE abc      
  @sRemovePreviouslySelectedWhereClause nvarchar(max)
AS
BEGIN

SELECT * 
      FROM Table 
     WHERE nId NOT IN (select * from dbo.fn_Split(@sRemovePreviouslySelectedWhereClause,','))

END;
0 голосов
/ 01 марта 2011

Вам необходимо использовать Dynamic SQL для таких запросов.

сначала создайте запрос и

SET @sql = 'select * from table 
where nId not in (' + @sRemovePreviouslySelectedWhereClause+ ')'

, затем используйте EXEC(@sql) для запуска запроса.

0 голосов
/ 01 марта 2011

Этот подход, который вы пытаетесь, не работает. Но если вы используете SQL Server 2008, вы можете использовать новые функции, называемые Табличные значения параметров .

По сути, вы создаете пользовательский тип таблицы

CREATE TYPE dbo.nIdTable AS TABLE(nID INT)

и затем вы можете передать несколько значений в этом TVP извне (например, из ADO.NET или подобного):

CREATE PROCEDURE abc(@idValues dbo.nIdTable READONLY)

и используйте эту табличную переменную внутри вашего хранимого процесса:

SELECT * 
FROM table 
WHERE nId NOT IN (SELECT nID FROM @idValues)
0 голосов
/ 01 марта 2011

Необходимо разделить параметр @sRemovePreviouslySelectedWhereClause на ',' и поместить полученные значения во временную таблицу.Тогда ваш выбор будет выглядеть как

select * from table where nId not in (select nId from #tempIds)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...