2009-08-08 16 views
31

Estoy utilizando SQL Server 2008 Enterprise. Estoy aprendiendo el parámetro OUTPUT del procedimiento almacenado de SQL Server. Por ejemplo, el procedimiento almacenado sp_add_jobschedule tiene un parámetro OUTPUT llamado schedule_id.Problema de parámetro de salida de SQL Server

http://msdn.microsoft.com/en-us/library/ms366342.aspx

Mi confusión es, se ve como parámetro OUTPUT se podría proporcionar un valor de entrada y devuelve un valor, parece que tiene comportamientos tanto de los parámetros de entrada y salida? ¿Está permitido no proporcionar ningún valor INPUT para el parámetro OUTPUT (para que se vea como un comportamiento de parámetro de salida puro)?

Respuesta

60

La confusión se justifica en un grado - y otros RDBMS como Oracle no tener parámetros de procedimiento almacenado que pueden ser de tipo IN (entrada única), OUT (sólo salida) , o INOUT (en ambos sentidos - tipo de parámetro "paso por referencia").

SQL Server es un poco descuidado aquí, ya que etiqueta el parámetro como OUTPUT, pero en realidad, esto significa INPUT/OUTPUT - que básicamente significa que el procedimiento almacenado tiene la oportunidad de devolver un valor a partir de su petición en ese parámetro.

Así que sí - a pesar de que se llama OUTPUT de parámetros, es realmente más de un parámetro INPUT/OUTPUT, y aquellos IN, INOUT, OUT como en Oracle no existen en SQL Server (en T-SQL).

+0

Gracias Marc, "La confusión se justifica en un grado - y otros RDBMS, como Oracle hacen tiene parámetros de procedimiento almacenados "- esta es la razón por la que estoy confundido. Estoy migrando de DB2 a SQL Server. Muchos conceptos son diferentes. :-( – George2

+1

Otra pregunta, podríamos hacer el parámetro OUTPUT como un parámetro opcional, es decir, no podríamos proporcionar su valor de entrada, y simplemente usarlo como salida? – George2

+3

Sí, por supuesto, podría proporcionar en valor INPUT o dejarlo vacío - Si no lo usa dentro de su procedimiento almacenado, no tiene sentido lo que pase. Depende de usted y del código que escriba en su procedimiento, independientemente de que usted siquiera vea el valor pasado. La cláusula "OUTPUT" solo significa que el procedimiento almacenado tiene la capacidad de DEVOLVER un valor en este parámetro, eso es todo. –

19

Puedo darle un breve ejemplo de cómo crear un procedimiento almacenado con el parámetro de salida.

CREATE PROCEDURE test_proc 

@intInput int, 
@intOutput int OUTPUT 

AS 
set @intOutput = @intInput + 1 

go 

Y para llamar a este procedimiento y luego utilizar el parámetro de salida hace de la siguiente manera:

declare @intResult int 
exec test_proc 3 ,@intResult OUT 
select @intResult 

Ves, que se debe declarar ouput primera variable. Y después de ejecutar el procedimiento almacenado, el valor de salida estará en su variable. Puede establecer cualquier valor para la variable de salida, pero después de ejecutar el procedimiento almacenado contendrá exactamente el retorno del procedimiento almacenado (sin importar el valor que haya en la variable de salida).

Por ejemplo:

declare @intResult int 
exec test_proc 3 ,@intResult OUT 
select @intResult 

Se volverá 4. Y:

declare @intResult int 
set @intResult = 8 
exec test_proc 3 ,@intResult OUT 
select @intResult 

también volver 4.

+1

Gracias, por lo tanto el parámetro de salida tiene parámetro de entrada y salida de los comportamientos de los parámetros? – George2

+3

@ George2: Sí, el parámetro OUTPUT actúa como parámetro de entrada y salida. – shahkalpesh

2

La pregunta es - ¿por qué qué quiere inhabilitar para proporcionar ¿entrada? Esto no tiene sentido alguno. Considere este ejemplo sencillo:

CREATE PROCEDURE test (@param AS INT OUTPUT) AS 
BEGIN 
    SET @param = 100 
END 
GO 

DECLARE @i INT 
SET @i = 0 

EXECUTE test @i OUTPUT 
PRINT @i 

DROP PROCEDURE test 

Esto imprime

100 

See - ¿cómo se supone para obtener un valor a cabo si no se pone en una variable primero?

+0

Gracias Tomalak, no estoy seguro de si puedo diseñar un procedimiento de tienda con el parámetro de salida de esta manera. Puedo tratar el parámetro de salida como un parámetro de entrada opcional (porque el parámetro de salida nos permite no ingresar ningún valor) y como un valor de retorno? – George2

+1

No estoy seguro de qué es tan difícil de entender sobre esto. :) ¿Cuál es el problema real? – Tomalak

+0

Estoy usando el parámetro OUTPUT como un parámetro de entrada de opción, no estoy seguro de si es el uso correcto? Estoy usando de esta manera, en el procedimiento de la tienda, verificará si la persona que llama ha ingresado cualquier valor para el parámetro OUTPUT, si es así, haré algo, si no hay ningún valor de entrada para el parámetro OUTPUT, haré algo más. – George2

2

Piense en los PARÁMETROS DE SALIDA como se pasaron por referencia en los lenguajes de programación, es lo mismo. El mejor ejemplo que puedo pensar ahora es devolver el código de error. Quieres insertar algo ... si seleccionas el código de retorno del SP, tienes que recuperarlo en tu código, con el parámetro OUTPUT que no tienes, ya estará en tu parámetro (me refiero al uso de comandos C#, PHP init métodos almacenados proc, o algo diferente cuerdas luego construyendo)

+0

¿Gracias Svetlio, parece que tiene comportamientos de los parámetros INPUT y OUTPUT? ¿Está permitido no proporcionar ningún valor INPUT para el parámetro OUTPUT (para que se vea como un comportamiento de parámetro de salida puro)? – George2

+2

@ George2: "¿Está permitido no proporcionar ningún valor de ENTRADA para el parámetro OUTPUT (para que se vea como un comportamiento de parámetro de salida puro)" - ¿No es eso lo que Sergey ha mostrado en el código, por ejemplo 1? – shahkalpesh

+0

¿Te refieres a este? declaran @intResult int test_proc Exec 3, @ intResult OUT seleccione @intResult – George2

5

Sí, puede utilizar un parámetro OUTPUT para pasar y recuperar valores (aunque no puedo pensar en una buena razón para hacerlo en este momento).

Aquí está un ejemplo trivial que demuestra esto:

-- The stored procedure 
CREATE PROCEDURE OutParamExample 
    @pNum int OUTPUT 
AS 
BEGIN 
    select @pNum 
    set @pNum = @pNum + 5 
END 
GO 

-- use a local variable to retrieve your output param value 
declare @TheNumber int 
set @TheNumber = 10 

print @TheNumber 
exec OutParamExample @TheNumber OUTPUT 
print @TheNumber 

Los resultados se vería así:

10 

----------- 
10 

(1 row(s) affected) 

15 

EDIT: OK, creo que un "no" echado de menos en el segundo párrafo y puede que no haya respondido la pregunta que hizo. Si desea un parámetro de salida estricto (por ejemplo, algo así como un código de retorno), no es necesario que proporcione un valor a la variable local pasada como parámetro de salida, pero aún debe declarar esa variable local para que Tendremos una forma de acceder al valor devuelto fuera del alcance del procedimiento en sí.

Por ejemplo:

declare @LocalNumber int 
-- I don't have to assign a value to @LocalNumber to pass it as a parameter 
exex OutParamExample @LocalNumber OUTPUT 
-- (assume SP has been altered to assign some reasonable value) 

-- but I do have to declare it as a local variable so I can get to 
-- the return value after the stored procedure has been called 
print @LocalNumber 
3

además de añadir a lo que han dicho anteriormente, los parámetros de salida puede actuar como entrada, así como salida. Pero, depende del procedimiento almacenado para usar el valor que se le pasa.

Si los procedimientos almacenados ignoran el valor pasado para el parámetro OUTPUT (que generalmente debería), el valor INPUT se ignora de todos modos.

Mediante el código de Sergey, que puede utilizar el usuario para el valor pasado @intOutput (si necesito)

create PROCEDURE test_proc 

@intInput int, 
@intOutput int OUTPUT 

AS 
set @intOutput = @intOutput + 1 

go 

embargo, que contradice el objetivo del parámetro de salida.
Para ofrecer una vista diferente, el compilador de C# obliga a sobrescribir el valor del parámetro de salida por asignación (sin utilizar el parámetro de salida).

p. Ej. No puedo hacer esto en C#. Aquí actúa como única salida de parámetros (es decir, ignorar el usuario valor pasado a esta función)

static void dosomething(out int i) 
{ 
    //i = 0; 
    i = i + 1; 
} 
1

Una nota adicional con respecto a parte de la pregunta original:

"¿Está permitido no proporcionar ninguna ENTRADA valores para el parámetro OUTPUT (..)? "

En SQLServer es posible especificar un valor predeterminado para un parámetro OUTPUT (que como otros han señalado realmente INOUT). Considere el siguiente ejemplo en el que puede especificar un valor explícito o dejar que la función en sí genere una ID.

CREATE PROCEDURE test (@id uniqueidentifier = NULL OUTPUT) AS 
BEGIN 
    IF @id IS NULL SET @id = NEWID() 
    -- INSERT INTO xyz (...) VALUES (@id, ...) 
    PRINT 'Insert with id: ' + CAST (@id as nvarchar(36)) 
END 
GO 

DECLARE @insertedId uniqueidentifier 
EXECUTE test '00000000-0000-0000-0000-000000000000' 
EXECUTE test @insertedId OUTPUT 
PRINT @insertedId 

DROP PROCEDURE test 

Esto imprime

Insert with id: 00000000-0000-0000-0000-000000000000 
Insert with id: 67AE3D27-8EAB-4301-B384-30EEA1488440 
67AE3D27-8EAB-4301-B384-30EEA1488440 
Cuestiones relacionadas