7

He creado un procedimiento de SQL dinámico que tiene una instrucción de selección y el código que parece:error de SQL dinámico nvarchar convertir a int

ALTER PROCEDURE cagroup (
    @DataID INT , 
    @days INT , 
    @GName VARCHAR(50) , 
    @T_ID INT , 
    @Act BIT , 
    @Key VARBINARY(16) 
) 
AS 
BEGIN 
    DECLARE @SQL NVARCHAR(MAX) 
    DECLARE @SchemaName SYSNAME 
    DECLARE @TableName SYSNAME 
    DECLARE @DatabaseName SYSNAME 
    DECLARE @BR CHAR(2) 
    SET @BR = CHAR(13) + CHAR(10) 

    SELECT @SchemaName = Source_Schema , 
      @TableName = Source_Table , 
      @DatabaseName = Source_Database 
    FROM Source 
    WHERE ID = @DataID 

SET @SQL = 'SELECT ' + @GName + ' AS GrName ,' + @BR 
       + @T_ID + ' AS To_ID ,' + @BR 
       + @DataID + ' AS DataSoID ,' + @BR 
       + @Act + ' AS Active ,' + @BR 
       + Key + ' AS key' + @BR 
       + 'R_ID AS S_R_ID' + @BR 
       + 'FROM' + @DatabaseName + '.' 
       + @SchemaName + '.' 
       + @TableName + ' t' + @BR 
       + 'LEFT OUTER JOIN Gro g ON g.GName = ' 
        + @GName + @BR + 'AND g.Data_ID] =' + @DataID + @BR 
        + 't.[I_DATE] > GETDATE() -' + @days + @BR 
        + 'g.GName IS NULL 
         AND ' + @GName + ' IS NOT NULL 
         AND t.[Act] = 1' + @BR 

    PRINT (@SQL) 
END 

Cuando Estoy ejecutando este procedimiento con esta declaración:

Exec dbo.cagroup 1,10,'[Gro]',1,1,NULL 

Recibo el siguiente error.

Msg 245, nivel 16, estado 1, Procedurecagroup, Línea 33 Error de conversión al convertir el valor nvarchar 'SELECT [Gro] AS gname, ' a tipo de datos int.

¿Dónde estoy equivocado?

+0

Ese código no funciona o ha sido modificado desde el código de trabajo para que no funcione. En particular, @GName no está declarado por lo que puedo decir y en cualquier caso, este bit de código: AND '+ @GName +' IS NOT NULL no funcionará a menos que @GName tenga espacios en blanco en el anverso y el reverso. –

+0

@Cade Roux Edité el código que solo era –

+0

del error tipográfico ¿cuál es la necesidad de la dinámica? – DForck42

Respuesta

13

Debe CASTAR todos los números a nvarchar en la concatenación.

No hay una conversión de estilo VBA implícita a la cadena. En el tipo de datos de SQL Server, la precedencia significa que las entradas son más altas que nvarchar: por lo que toda la cadena intenta ser CAST a int.

SET @SQL = 'SELECT ' + @GName + ' AS GrName ,' + @BR 
       + CAST(@T_ID AS nvarchar(10)) + ' AS To_ID ,' ... 

Editar: Will A tiene un buen punto: ¡mira para NULLs!

+0

@GBN Muchas gracias. Agregué el molde a todos los números y cuando lo ejecuto solo dice Query Executed con éxito, no imprime el enunciado sql. ¿Hay algo que necesite modificar –

+0

mirar en la ventana de mensajes – StingyJack

+4

@Sam? Verifique que ninguno de los valores que está utilizando en su concatenación sean NULL - intente concatenar un NULL y terminará con un NULL. –

1

Si tiene que crear este tipo de SQL dinámico, es mejor obtener la información de la columna de los metadatos que pasarla.

Select * from Information_Schema.Columns Where [email protected] 

Tiene que escribir un cursor feo para construir el SQL. Esperar problemas de rendimiento. Hago mucho de esto durante el desarrollo para escribir código para mí, pero no me atrevo a ejecutarlo en producción.

+0

+1 por recomendar código genérico –