2011-08-09 22 views
6

Tengo un procedimiento almacenado de la siguiente manera:SQL Server 2008 procedimiento almacenado con múltiples parámetros de salida

ALTER PROCEDURE [dbo].[sp_web_orders_insert] 
(
    @userId int = default, 
    @custId int = default, 
    @orderDate datetime = default, 
    @orderTotal money = default, 
    @statusId int = default, 
    @orderReference varchar(50) = default, 
    @custReference varchar(50) = default, 
    @order_ID INT output, 
    @orderReferenceOutput varchar(50) output 
) 
AS 


    SET NOCOUNT OFF; 
    INSERT INTO [web_orders] ([user_ID], [cust_ID], [orderDate], [orderTotal], [statusId], [orderReference], [custReference]) VALUES (@userId, @custId, @orderDate, @orderTotal, @statusId , 'PLC' + REPLICATE('0', (7 - LEN((select MAX(order_ID) from web_orders)))) + CAST((select(max(order_ID)+1) from web_orders) AS VARCHAR(5)), @custReference); 

    SELECT @order_ID = @@IDENTITY 
    RETURN @order_ID 

    SELECT @orderReferenceOutput = 'PLC' + REPLICATE('0', (7 - LEN((select MAX(order_ID) from web_orders)))) + CAST((select(max(order_ID)+1) from web_orders) AS VARCHAR(5)) 
    RETURN @orderReferenceOutput 

Por alguna razón el segundo parámetro de salida @orderReferenceOutput vuelve nada. El objetivo de este segundo parámetro de salida es recuperar una columna que acabo de insertar en la base de datos.

+3

La solución más fácil: basta con comentar sus comandos de retorno. Esto no es para lo que son. –

Respuesta

12

La ejecución del procedimiento finaliza después de su primer RETURN que "sale incondicionalmente de una consulta o procedimiento".

RETURN @order_ID 

lugar, considere regresar ambos valores como un conjunto de registros con

SELECT @order_ID AS OrderID, @orderReferenceOutput AS OrderReference 

al final del procedimiento.

+0

Gracias por aceptar la respuesta cuando me permite – StevieB

+4

@Joe, él ya tiene parámetros de salida, ¿por qué no usarlos en lugar de agregar la sobrecarga de un juego de registros? –

2

Solo puede obtener una sola devolución en un procedimiento almacenado. Como soo nas golpea la primera vuelta, sale del proceso.

Use las operaciones SET para asignar valores a sus variables antes de emitir un RETORNO.

Microsoft Article on Return

13

Tiene varios parámetros de salida, usted debe utilizar ellos. Los valores RETURN son para códigos de error/estado, no para datos.

ALTER PROCEDURE [dbo].[sp_web_orders_insert] 
    @userId ..., 
    @order_ID INT OUTPUT, 
    @orderReferenceOutput VARCHAR(50) OUTPUT 
AS 
BEGIN 
    SET NOCOUNT OFF; -- WHY????????? 

    INSERT INTO [web_orders] (user_ID, ...) SELECT @userId, ...; 

    SELECT @order_ID = SCOPE_IDENTITY(); -- preferred over @@IDENTITY; 

    -- using @order_ID here instead of SELECT MAX() twice: 

    SELECT @orderReferenceOutput = 'PLC' 
     + REPLICATE('0', (7 - LEN((@order_ID+1)))) 
     + CAST((@order_ID+1) AS VARCHAR(5)) -- (5)? This breaks when you hit order #100,000 

    RETURN; -- do not RETURN any data - it's already in your OUTPUT parameters! 
END 
GO 
3

eliminamos su RETURN de su procedimiento almacenado originales.

Ajuste su sentencia de llamada para parecerse

DECLARE @Id INT 
DECLARE @Reference VARCHAR(50) 

EXEC [dbo].[sp_web_orders_insert], @order_ID = @Id OUTPUT, 
    @orderReferenceOutput = @Reference OUTPUT 

@Id y @Reference están disponibles en su proceso de llamada.

-1

Debe poner la salida al final de cada salida en la instrucción exec, de lo contrario, todo lo que obtiene es nulo. Usted puede hacer una prueba sencilla para comprobar esto:

if(@order_ID is null) 
Print '@order_ID is null' 
else 
Print '@order_ID is not null' 
+0

Creo que esto no responde a la pregunta OP. – matsjoyce

Cuestiones relacionadas