不幸的是,在Dynamic SQL中使用OUTPUT参数我只得到null值

时间:2015-11-03 12:39:55

标签: sql-server tsql

我看了一下Microsoft.com的这个页面 https://msdn.microsoft.com/en-us/library/ms188001.aspx 但是我做错了什么?我只能从动态sql语句中获取空值

DECLARE @ParmDefinition NVARCHAR(500)
declare @mynum int,@tempin int
declare @mychar char(5),@tempchar  char(4)
declare @mysqluse char(19)
declare @comname char(200),@sqlstr nvarchar(1000)
declare @tabname1 char(30),@tabname2 char(30)

select @mynum=1
while @mynum<99 
begin

 select @tempin=1000+@mynum
 select @tempchar=convert(char(4),@tempin)

 if @tempchar is null
 begin
  select 'exception occured,program terminated!'
  return
end 

     select @mychar='ms'+right(@tempchar,3)--dynamic change the database

      select @comname=@mychar


     declare @ldt_ksrq datetime, @ldt_jsrq datetime, @ls_prod varchar(50)
     set @ldt_ksrq = '2015-09-26'   
     set @ldt_jsrq = '2015-10-26'  
     set @ls_prod  = '3%'           



 declare @ld_kcje numeric(10,2), @ld_xsje numeric(10,2), @ld_yhje1 numeric(10,2), @ld_thje numeric(10,2), @ld_yhje2 numeric(10,2)
 declare @ld_dcje numeric(10,2), @ld_drje numeric(10,2), @ld_jcje numeric(10,2), @ld_tcje numeric(10,2)
 declare @ld_kcjeout numeric(10,2), @ld_xsjeout numeric(10,2), @ld_yhje1out numeric(10,2), @ld_thjeout numeric(10,2), @ld_yhje2out numeric(10,2)
 declare @ld_dcjeout numeric(10,2), @ld_drjeout numeric(10,2), @ld_jcjeout numeric(10,2), @ld_tcjeout numeric(10,2)
 SET NOCOUNT ON
 select @tabname1=@mychar+'.dbo.prod_dep'
 select @tabname2=@mychar+'.dbo.product'
 select @sqlstr='select @ld_kcjeout = sum(pd.lest_num * p.retail_price + pd.part_num  *  p.part_price ) from @tabnamein1 pd, @tabnamein2 p where pd.prod_no = p.prod_no and pd.prod_no not like @ls_prodin'
  SET @ParmDefinition = N'@ld_kcjeout numeric(10,2) OUTPUT,@tabnamein1 char(30),@tabnamein2 char(30),@ls_prodin varchar(50)'
   exec  sp_executesql @sqlstr,
       @ParmDefinition,
       @ld_kcjeout=@ld_kcje OUTPUT,
       @tabnamein1=@tabname1,
       @tabnamein2=@tabname2, 
       @ls_prodin=@ls_prod


    select @tabname1=@mychar+'.dbo.bill_main'
    select @tabname2=@mychar+'.dbo.bill_sub'
    select @sqlstr='select @ld_xsjeout  = sum((s.num + s.part_num) * s.retail_price),
   @ld_yhje1 = sum((s.num + s.part_num) * (s.yj_price - s.retail_price)) from @tabname1in m, @tabname2in s where m.bill_no = s.bill_no and m.bill_date >= @ldt_ksrqin and m.bill_date < @ldt_jsrqin and m.bill_no like  ''S%'' and s.prod_no not like @ls_prod and (s.num + s.part_num)>0'

    SET @ParmDefinition = N'@ld_xsjeout numeric(10,2) OUTPUT,@ld_yhje1out numeric(10,2) OUTPUT,@tabname1in char(30),@tabname2in char(30),@ls_prodin varchar(50),@ldt_ksrqin datetime,@ldt_jsrqin datetime'

    EXEC sp_executesql  @sqlstr,
    @ParmDefinition,
    @ld_kcjeout=@ld_kcje OUTPUT,
    @ld_yhje1out=@ld_yhje1 OUTPUT,
    @tabname1in=@tabname1,
    @tabname2in=@tabname2,
    @ls_prodin=@ls_prod  ,
    @ldt_ksrqin=@ldt_ksrq,
    @ldt_jsrqin=@ldt_jsrq;


....
end 

我只是无法弄清楚为什么@ ld_kcje,@ ld_yhje1变量的值都为null,这是SQL语句的输出变量 问候 肯

2 个答案:

答案 0 :(得分:0)

在组合变量时,沿着这些方向会是这样的,方括号可以满足变量中的任何奇数字符。

            Select  @sqlstr = 'select ['+@ld_kcjeout+'] = sum(pd.lest_num * p.retail_price + pd.part_num  *  p.part_price ) from ['+@tabname1+'] pd, ['+@tabname2+'] p where pd.prod_no = p.prod_no and pd.prod_no not like '''+@ls_prod+'''';

另外,我建议

  1. 在脚本开头创建临时结果表以捕获数据
  2. 而不是返回发生异常,程序终止!&#39;使用RAISERROR消息,否则您的数据集将在您的过程中进一步关闭
  3. 使用sp_MSforeachdb对多个数据库执行SQL

答案 1 :(得分:0)

有两种简单的方法可以做到这一点。既然你知道你期望的输出,为什么不把数据放到临时表中然后从中选择(下面的方法1)。

--method 1: drop dynamic output into a table
declare @result table(value nvarchar(100));
declare @sql nvarchar(max) = 'select 100';
insert into @result
exec sp_executesql @sql
select * from @result

--method 2: capture the output directly
declare @capturedoutput int;
set @sql = 'select @capturedoutput = 100';
EXEC sp_executesql @sql
 ,N'@capturedoutput int OUTPUT'
 ,@capturedoutput=@capturedoutput OUTPUT
select @capturedoutput