简体   繁体   中英

Stored Procedure giving error

I'm trying to use a stored procedure to display the results of a table. The stored procedure is giving the error 'Procedure expects parameter '@parameters' of type 'ntext/nchar/nvarchar'

ALTER PROCEDURE COMNODE_PROC_SearchProduct --'','GUN',''

    @PRODUCTID INT = NULL,
    @PRODUCT_NAME VARCHAR(500) = NULL,
    @PRODUCT_POINTS INT = NULL  

AS
BEGIN

SET NOCOUNT ON;
   Declare @SQLQuery AS NVarchar(MAX)
   Declare @ParamDefinition AS NVarchar(MAX) 
    Set @ParamDefinition = '@ID INT,
    @NAME VARCHAR(500),
    @POINTS INT'

   Set @SQLQuery = 'SELECT PRODUCT_ID,PRODUCT_NAME,PRODUCT_REDEEM_POINTS FROM TBL_REDEEM_PRODUCT WHERE  (1 = 1)';

   If @PRODUCTID Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (PRODUCT_ID ='+CAST(@PRODUCTID AS VARCHAR(500) )     

   If @PRODUCT_NAME Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (PRODUCT_NAME =' + CAST(@PRODUCT_NAME AS VARCHAR(500) )    

   If @PRODUCT_POINTS Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (PRODUCT_REDEEM_POINTS ='+  CAST(@PRODUCT_POINTS AS VARCHAR(500))



    Execute sp_Executesql     @SQLQuery, 
            @ID = @PRODUCTID , 
            @NAME = @PRODUCT_NAME , 
            @POINTS = @PRODUCT_POINTS;

END

You need to pass in the parameter definition to sp_executesql , see: https://msdn.microsoft.com/en-us/library/ms188001.aspx

Execute sp_Executesql     @SQLQuery, 
        @ParamDefinition,
        @ID = @PRODUCTID , 
        @NAME = @PRODUCT_NAME , 
        @POINTS = @PRODUCT_POINTS;

One of the main reasons you would want to use sp_executesql so do not have to concatenate variables, have you can be protected from sql-injection attack using the parameterised query.

You concatenating parameters just kill the purpose and makes your query vulnerable to sql-injection . See below the proper use of dynamic sql the safe way.

ALTER PROCEDURE COMNODE_PROC_SearchProduct --'','GUN',''

    @PRODUCTID      INT          = NULL,
    @PRODUCT_NAME   VARCHAR(500) = NULL,
    @PRODUCT_POINTS INT          = NULL  

AS
BEGIN

SET NOCOUNT ON;
   Declare @SQLQuery AS NVarchar(MAX);
   Declare @ParamDefinition AS NVarchar(MAX);

    Set @ParamDefinition = N'@ID INT, @NAME VARCHAR(500), @POINTS INT';

    -- A much cleaner way to write this would be...

   Set @SQLQuery = N'SELECT PRODUCT_ID,PRODUCT_NAME,PRODUCT_REDEEM_POINTS 
                     FROM TBL_REDEEM_PRODUCT 
                      WHERE  (1 = 1)'
                 + CASE WHEN @PRODUCTID Is Not Null 
                   THEN N' And PRODUCT_ID = @ID ' ELSE N' ' END     
                 + CASE WHEN @PRODUCT_NAME Is Not Null 
                   THEN N' And PRODUCT_NAME = @NAME ' ELSE N' ' END     
                 + CASE WHEN @PRODUCT_POINTS Is Not Null 
                   THEN N' And PRODUCT_REDEEM_POINTS = @POINTS' ELSE N' ' END     



  Execute sp_Executesql  @SQLQuery
                        ,@ParamDefinition   --<-- this was missing 
                        ,@ID = @PRODUCTID 
                        ,@NAME = @PRODUCT_NAME 
                        ,@POINTS = @PRODUCT_POINTS;

END

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM