2011-02-08 7 views
12

Estoy tratando de escribir un procedimiento almacenado para ayudar con el desarrollo de nuestra base de datos, pero estoy teniendo problemas para usarlo. Por ejemplo:¿Utiliza el resultado de una expresión (por ejemplo, Llamada de función) en una lista de parámetros de procedimiento almacenado?

DECLARE @pID int; 
SET @pID = 1; 
EXEC WriteLog 'Component', 'Source', 'Could not find given id: ' + CAST(@pID AS varchar); 

Esto produce el error (en SQL Server 2005)

Msg 102, nivel 15, estado 1, línea 4 sintaxis incorrecta cerca '+'.

¿Puede alguien explicarme por qué mi sintaxis es incorrecta y la forma correcta de resolver este problema?

Respuesta

18

Necesita usar una variable intermedia. SQL Server no es compatible con este tipo de operación en la lista de parámetros, aunque ha estado en la lista TODO durante algunos años. (Ver Connect Item: Use scalar functions as stored procedure parameters)

El grammar for EXEC es

[ { EXEC | EXECUTE } ] 
    { 
     [ @return_status = ] 
     { module_name [ ;number ] | @module_name_var } 
     [ [ @parameter = ] { value 
          | @variable [ OUTPUT ] 
          | [ DEFAULT ] 
          } 
     ] 
     [ ,...n ] 
     [ WITH <execute_option> [ ,...n ] ] 
    } 
[;] 

La documentación no está claro en un formato aceptable para value pero parece ser sólo expresiones "simples" como valores literales o @@ funciones del sistema prefijadas (como @@IDENTITY). No se permiten otras funciones del sistema, como SCOPE_IDENTITY() (incluso aquellas que no requieren paréntesis, como CURRENT_TIMESTAMP, no están permitidas).

Así que por el momento es necesario utilizar la sintaxis tales como los siguientes

DECLARE @pID INT; 

SET @pID = 1; 

/*If 2008+ for previous versions this needs to be two separate statements*/ 
DECLARE @string VARCHAR(50) = 'Could not find given id: ' + CAST(@pID AS VARCHAR(11)) 

EXEC WriteLog 
    'Component', 
    'Source', 
    @string 
+3

Esperaba evitar las variables intermedias. ¿Hay una forma adecuada de hacer esto sin presentarlos? – WorkerThread

+0

Ah, acabo de ver tu explicación. Gracias por aclarar esto. – WorkerThread

+0

@Worker - Todo es un poco molesto. MS reconoce tanto aquí https://connect.microsoft.com/SQLServer/feedback/details/352110/t-sql-use-scalar-functions-as-stored-procedure-parameters –

2
DECLARE @pID int; 
declare @IdAsString varchar(100) 

SET @pID = 1; 

Select @IdAsString ='Could not find given id: ' + Cast(@pId as varchar(10)) 

EXEC WriteLog 'Component', 'Source', @IdAsString 

Como señala Martin, el siguiente no sólo se aplica a las columnas de variables.

Tenga en cuenta que he modificado el yeso a varchar(10) esto permitirá enteros mayores de 1 dígito. varchar sólo permitirá 1 carácter

+1

@Barry - Eso es cierto para una columna pero el valor predeterminado para una variable 'varchar' es 10.' seleccione CAST ('1234567890' como varchar) '. Sin embargo, necesitas '11' para todo el rango de' int' si vas a permitir negativos. –

+0

@Martin - bueno, yo no sabía eso. Gracias por señalar. ¿Sabes por qué el comportamiento es diferente? – codingbadger

+0

@Barry - No, parece una incoherencia bastante desconcertante. Supongo que probablemente haya alguna razón histórica ... –

1

No se puede operar sobre los parámetros de un procedimiento almacenado. Debe asignar ese valor a otra variable y luego pasarlo a su SP.

DECLARE @pID int, @nameId VARCHAR(100); 
SET @pID = 1; 
SET @nameId = 'Could not find given id: ' + CAST(@pID AS varchar); 

EXEC WriteLog 'Component', 'Source', @nameId 
0

Quizás es algo como esto?

DECLARE @pID int; 
SET @pID = 1; 

DECLARE @Message NVARCHAR(50); 

SET @Message = 'Could not find given id: ' + CAST(@pID AS varchar) 
EXEC WriteLog 'Component', 'Source', @Message; 
0

probar este lugar ...

DECLARE @pID int; 
SET @pID = 1; 

DECLARE @message varchar(255); 
SET @message = 'Could not find given id: ' + CAST(@pID AS varchar) 

EXEC WriteLog 'Component', 'Source', @message; 
0

DECLARE @ id int

SET @ Id = 10

SELECT LTRIM (RTRIM (STR (@id))) AS stringValue

Cuestiones relacionadas