Dynamic SQL with string including variables declar

2019-08-21 10:08发布

问题:

Is it possible to run dynamic SQL scripts that include declaration of variables?

Example:

Important note: this example is only to demonstrate the mechanism I need to implement. The shown calculation is trivial for the sake of simplicity.

I need to return the minimal value between 4 passed values so, programmatically, I create a string that contains the following code:

DECLARE @_1 INT = 12 ;
DECLARE @_2 INT = 22 ;
DECLARE @_3 INT = 32 ;
DECLARE @_4 INT = 42 ;
DECLARE @_Min   = NULL ;

SET @_Min = @_1 ;
IF (@_2 < @_Min) SET @_Min = @_2 ;
IF (@_3 < @_Min) SET @_Min = @_3 ;
IF (@_4 < @_Min) SET @_Min = @_4 ;

SELECT @_Min ;

Again, all this is contained in a string variable (say @_Command).

To execute this and get the result of the calculation, I would be running the following command:

EXECUTE sp_executesql @_l_Command                     , 
                      N'@_l_Result FLOAT OUTPUT'      , 
                      @_l_Result = @_l_Result OUTPUT    ;

When running it, I get an error message stating:

Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'DECLARE'.

Obviously I'm doing something syntactically wrong but cannot figure out what it could be.

回答1:

Yes you can declare variables in dynamic query.
please set @_Min variale type in query
I run you query without error

DECLARE @_l_Result NVARCHAR(MAX)
DECLARE @_l_Command NVARCHAR(MAX)='
DECLARE @_1 INT = 12 ;
DECLARE @_2 INT = 22 ;
DECLARE @_3 INT = 32 ;
DECLARE @_4 INT = 42 ;
DECLARE @_Min int  = NULL ;

SET @_Min = @_1 ;
IF (@_2 < @_Min) SET @_Min = @_2 ;
IF (@_3 < @_Min) SET @_Min = @_3 ;
IF (@_4 < @_Min) SET @_Min = @_4 ;

SELECT @_Min as res ;'

EXECUTE sp_executesql @_l_Command                     , 
                      N'@_l_Result FLOAT OUTPUT'      , 
                      @_l_Result = @_l_Result OUTPUT    ;

or

EXECUTE sp_executesql @_l_Command



回答2:

Apart from setting the variable type for @_Min,If you need to pass values then you should also pass the inputs as separate inputs while executing sp_executesql, like below

DECLARE @_l_Command nVarchar(max),@Params nVarchar(max)
SET @_l_Command='SET @_Min = @_1 ;
IF (@_2 < @_Min) SET @_Min = @_2 ;
IF (@_3 < @_Min) SET @_Min = @_3 ;
IF (@_4 < @_Min) SET @_Min = @_4 ;

SELECT @_Min ;'


SET @Params='@_1 INT,@_2 INT,@_3 INT,@_4 INT,@_Min INT'
EXECUTE sp_executesql @_l_Command,@Params,12,22,32,42,NULL