Многозначный параметр SSRS с использованием хранимой процедуры - PullRequest
19 голосов
/ 11 августа 2009

Я работаю над отчетом SSRS, в котором используется хранимая процедура, содержащая несколько параметров. У меня проблемы с двумя параметрами, потому что я хочу выбрать несколько элементов.

Вот сокращенная версия того, что у меня есть:

CREATE PROCEDURE [dbo].[uspMyStoredProcedure] 
  (@ReportProductSalesGroupID AS VARCHAR(MAX) 
  ,@ReportProductFamilyID AS VARCHAR(MAX)
  ,@ReportStartDate AS DATETIME
  ,@ReportEndDate AS DATETIME)

--THE REST OF MY QUERY HERE WHICH PULLS ALL OF THE NEEDED COLUMNS

WHERE DateInvoicedID BETWEEN @ReportStartDate AND @ReportEndDate
AND ProductSalesGroupID IN (@ReportProductSalesGroupID)
AND ProductFamilyID IN (@ReportProductFamilyID)

Когда я пытаюсь просто запустить хранимую процедуру, я возвращаю значения, только если я ввожу только 1 значение для @ReportProductSalesGroupID и 1 значение @ReportProductFamilyID. Если я попытаюсь ввести два SalesGroupID и / или 2 ProductFamilyID, это не приведет к ошибке, но я ничего не верну.

-- Returns data
EXEC uspMyStoredProcedure 'G23',     'NOF',     '7/1/2009', '7/31/2009'

-- Doesn't return data
EXEC uspMyStoredProcedure 'G23,G22', 'NOF,ALT', '7/1/2009', '7/31/2009'

В SSRS я получаю сообщение об ошибке:

Неверный синтаксис рядом с ','

Похоже, что в строку включен разделитель , вместо разделителя

Ответы [ 4 ]

37 голосов
/ 25 марта 2012

Вам нужно три вещи:

  1. В свойствах набора данных SSRS передайте многозначный параметр хранимой процедуре в виде строки с разделителями-запятыми

    =Join(Parameters!TerritoryMulti.Value, ",")
    
  2. В Sql Server вам нужна функция табличного значения, которая может разбивать строку с разделителями-запятыми обратно в мини-таблицу (например, см. Здесь ). edit: начиная с SQL Server 2016 вы можете использовать встроенную функцию STRING_SPLIT для этого

  3. В хранимой процедуре есть предложение where как-то так:

    WHERE sometable.TerritoryID in (select Item from dbo.ufnSplit(@TerritoryMulti,','))
    

    ... где ufnSplit - ваша функция разделения с шага 2.

(полные шаги и код в моем сообщении в блоге ' многозначные параметры SSRS с меньшим количеством ошибок '):

6 голосов
/ 23 мая 2012

Допустим, у вас есть список с несколькими значениями @param1

Создайте еще один внутренний параметр в отчете SSRS с именем @param2 и установите значение по умолчанию:

=Join(Parameters!param1.value, 'XXX')

XXX может быть любым разделителем, кроме запятой (см. Ниже)

Затем вы можете передать @param2 вашему запросу или хранимой процедуре.

Если вы попытаетесь сделать это любым другим способом, это приведет к сбою любой строковой функции, которая использует запятые для разделения аргументов. (например, CHARINDEX, ЗАМЕНА).

Например, Replace(@param2, ',', 'replacement') не будет работать. Вы получите ошибки типа «Заменить функцию требует 3 аргумента».

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

Наконец-то мне удалось получить простое решение этой проблемы. Ниже я предоставил все (3) шаги, которые я выполнил.

Надеюсь, вам, ребята, понравится:)

Шаг 1 - Я создал глобальную временную таблицу с одним столбцом.

CREATE GLOBAL TEMPORARY TABLE TEMP_PARAM_TABLE(
  COL_NAME  VARCHAR2(255 BYTE)
) ON COMMIT PRESERVE ROWS NOCACHE;

Шаг 2 - В процедуре разделения я не использовал массив или данные, я непосредственно загрузил значения разделения в мою глобальную временную таблицу.

CREATE OR REPLACE PROCEDURE split_param(p_string IN VARCHAR2 ,p_separator IN VARCHAR2
)
IS
   v_string VARCHAR2(4000);
   v_initial_pos NUMBER(9) := 1;
   v_position NUMBER(9) := 1;
BEGIN
   v_string := p_string || p_separator;

   delete from temp_param_policy;

   LOOP
      v_position :=
                  INSTR(v_string, p_separator, v_initial_pos, 1);
      EXIT WHEN(NVL(v_position, 0) = 0);

      INSERT INTO temp_param_table
           VALUES (SUBSTR(v_string, v_initial_pos
                         , v_position - v_initial_pos));

      v_initial_pos := v_position + 1;
   END LOOP;
commit;

END split_param;
/

Шаг 3 - В параметрах набора данных SSRS я использовал

=Join(Parameters!A_COUNTRY.Value, ",")

Шаг 4: В начале вашей хранимой процедуры выполняется Процедура

Exec split_param(A_Country, ‘,’);

Шаг 5: В вашей хранимой процедуре SQL используйте условие, как показано ниже.

Where country_name in (select * from TEMP_PARAM_TABLE)
0 голосов
/ 31 января 2017

Когда SSRS передает параметр, он имеет вид: Param1, Param2, Param3.

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

CREATE OR REPLACE PROCEDURE user.parameter_name ( i_multivalue_parameter ) AS l_multivalue_parameter varchar2(25555) := ';' || replace(i_multivalue_parameter,',',';') || ';'; BEGIN select something from dual where ( instr(l_multivalue_parameter, ';' || database_value_that_is_singular || ';') > 0 ) END;

i_multivalue_parameter передается через SSRS.

l_multivalue_parameter считывает параметр, переданный через SSRS, и помещает идентификаторы вокруг каждого значения.

database_value_that_is_singular - это значение, возвращаемое для каждой записи.

То есть, если через SSRS передаются 'Type1, Type2, Type3':

i_multivalue_parameter: Тип1, Тип2, Тип3

l_multivalue_parameter:; Тип1; Тип2; Тип3;

database_value_that_is_singular is:; Type1; или; Тип2; или; Тип3;

Instr вернет значение больше 0, если параметр соответствует.

Это работает, даже если все параметры похожи. Например: «Тип А» и «Тип АА». То есть «Тип А» не будет соответствовать «Типу АА».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...