我意识到这是一个与Stop SSMS from scripting SPs using sp_executesql?
非常相似的问题但是,它们似乎改变了SSMS 2012的行为。
如果您选择了“检查存在”选项,请执行以下操作:
...它现在为即将创建的proc生成一个IF NOT EXISTS,以及作为前一个drop proc的IF EXISTS,如果像我通常那样选择DROP和CREATE选项:
这会强制它使用sp_executesql编写CREATE脚本。这是毫无意义的,因为如果DROP刚刚丢弃它,你不需要在CREATE上检查IF NOT EXISTS。
似乎不可能没有另一个。
有什么想法吗?
答案 0 :(得分:9)
如果没有动态SQL,则无法执行此操作,因为存储过程必须位于其自己的批处理中。所以你不能说:
IF <some condition>
<start a new batch>
保持同一批次的唯一方法是使用sp_executesql
。
如果您要同时编写DROP
和CREATE
脚本,只需在不检查对象存在的情况下执行此操作。这会给你:
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; 。在第一次传递期间,
de-select
选中“检查存在”并选择CREATE
脚本。
Append To File
。然后,当在第二次传递上运行生成脚本时,取消选中"Overwrite File"
的选项。这仅在您为每个对象生成单独的文件时才有效。