如何使用sp_executesql阻止SSMS 2012编写SP脚本

时间:2012-05-16 14:43:30

标签: sql-server ssms

我意识到这是一个与Stop SSMS from scripting SPs using sp_executesql?

非常相似的问题

但是,它们似乎改变了SSMS 2012的行为。

如果您选择了“检查存在”选项,请执行以下操作:

enter image description here

...它现在为即将创建的proc生成一个IF NOT EXISTS,以及作为前一个drop proc的IF EXISTS,如果像我通常那样选择DROP和CREATE选项:

enter image description here

这会强制它使用sp_executesql编写CREATE脚本。这是毫无意义的,因为如果DROP刚刚丢弃它,你不需要在CREATE上检查IF NOT EXISTS。

似乎不可能没有另一个。

有什么想法吗?

5 个答案:

答案 0 :(得分:9)

如果没有动态SQL,则无法执行此操作,因为存储过程必须位于其自己的批处理中。所以你不能说:

IF <some condition>
  <start a new batch>

保持同一批次的唯一方法是使用sp_executesql

如果您要同时编写DROPCREATE脚本,只需在不检查对象存在的情况下执行此操作。这会给你:

DROP PROCEDURE ...;
GO
CREATE PROCEDURE ...;
GO

谁在乎DROP失败了? (它不应该,因为你只是从它编写脚本!)

如果你为可能拥有该对象的另一个系统编写脚本,那么当DROP没有,CREATE时会收到错误消息,但{{1仍然会发生,所以你可以忽略DROP错误。如果你真的想要,你可以在DROP手动包装TRY/CATCH语句,但我不认为这是必要的。

如果你需要为很多程序执行此操作,或者如果您确实需要不产生良性错误的过程,我建议您放弃Management Studio的原始脚本选项并使用第三方工具。他们已经处理了许多你尚未遇到的问题,但是会。我在博客上写道:

http://bertrandaaron.wordpress.com/2012/04/20/re-blog-the-cost-of-reinventing-the-wheel/

答案 1 :(得分:5)

最接近此功能的是使用工具,选项,SQL Server对象资源管理器,脚本,然后将Check for Object Existing设置为false。

缺点是,如果你这样做,那么即使对象不存在,drop和created也会一直尝试丢弃。理想的解决方案是允许您的脚本看起来像下面的示例,用于创建视图,过程和用户​​定义函数。

/****** Object:  View [dbo].[vEmployees]    Script Date: 9/14/2012 9:18:57 AM ******/
IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vEmployees]'))
DROP VIEW [dbo].[vEmployees]
GO

CREATE VIEW [dbo].[vEmployees]
AS
    SELECT DISTINCT
        Employees.EmployeeID,
        FirstName,
        LastName
    from
        Employees
            JOIN Sales on Employees.EmployeeID=Sales.EmployeeID
GO

简而言之,如果脚本引擎认为丢弃并在检查对象存在时一起创建,则不需要将条件放在创建上。

答案 2 :(得分:1)

我找到了解决这个问题的好方法。 你必须做两次通过&#34;编写脚本时。 在第一次传递期间,选择仅检查DROP脚本的检查存在的选项。 然后,在第二遍中,取消选择Check for Existence选项并选择CREATE脚本。此外,使用“附加到文件”选项。然后在第二次传递时运行生成脚本时,取消选中&#34; Overwrite File&#34;的选项。这仅在您为每个对象生成单独的文件时才有效。

答案 3 :(得分:0)

我也在努力解决同样的问题。如果需要为整个数据库编写脚本,可能需要考虑ApexSQL脚本。我尝试了几种工具,ApexSQL完全根据我的需要编写了对象脚本。 (如果对象存在,则删除。创建对象)。我相信它也适用于命令行。注意,它是共享软件;我只使用了评估版,因为我只需要几次。

以下是一些配置后的过程输出示例。

IF (EXISTS(SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[myProcedure]') AND [type]='P'))
DROP PROCEDURE [dbo].[myProcedure]
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE dbo.myProcedure
AS
    select 1 as a
GO

答案 4 :(得分:0)

最后,在搜索了大量文章之后,我找到了解决方案,你必须在scripting时进行&#34;两次通过&#34; 。在第一次传递期间,

  • 选择“检查存在的选项”并仅选择DROP脚本。
  • 然后,在第二次传递de-select选中“检查存在”并选择CREATE脚本。
    • 此外,使用选项Append To File。然后,当在第二次传递上运行生成脚本时,取消选中"Overwrite File"的选项。这仅在您为每个对象生成单独的文件时才有效。