【问题标题】:Alter View within stored procedure在存储过程中更改视图
【发布时间】:2017-03-16 21:05:24
【问题描述】:

我们如何改变存储过程中的视图?

create procedure createviewupdatepenaltypointsconsecutive
as
begin
alter VIEW consecutive
as


WITH cte as (
    SELECT *, 
           LAG([pointsRewarded], 1) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev1_points,
           LAG([pointsRewarded], 2) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev2_points,
           LAG([pointsRewarded], 3) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev3_points
    FROM week1
)
SELECT *,
       CASE WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10  AND prev3_points = -10 
            THEN -200
            WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10 
            THEN -100
            WHEN [pointsRewarded] = -10 AND prev1_points = -10
            THEN -50
            ELSE 0
       END penalty       
FROM cte

end

M 收到此错误: 消息 156,级别 15,状态 1,过程 createviewupdatepenaltypointsconsecutive,第 4 行 关键字“VIEW”附近的语法不正确。 消息 319,级别 15,状态 1,过程 createviewupdatepenaltypointsconsecutive,第 8 行 关键字“with”附近的语法不正确。如果这个语句是一个公用表表达式、一个 xmlnamespaces 子句或一个更改跟踪上下文子句,则前面的语句必须以分号结束。

【问题讨论】:

  • 在这个过程中重新创建视图有什么意义?视图定义似乎没有以任何方式改变,存储过程没有应用任何逻辑,也没有接受任何参数。
  • 我试图解决的问题需要我将视图放在存储过程中。

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2012


【解决方案1】:

您将无法像在存储过程中那样运行ALTER VIEW 语句。因此,要解决您的问题,您必须采取 2 项措施:

1) 要更正当前出现的错误,您必须在 CTE 开头使用分号,如下所示:

WITH cte as (
    SELECT *, 
       LAG([pointsRewarded], 1) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev1_points,
       LAG([pointsRewarded], 2) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev2_points,
       LAG([pointsRewarded], 3) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev3_points
FROM week1)
SELECT *,
   CASE WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10  AND prev3_points = -10 
        THEN -200
        WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10 
        THEN -100
        WHEN [pointsRewarded] = -10 AND prev1_points = -10
        THEN -50
        ELSE 0
   END penalty       
FROM cte

(或者更好地开始使用分号终止所有 SQL 语句,因为不推荐使用替代方法)。

2) 将您的 alter view 语句转换为动态 SQL 字符串并使用 sp_executesql 执行它,因为 ALTER VIEW 语句必须是批处理中的第一个:

CREATE PROCEDURE createviewupdatepenaltypointsconsecutive
AS
BEGIN
   DECLARE @STMT AS NVARCHAR(MAX) =
   '
  ALTER VIEW consecutive
  AS


  WITH cte as (
      SELECT *, 
             LAG([pointsRewarded], 1) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev1_points,
             LAG([pointsRewarded], 2) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev2_points,
             LAG([pointsRewarded], 3) OVER (PARTITION BY [EmployeeID] ORDER BY [WeekNumber]) as prev3_points
      FROM week1
  )
  SELECT *,
         CASE WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10  AND prev3_points = -10 
              THEN -200
              WHEN [pointsRewarded] = -10 AND prev1_points = -10  AND prev2_points = -10 
              THEN -100
              WHEN [pointsRewarded] = -10 AND prev1_points = -10
              THEN -50
              ELSE 0
         END penalty       
  FROM cte
   '
   EXEC sp_executesql @STMT;
END

【讨论】:

  • 感谢您的输入。第二点,请告诉我怎么做?
  • 我编辑了我的答案,希望能完全回答您的问题。但是,正如 Damien_The_Unbeliever 在上面的 cmets 中提到的那样,您真的应该认为这是一种不好的做法。
  • 非常感谢。你是个天才。这很有帮助。
  • M 出现错误:消息 102,级别 15,状态 1,过程连续,第 6 行 ';' 附近的语法不正确。
  • 对不起,在我的第一次编辑中,我在答案的错误部分进行了更正。原因是 SQL Server 无法确定 WITH 是指选项还是 CTE 的开始。因此,如果您在多语句批处理中使用 CTE,并且不使用分号终止语句,则必须在 CTE 的开头添加分号,以便 SQL Server 了解您正在使用 CTE。实际上,您终止前一个语句的方式。在您的情况下,尽管 CTE 没有前面的语句来终止,因此分号是错误的。我希望我现在已经为你说清楚了!
猜你喜欢
  • 2017-03-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
相关资源
最近更新 更多