2009-08-10 53 views
15

Estoy trabajando en un informe de SSRS que utiliza un procedimiento almacenado que contiene algunos parámetros. Tengo problemas con dos de los parámetros porque quiero tener la opción de seleccionar más de un elemento.Parámetro de valores múltiples de SSRS con un procedimiento almacenado

Aquí es una versión condensada de lo que tengo:

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) 

Cuando intento basta con ejecutar el procedimiento almacenado sólo valores de retorno si entro a sólo 1 valor para @ReportProductSalesGroupID y 1 @ReportProductFamilyID valor. Si trato de ingresar dos SalesGroupID y/o 2 ProductFamilyID, no se produce un error, pero no devuelvo nada.

-- 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' 

En SSRS me sale un error que dice:

sintaxis

incorrecta cerca ''

Parece que el separador , está siendo incluido en la cadena en lugar de un delimitador

+0

Puede usar: - SQL dinámico - Función definida por el usuario con valores de tabla Consulte [este enlace para obtener más información] (http://www.sql-server-helper.com/functions/comma-delimited-tablent). aspx). –

+0

Alternativamente, este es un duplicado cercano de http://stackoverflow.com/questions/337704/parameterizing-a-sql-in-clause En particular, la solución de David Robbins se ve bien. –

+0

Ok, lo hice y funciona si ejecuto EXEC uspMyStoredProcedure 'G23, G22', 'NOF, ALT', '8/1/2009', '8/9/2009' Pero tan pronto como lo intente en rs y seleccione más de un valor del menú desplegable (generado a partir de un conjunto de datos) obtengo una sintaxis incorrecta cerca de ',' No estoy seguro de qué me falta – user153949

Respuesta

29

Necesita tres cosas:

  1. En las propiedades del conjunto de datos de SSRS, pase el parámetro de varios valores al procedimiento almacenado como una cadena delimitada por comas

    =Join(Parameters!TerritoryMulti.Value, ",") 
    
  2. en SQL Server, necesita una función de tabla-valor que se puede dividir una coma -delimited cadena de vuelta en un mini tabla (por ejemplo see here)

  3. En el procedimiento almacenado, tiene una cláusula where o menos así:

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

    ... donde ufnSplit es su función de división desde el paso 2.

(pasos y el código completo en mi entrada de blog 'SSRS multi-value parameters with less fail'):

6

Vamos a suponer que usted tiene una lista de múltiples valor @param1

Cree otro parámetro interno en su informe de SSRS llamados @param2 y establecer el valor por defecto a:

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

XXX puede ser cualquier delimitador que desee, EXCEPTO una coma (ver a continuación)

Luego, puede pasar @param2 a su consulta o procedimiento almacenado.

Si intenta hacerlo de otra forma, hará que falle cualquier función de cadena que utilice comas para separar los argumentos. (por ejemplo, CHARINDEX, REPLACE).

Por ejemplo Replace(@param2, ',', 'replacement') no funcionará. Terminará con errores como "Reemplazar función requiere 3 argumentos".

+1

Las comas funcionan bien para mí, consulte http://stackoverflow.com/a/9862901/22194 – codeulike

1

Finalmente pude obtener una solución simple para este problema. A continuación, he proporcionado todos los (3) pasos que seguí.

espero que ustedes le va a gustar :)

Paso 1 - He creado una tabla temporal global con una columna.

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

Paso 2 - En el procedimiento de división, que no hizo uso de cualquier matriz o tabla de datos, he cargado directamente los valores de división en mi tabla temporal global.

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; 
/

Paso 3 - En los parámetros de conjunto de datos de SSRS, he utilizado

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

Paso 4: En el comienzo de su procedimiento almacenado ejecuta el procedimiento

Exec split_param(A_Country, ‘,’); 

Paso 5: En su procedimiento almacenado sql usa la condición como a continuación.

Where country_name in (select * from TEMP_PARAM_TABLE) 
0

Cuando SSRS pasa el parámetro es en la forma: Param1, Param2, Param3.

En el procedimiento, solo necesita poner identificadores alrededor de cada parámetro. Y también identificadores alrededor del valor que devuelve el conjunto de datos. En mi caso, utilicé punto y coma.

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 se pasa a través de SSRS.

l_multivalue_parameter lee el parámetro pasado a través de SSRS y coloca identificadores alrededor de cada valor.

database_value_that_is_singular es el valor devuelto para cada registro.

Así que si 'Tipo 1, Tipo 2, Type3'is aprobada en medio de SSRS:

i_multivalue_parameter es: Tipo 1, Tipo 2, Tipo 3

l_multivalue_parameter es:; Tipo 1; Tipo 2; Tipo 3;

database_value_that_is_singular es:; Type1; o; Tipo2; o; Tipo3;

Instr devolverá un valor superior a 0 si el parámetro coincide.

Esto funciona incluso si cada parámetro es similar. EG: "Tipo A" y "Tipo AA". Es decir, "Tipo A" no coincidirá con "Tipo AA".

+0

Cuando dice "identificador", ¿quiere decir "delimitador"? (¿O "separador"?) Además, su respuesta parece un procedimiento Oracle PL/SQL, mientras que la pregunta parece ser sobre un procedimiento SQL Server T/SQL? – criticalfix

Cuestiones relacionadas