【问题标题】:SQL Server script: ALTER PROCEDURE - Executing multiple ALTER PROCEDURE into one script without having to select each of the ALTER one after anotherSQL Server 脚本:ALTER PROCEDURE - 将多个 ALTER PROCEDURE 执行到一个脚本中,而不必一个接一个地选择每个 ALTER
【发布时间】:2025-12-04 05:30:01
【问题描述】:

我知道这不是什么大问题,但无论如何它都会让我发痒。

  1. 我有一个 SQL Server 2005 脚本来创建新的数据表、约束、更改某些表以添加列、更改程序以考虑表更改等。
  2. 在脚本遇到我的 ALTER PROCEDURE 语句之前一切正常。
  3. 报错信息如下:

“消息 156,级别 15,状态 1,程序 cpromo_Get_ConsultDetails_PromotionBan, 第 59 行 关键字“程序”。

这是我的脚本示例:

ALTER PROCEDURE [dbo].[cpromo_Get_ConsultDetails_PromotionBan] 
(
 @idPromoBan int, 
 @uid int 
)
AS
begin
 set nocount on;

 /* 1-  detail de la promo */
 SELECT p.[nopromo], p.[StartDate], p.[EndDate], p.[DateText]
 FROM [cpromo_PromotionBanniere] as pb
 INNER JOIN [cpromo_Promotions] as p ON p.[idPromo] = pb.[idPromo]
 WHERE (pb.[idPromoBan] = @idPromoBan)

 /* 2 - cartes de la promo */
 SELECT pis.[idCardText], ct.[nom], ct.[descr], ct.[prix], ct.[prixCoupon], ct.[qtyItem], i.[Impact]
 FROM [cpromo_PromotionsItems] as pis
 INNER JOIN [cpromo_Impacts] as i ON i.[idImpact] = pis.[idImpact] 
 INNER JOIN [cpromo_CardText] as ct ON ct.[idCardText] = pis.[idCardText]
 WHERE (pis.[idPromoBan] = @idPromoBan)
 ORDER BY i.[iorder], ct.[nom];

 /* 3 - pvedettes opti */
 SELECT m.[idCardText], m.[qtyCardL], m.[qtyCardM], m.[qtyCardMG], m.[qtyCardS],
     ISNULL(m.[qtyCardMini], 0) as qtyCardMini,
     ISNULL(m.[qtyCardMiniPTJ], 0) as qtyCardMiniPTJ
 FROM [cpromo_MEMCards] as m
 INNER JOIN [cpromo_CardText] as ct ON ct.[idCardText] = m.[idCardText]
 WHERE (m.[idPromoBan] = @idPromoBan)
 ORDER BY ct.[nom];


 /* 4 - cart */
 SELECT [idCartEl], [idCardText], [qtyL], [qtyM], [qtyMG], [qtyS],
     ISNULL([qtyMini], 0) as qtyMini,
     ISNULL([qtyMiniPTJ], 0) as qtyMiniPTJ
 FROM [cpromo_UserCarts]
 WHERE ([uid] = @uid AND [idPromoBan] = @idPromoBan);
end


ALTER PROCEDURE [dbo].[cpromo_Get_CartItems_ByPromotionBan] 
(
 @uid int,
 @idPromoBan int 
)
AS
begin
 set nocount on;

 SELECT ct.nom, ct.descr, p.DateText, ct.prix, ct.prixCoupon, ct.qtyItem,
           uc.qtyL, uc.qtyM, uc.qtyMG, uc.qtyS,
     isnull(uc.qtyMini, 0) as qtyMini,
     isnull(uc.qtyMiniPTJ, 0) as qtyMiniPTJ, 3 as qteLimite
 FROM cpromo_UserCarts as uc
 INNER JOIN cpromo_CardText as ct ON ct.idCardText = uc.idCardText 
 INNER JOIN cpromo_PromotionBanniere as pb ON pb.idPromoBan = uc.idPromoBan 
 INNER JOIN cpromo_Promotions  as p ON p.idPromo = pb.idPromo
 WHERE (uc.uid = @uid) AND (uc.idPromoBan = @idPromoBan);
end

错误指向双击时遇到的第一个“end”关键字。我根本没有得到的是当一个又一个选择一个 ALTER 语句时,它运行得很好而且很流畅!当我尝试通过按 [F5] 而不进行选择来运行它们时,它给了我错误。

我尝试将 ALTER 语句嵌入到另一个 BEGIN...END 中,但没有成功,它说关键字 ALTER...附近存在语法错误...

编辑:可能是因为我注释了在开始语句之后执行的修改吗?

ALTER PROCEDURE [dbo].[cpromo_Get_ConsultDetails_PromotionBan] 
    (
     @idPromoBan int, 
     @uid int 
    )
    AS
    begin
------------------
-- Added column to take table changes into account blah blah blah...
------------------
     set nocount on;

     /* 1-  detail de la promo */
     SELECT p.[nopromo], p.[StartDate], p.[EndDate], p.[DateText]
     FROM [cpromo_PromotionBanniere] as pb
     INNER JOIN [cpromo_Promotions] as p ON p.[idPromo] = pb.[idPromo]
     WHERE (pb.[idPromoBan] = @idPromoBan)

     /* 2 - cartes de la promo */
     SELECT pis.[idCardText], ct.[nom], ct.[descr], ct.[prix], ct.[prixCoupon], ct.[qtyItem], i.[Impact]
     FROM [cpromo_PromotionsItems] as pis
     INNER JOIN [cpromo_Impacts] as i ON i.[idImpact] = pis.[idImpact] 
     INNER JOIN [cpromo_CardText] as ct ON ct.[idCardText] = pis.[idCardText]
     WHERE (pis.[idPromoBan] = @idPromoBan)
     ORDER BY i.[iorder], ct.[nom];

     /* 3 - pvedettes opti */
     SELECT m.[idCardText], m.[qtyCardL], m.[qtyCardM], m.[qtyCardMG], m.[qtyCardS],
         ISNULL(m.[qtyCardMini], 0) as qtyCardMini,
         ISNULL(m.[qtyCardMiniPTJ], 0) as qtyCardMiniPTJ
     FROM [cpromo_MEMCards] as m
     INNER JOIN [cpromo_CardText] as ct ON ct.[idCardText] = m.[idCardText]
     WHERE (m.[idPromoBan] = @idPromoBan)
     ORDER BY ct.[nom];


     /* 4 - cart */
     SELECT [idCartEl], [idCardText], [qtyL], [qtyM], [qtyMG], [qtyS],
         ISNULL([qtyMini], 0) as qtyMini,
         ISNULL([qtyMiniPTJ], 0) as qtyMiniPTJ
     FROM [cpromo_UserCarts]
     WHERE ([uid] = @uid AND [idPromoBan] = @idPromoBan);
    end

感谢任何帮助或任何提示。

【问题讨论】:

  • 按照建议,我在每个 ALTER PROCEDURE 开始...结束后插入“GO”,然后它在“ALTER”附近显示另一个语法错误。
  • 我确实尝试按照此处另一位程序员的建议删除所有参数括号(我很遗憾没有时间记住他的名字),但仍然有错误消息 Msg 156, Level 15 ,状态 1,过程 cpromo_Get_ConsultDetails_PromotionBan,第 59 行 关键字“ALTER”附近的语法不正确。当我双击它时,它会将我指向第一个“end”关键字。
  • 我是否应该考虑说我所做的是复制并粘贴为每个过程生成的 ALTER PROCEDURE 脚本?
  • 我知道它很长而且读起来不太有趣。对不起。这个项目位于一个客户站点,我没有得到内部编程团队的太多支持。
  • 好吧,我成功解决了我的语法错误。我要感谢大家的答案,我将设置为正确的解决方案。这都是你的答案。

标签: sql-server-2005 alter-table alter sql-scripts


【解决方案1】:

这个答案不是我的,因为它是我得到的所有答案的结果。每个答案都有解决方案的一部分,所以我想给出一个答案,其中包含解决方案的所有要点。

  1. 在每个 ALTER PROCEDURE 语句之间插入一个“GO”语句(每个回答的人)
  2. 确保空白区域中没有不可见的字符 (Arvo)
  3. BEGIN...END 语句被发现是不必要的 (Mayo)
  4. 根据程序核心在 AS...GO 中删除分号似乎也造成了一些麻烦 (Mayo)
  5. 我的问题编辑中描述的程序核心中的 cmets 无关紧要,一旦检查了上述几点(我自己),它就不会导致任何错误

希望有一天这会对某人有所帮助。

感谢大家,感谢大家!

【讨论】:

    【解决方案2】:

    在更改语句之间插入“go”

    【讨论】:

    • 感谢 Matts Wrock 的回答。我按照我的问题中的评论进行了尝试,但随后在关键字 ALTER 附近出现语法错误,尽管当作为单个 ALTER 语句运行时(选中时),它们都运行得很好而且很流畅。即使插入了“GO”关键字。
    【解决方案3】:

    在您的第一个 ALTER PROCEDURE BEGIN ... END 之后放一个 GO

    【讨论】:

    • 感谢您的及时答复。你注意到我的编辑了吗?可以是它周围的东西吗?
    • 您在这些语句中没有 BEGIN ... END?
    • 我终于习惯在 ALTER PROCEDURE 语句本身中不包含任何 BEGIN...END 语句。
    【解决方案4】:

    在每个end 过程语句之后添加一个go 语句。 go "向 SQL Server 实用程序发出一批 Transact-SQL 语句结束的信号。" (http://msdn.microsoft.com/en-us/library/ms188037.aspx)。

    【讨论】:

    • 它现在给了我错误:消息 156,级别 15,状态 1,过程 cpromo_Get_ConsultDetails_PromotionBan,第 59 行关键字“ALTER”附近的语法不正确。
    【解决方案5】:

    我同意 go 语句 - 但参数周围的括号可能导致语法错误?这是我的团队使用的...

    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS OFF 
    GO
    
    ALTER PROCEDURE dbo.proc
    @param1 int
    AS
       select 1
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
    
    -- repeat for additional procedures
    

    【讨论】:

    • 所以不会有任何 begin...end 语句?
    • 无论如何我都要试试。谢谢!
    • 这里是我在删除 begin...end 语句时收到的错误消息:发生了致命的脚本错误。解析 GO 时遇到不正确的语法。
    • 我通常看不到的唯一另一件事是您的某些陈述末尾的分号。也许那些阻止了 AS 和 GO 之间的代码被解释为单个块?
    • 我确实删除了分号,但错误仍然存​​在。我将尝试按照 Arvo 的建议删除任何不可见的字符。我们不知道!感谢您的时间和考虑回答我的问题。
    【解决方案6】:

    您可能在第一个和第二个过程之间的空白区域中有一些不可见的字符(例如 nbspace)。删除 end 和后续 alter 之间的所有内容(包括换行符 - 导致 endALTER),然后放回一些换行符并在某行写入 GO。

    在从网上复制一些示例代码后,我亲眼目睹了这一点:)

    【讨论】:

    • 谢谢!这绝对是我没有想到的! :-) 上帝知道它会发生!呵呵呵呵……我试试!
    • 这解决了我的部分问题,因为报告的错误数量急剧减少,这根本不是戏剧性的! ;-) 谢谢!
    最近更新 更多