locked
Procedimiento almacenado con parámetro especial RRS feed

  • Pregunta

  • Hola

    Tengo un procedimiento que debe hacer esto:

    select * from Tabla where codigo in (@param)

    donde @param es el parámetro de entrada al procedimiento. Ahora bie, ¿como llamo al procedimiento?:

    Exec MiRPocedimiento '12',25'

    por ejemplo, me dice que espera dos parámetros.

    Saludos y gracias

    Asier

    domingo, 12 de febrero de 2012 21:31

Respuestas

  • Si usas la version 2008 o mayor, entonces deberas usar parametros tipo tabla para pasar el arreglo, de lo contrario tendras que pasar la lista como una lista delimitada, o un documento xml. Luego procederas a desmantelar la lista mediante alguna funcion, de manera que esta funcion te devvuelva una fila por cada elemento en la lista. El resto seria unir mediante JOIN la tabla y la lista.

    No puedes hacerlo de la forma que planteas porque en SQL Server no tenemos la funcionalidad de macro substitucion, por lo que si pasas el valor '12,17', por ejemplo, esta lista se vera como una sola constante que contiene la cadena '12,17' y no como una lista que contiene los elementos 12 y 17.

    Aqui te dejo un articulo muy bueno que compara varios metodos para desmantelar la lista, ademas del metodo que usa parametros tipo tabla. Tomate tu tiempo y trata de entender los diferentes metodos.

    Arrays and Lists in SQL Server
    http://www.sommarskog.se/arrays-in-sql.html

    Por mi parte, te dejo un ejemplo que usa los metodos del tipo xml.

    SET NOCOUNT ON;
    USE tempdb;
    GO
    DECLARE @T TABLE (
    c1 int NOT NULL
    );
    
    INSERT INTO @T (c1)
    VALUES (1), (2), (3), (4);
    
    DECLARE @s varchar(MAX) = '1,3';
    
    SELECT
    	T.*
    FROM
    	@T AS T
    	INNER JOIN
    	(  
    	SELECT
    		N.e.value('text()[1]', 'int') AS c1		  
    	FROM
    		(SELECT @s AS [text()] FOR XML PATH('')) AS R(s)
    		CROSS APPLY
    		(SELECT CAST('<e>' + REPLACE(R.s, ',', '</e><e>') + '</e>' AS xml)) AS S(x)
    		CROSS APPLY
    		S.x.nodes('e') AS N(e)
    	) AS L(c1)
    	ON L.c1 = T.c1;
    GO

    Espero te sea de ayuda.


    AMB

    Some guidelines for posting questions...

    domingo, 12 de febrero de 2012 22:58
  • Si un procedimiento almacenado creado por un usuario tiene el mismo nombre que un procedimiento almacenado del sistema, el procedimiento creado por el usuario no llegará a ejecutarse si utiliza una referencia de nombre certificado que no sea de esquema.

    Ejecutalo así:

    Exec esquema.MiRPocedimiento '12';

    donde esquema, será, el esquema alcual pertenezca tu procedimiento, por defecto: dbo.

    De todas formas, enseñanos la definición del procedimeinto, facilitanos el Create Procedure completo, de tu procedimiento.


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008

    domingo, 12 de febrero de 2012 23:00

Todas las respuestas

  • Si usas la version 2008 o mayor, entonces deberas usar parametros tipo tabla para pasar el arreglo, de lo contrario tendras que pasar la lista como una lista delimitada, o un documento xml. Luego procederas a desmantelar la lista mediante alguna funcion, de manera que esta funcion te devvuelva una fila por cada elemento en la lista. El resto seria unir mediante JOIN la tabla y la lista.

    No puedes hacerlo de la forma que planteas porque en SQL Server no tenemos la funcionalidad de macro substitucion, por lo que si pasas el valor '12,17', por ejemplo, esta lista se vera como una sola constante que contiene la cadena '12,17' y no como una lista que contiene los elementos 12 y 17.

    Aqui te dejo un articulo muy bueno que compara varios metodos para desmantelar la lista, ademas del metodo que usa parametros tipo tabla. Tomate tu tiempo y trata de entender los diferentes metodos.

    Arrays and Lists in SQL Server
    http://www.sommarskog.se/arrays-in-sql.html

    Por mi parte, te dejo un ejemplo que usa los metodos del tipo xml.

    SET NOCOUNT ON;
    USE tempdb;
    GO
    DECLARE @T TABLE (
    c1 int NOT NULL
    );
    
    INSERT INTO @T (c1)
    VALUES (1), (2), (3), (4);
    
    DECLARE @s varchar(MAX) = '1,3';
    
    SELECT
    	T.*
    FROM
    	@T AS T
    	INNER JOIN
    	(  
    	SELECT
    		N.e.value('text()[1]', 'int') AS c1		  
    	FROM
    		(SELECT @s AS [text()] FOR XML PATH('')) AS R(s)
    		CROSS APPLY
    		(SELECT CAST('<e>' + REPLACE(R.s, ',', '</e><e>') + '</e>' AS xml)) AS S(x)
    		CROSS APPLY
    		S.x.nodes('e') AS N(e)
    	) AS L(c1)
    	ON L.c1 = T.c1;
    GO

    Espero te sea de ayuda.


    AMB

    Some guidelines for posting questions...

    domingo, 12 de febrero de 2012 22:58
  • Si un procedimiento almacenado creado por un usuario tiene el mismo nombre que un procedimiento almacenado del sistema, el procedimiento creado por el usuario no llegará a ejecutarse si utiliza una referencia de nombre certificado que no sea de esquema.

    Ejecutalo así:

    Exec esquema.MiRPocedimiento '12';

    donde esquema, será, el esquema alcual pertenezca tu procedimiento, por defecto: dbo.

    De todas formas, enseñanos la definición del procedimeinto, facilitanos el Create Procedure completo, de tu procedimiento.


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008

    domingo, 12 de febrero de 2012 23:00