Передача нескольких значений для одного параметра в службах Reporting Services - PullRequest
67 голосов
/ 04 февраля 2009

В моем отчете несколько параметров Multi-Select. Я пытаюсь найти способ передать несколько значений для одного параметра в строке веб-запроса? Если я передаю одно значение, оно работает нормально.

Отчет работает нормально, выбирая несколько вариантов для одного параметра. Моя проблема заключается в строке веб-запроса.

Ответы [ 21 ]

96 голосов
/ 06 февраля 2009

Хотя решение Джона Сэнсома работает, есть еще один способ сделать это, не используя потенциально неэффективный UDF со скалярным значением. В отчете SSRS на вкладке параметров определения запроса установите значение параметра

=join(Parameters!<your param name>.Value,",")

В вашем запросе вы можете ссылаться на значение следующим образом:

where yourColumn in (@<your param name>)
43 голосов
/ 19 марта 2009

Это то, что я использую при передаче параметра множественного выбора в другой параметр множественного выбора.

=SPLIT(JOIN(Parameters!<your param name>.Value,","),",")
21 голосов
/ 04 февраля 2009

Это одна из плохо поддерживаемых функций служб отчетов SQL.

Что вам нужно сделать, это передать все выбранные вами элементы в виде одной строки в хранимую процедуру. Каждый элемент в строке будет разделен запятой.

Затем я делю строку, используя функцию, которая возвращает предоставленную строку в виде таблицы. Смотри ниже.

ALTER FUNCTION [dbo].[fn_MVParam]
   (@RepParam nvarchar(4000), @Delim char(1)= ',')
RETURNS @Values TABLE (Param nvarchar(4000))AS
  BEGIN
  DECLARE @chrind INT
  DECLARE @Piece nvarchar(100)
  SELECT @chrind = 1 
  WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR))
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam) - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
  RETURN
  END

Затем вы можете ссылаться на результаты в предложении where вашего основного запроса следующим образом:

where someColumn IN(SELECT Param FROM dbo.fn_MVParam(@sParameterString,','))

Я надеюсь, что вы найдете это решение полезным. Пожалуйста, не стесняйтесь задавать любые ваши вопросы.

Cheers, Джон

8 голосов
/ 26 марта 2010

Джон Сэнсом и Эд Харпер имеют отличные решения. Однако я не смог заставить их работать при работе с полями идентификаторов (т.е. целыми числами). Я изменил функцию разделения ниже, чтобы CAST значения были целыми числами, чтобы таблица соединялась со столбцами первичного ключа. Я также прокомментировал код и добавил столбец для заказа, если порядок списка с разделителями был значительным.

CREATE FUNCTION [dbo].[fn_SplitInt]
(
    @List       nvarchar(4000),
    @Delimiter  char(1)= ','
)
RETURNS @Values TABLE
(
    Position int IDENTITY PRIMARY KEY,
    Number int
)

AS

  BEGIN

  -- set up working variables
  DECLARE @Index INT
  DECLARE @ItemValue nvarchar(100)
  SELECT @Index = 1 

  -- iterate until we have no more characters to work with
  WHILE @Index > 0

    BEGIN

      -- find first delimiter
      SELECT @Index = CHARINDEX(@Delimiter,@List)

      -- extract the item value
      IF @Index  > 0     -- if found, take the value left of the delimiter
        SELECT @ItemValue = LEFT(@List,@Index - 1)
      ELSE               -- if none, take the remainder as the last value
        SELECT @ItemValue = @List

      -- insert the value into our new table
      INSERT INTO @Values (Number) VALUES (CAST(@ItemValue AS int))

      -- remove the found item from the working list
      SELECT @List = RIGHT(@List,LEN(@List) - @Index)

      -- if list is empty, we are done
      IF LEN(@List) = 0 BREAK

    END

  RETURN

  END

Используйте эту функцию, как указано ранее:

WHERE id IN (SELECT Number FROM dbo.fn_SplitInt(@sParameterString,','))
4 голосов
/ 19 апреля 2011

Я столкнулся с проблемой с другим замечательным fn_MVParam. SSRS 2005 отправил данные с апострофом в виде двух кавычек.

Я добавил одну строку, чтобы исправить это.

select @RepParam = replace(@RepParam,'''''','''')

Моя версия fn также использует varchar вместо nvarchar.

CREATE FUNCTION [dbo].[fn_MVParam]
   (
    @RepParam varchar(MAX),
    @Delim char(1)= ','
   )
RETURNS @Values TABLE (Param varchar(MAX)) AS
/*
  Usage:  Use this in your report SP 
     where ID in (SELECT Param FROM fn_MVParam(@PlanIDList,','))
*/

BEGIN

   select @RepParam = replace(@RepParam,'''''','''')
   DECLARE @chrind INT
   DECLARE @Piece varchar(MAX)
   SELECT @chrind = 1
   WHILE @chrind > 0
      BEGIN
         SELECT @chrind = CHARINDEX(@Delim,@RepParam)
         IF @chrind > 0
            SELECT @Piece = LEFT(@RepParam,@chrind - 1)
         ELSE
            SELECT @Piece = @RepParam
         INSERT @VALUES(Param) VALUES(@Piece)
         SELECT @RepParam = RIGHT(@RepParam,DATALENGTH(@RepParam) - @chrind)
         IF DATALENGTH(@RepParam) = 0 BREAK
      END
   RETURN
END
4 голосов
/ 03 ноября 2009

ORACLE:

Фраза «IN» (решение Эда) не будет работать против соединения с Oracle (по крайней мере, версия 10). Тем не менее, нашел этот простой обходной путь, который делает. С помощью вкладки параметра набора данных превратить многозначный параметр в CSV:

    :name =join(Parameters!name.Value,",")

Затем в предложении WHERE вашего оператора SQL используйте функцию instring для проверки на совпадение.

    INSTR(:name, TABLE.FILENAME) > 0
3 голосов
/ 03 февраля 2012

Модификация отличного решения Джона, решить:

  • Ошибка "2 цитаты"
  • пробел после одного элемента в параметре

    
    ALTER FUNCTION [dbo].[fn_MVParam]
    (@RepParam nvarchar(4000), @Delim char(1)= ',')
    RETURNS @Values TABLE (Param nvarchar(4000))AS
    BEGIN
    //2 quotes error
    set @RepParam = replace(@RepParam,char(39)+char(39),CHAR(39))
    DECLARE @chrind INT
    DECLARE @Piece nvarchar(100)
    SELECT @chrind = 1 
    WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR(300)))
      //space after one of piece in parameter: LEN(@RepParam + '1')-1
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam + '1')-1 - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
    RETURN
    END
    
    
1 голос
/ 13 декабря 2010

Что вы также можете сделать, это добавить этот код в хранимую процедуру:

set @s = char(39) + replace(@s, ',', char(39) + ',' + char(39)) + char(39)

(Предполагая, что @s является многозначной строкой (например, "A, B, C"))

1 голос
/ 07 февраля 2009

Просто комментарий - я столкнулся с болезненным миром, пытаясь заставить предложение IN работать в соединении с Oracle 10g. Я не думаю, что переписанный запрос может быть правильно передан в 10 г дБ. Мне пришлось полностью отбросить многозначность. Запрос будет возвращать данные только тогда, когда выбрано одно значение (из селектора многозначного параметра). Я попробовал драйверы MS и Oracle с одинаковыми результатами. Я хотел бы услышать, имел ли кто-нибудь успех с этим.

1 голос
/ 14 февраля 2013

Я новичок на сайте и не могу понять, как прокомментировать предыдущий ответ, что, как я считаю, должно быть. Я также не смог проголосовать за пост Джеффа, который, как мне кажется, дал мне мой ответ. В любом случае ...

Хотя я могу видеть, как работают некоторые замечательные посты и последующие настройки, у меня есть доступ только для чтения к базе данных, поэтому никакие UDF, SP или решения на основе представления не работают для меня. Таким образом, решение Эда Харпера выглядело хорошо, за исключением комментария VenkateswarluAvula о том, что вы не можете передавать строку с разделителями-запятыми в качестве параметра в предложение WHERE IN и ожидать, что она будет работать так, как вам нужно. Но решение Джеффа о ORACLE 10g заполняет этот пробел. Я собрал их вместе с сообщением в блоге Рассела Кристофера на http://blogs.msdn.com/b/bimusings/archive/2007/05/07/how-do-you-set-select-all-as-the-default-for-multi-value-parameters-in-reporting-services.aspx, и у меня есть решение:

Создайте свой многовариантный параметр MYPARAMETER, используя любой источник доступных значений (возможно, набор данных). В моем случае, мультивыбор был из набора записей TEXT, но я уверен, что с некоторыми изменениями он будет работать с другими типами. Если вы хотите, чтобы «Выбрать все» было положением по умолчанию, установите тот же источник, что и по умолчанию. Это дает вам ваш пользовательский интерфейс, но созданный параметр не является параметром, переданным в мой SQL.

Переходя к SQL и решению Джеффом проблемы WHERE IN (@MYPARAMETER), у меня возникла проблема полностью моя, в которой одно из значений ('Charge') появляется в одном из других значений (' Non Charge '), то есть CHARINDEX может найти ложноположительный результат. Мне нужно было найти параметр для значения с разделителями до и после. Это означает, что мне нужно убедиться, что разделенный запятыми список также содержит начальную и конечную запятую. А это мой фрагмент SQL:

where ...
and CHARINDEX(',' + pitran.LINEPROPERTYID + ',', @MYPARAMETER_LIST) > 0

Немного посередине - создать еще один параметр (скрытый в производстве, но не в процессе разработки) с помощью:

  • Имя MYPARAMETER_LIST
  • Тип текста
  • Одно доступное значение ="," + join(Parameters!MYPARAMETER.Value,",") + "," и метка,
    на самом деле не имеет значения (так как он не будет отображаться).
  • Значение по умолчанию точно такое же
  • Просто чтобы быть уверенным, я установил Always Refresh в обоих параметрах 'Advanced Свойства

Именно этот параметр передается в SQL, который просто является строкой с возможностью поиска, но который обрабатывает SQL, как любой фрагмент текста.

Я надеюсь, что объединение этих фрагментов ответов поможет кому-то найти то, что они ищут.

...