2017-09-02 56 views
1

我想运行以下存储过程。动态SQL错误

CREATE PROCEDURE NWR.GRADER 
    @YEAR AS NVARCHAR(4) 
AS 
BEGIN 
    DECLARE @sql1 as nvarchar(500) = 
     N'select a.*, b.pts as W_GRD_PTS 
      into nwr.atp_matches_' + @YEAR + N'WGP 
      from nwr.atp_matches_' + @YEAR + N' a 
      left join NWR.RNK_VAL as b on a.winner_rank >= low 
            and a.winner_rank<= high 

      alter table nwr.atp_matches_' + @YEAR + N'WGP 
      add L_GRD_PTS smallint null 

      UPDATE nwr.atp_matches_' + @YEAR + N'WGP 
      SET L_GRD_PTS = C.pts 
      FROM NWR.RNK_VAL C 
      WHERE loser_rank >= LOW AND loser_rank <= HIGH;' 

    --print (@sql1); 
    EXEC sys.sp_execute @sql1; 
end; 

exec nwr.GRADER @year='2016'; 

但是我发现了以下错误

消息214,级别16,状态2,过程sp_execute,行1个
过程需要类型 '诠释' 参数 '@Handle'。

但是当我切换到打印,而不是EXEC我得到正是我想象的那么下面的代码:

select a.*, b.pts as W_GRD_PTS 
into nwr.atp_matches_2016WGP 
from nwr.atp_matches_2016 a 
left join NWR.RNK_VAL as b on a.winner_rank >= low and a.winner_rank <= high 

alter table nwr.atp_matches_2016WGP 
    add L_GRD_PTS smallint null 

UPDATE nwr.atp_matches_2016WGP 
SET L_GRD_PTS=C.pts 
FROM NWR.RNK_VAL C 
WHERE loser_rank>= LOW AND loser_rank<= HIGH; 

任何人都可以解释我做错了吗?

+2

正是这种... EXEC sys.sp_execute @ sql1 ...应该是这样的... EXEC sys.sp_execute ** sql ** @ sql1; –

+0

另外:在单个查询中混合使用DML(数据操作 - 选择,插入,删除)和DDL(数据定义 - 更改表等)的做法始终是一个坏主意。每次运行这个存储过程时,一个新列“L_GRD_PTS”将被添加到您的表中......实际上,这只会在一次**之后有效,然后失败......不要这样做!让你** DDL **与你的其他代码分开! –

回答

3

的错误振振有辞的是,你正在使用,而不是sys.sp_executesqlsys.sp_execute

在一个侧面说明,我不禁注意到,它看起来像你的动态查询可以简化一点...只是把它扔在那里......

CREATE PROCEDURE NWR.GRADER 
    @YEAR AS NVARCHAR(4), 
    @Debug BIT = 0  -- 0=execute d-sql & 1=print d-sql... 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql1 as nvarchar(500) =N' 
SELECT 
    a.*, 
    W_GRD_PTS = b.pts, 
    L_GRD_PTS = c.pts 
    into nwr.atp_matches_' + @YEAR + N'WGP 
FROM 
    nwr.atp_matches_' + @YEAR + N' a 
    LEFT JOIN NWR.RNK_VAL as b 
     ON a.winner_rank >= b.low 
     AND a.winner_rank <= b.high 
    LEFT JOIN NWR.RNK_VAL c 
     ON a.loser_rank >= c.low 
     AND a.loser_rank<= c.high;' 

    IF @Debug = 1 
    BEGIN 
     PRINT(@sql1); 
    END; 
    ELSE 
    BEGIN 
     EXEC sys.sp_executesql @sql1; 
    END; 
END; 
GO 
+1

投掷罢工! – scsimon