I realise this is a very similar question to Stop SSMS from scripting SPs using sp_executesql?
However, they seem to have changed the behaviour with SSMS 2012.
I
The closest you can get to this functionality is to go under tools, options, SQL Server Object Explorer, Scripting, then set the Check for Object Existing to false.
The drawback is that if you do this then drops and creates will always try to drop even if the object does not exist. The ideal solution would be a setting that allowed your script to look like the example below for creating Views, Procedures, and User-Defined Functions.
/****** 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
In short if the scripting engine thinks of the drop and create together in checking for object existance it does not need to put the condition on the create.
I also struggled with the same issue. If you need to script out the objects for an entire database, you might want to consider ApexSQL Script. I tried several tools and ApexSQL scripted the objects exactly how I needed. (if object exists, then drop. create the object). I believe it also works from the command-line. Note, it is shareware; I've only used the evaluation version because I only needed it a handful of times.
Below is an example of the output for a procedure after some configuration.
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
I found a good solution to this problem. You must make "two passes" when scripting. During the first pass, select the options to Check for Existence AND for only the DROP script. Then, on the second pass, de-select the option for Check for Existence and select the CREATE script. In addition, use the option Append To File. Then when running the generate scripts on the second pass, uncheck the option for "Overwrite File". This will only work if you are generating a separate file for each object.
You can't do this without the dynamic SQL because a stored procedure has to be in its own batch. Therefore you can't say:
IF <some condition>
<start a new batch>
The only way to keep that in the same batch is to use sp_executesql
.
If you're going to script the DROP
and CREATE
simultaneously, just do it without the check for object existence. This will give you:
DROP PROCEDURE ...;
GO
CREATE PROCEDURE ...;
GO
Who cares if the DROP
fails? (It shouldn't, because you just scripted from it!)
If you're scripting this for another system that might have the object, you'll get an error message for the DROP
when it doesn't, but the CREATE
will still happen, so you can ignore the DROP
errors. If you really want you can manually wrap the DROP
statements in TRY/CATCH
but I don't think it's necessary.
If you need to do this for a lot of procedures, or if you really need the process to not generate benign errors, I suggest you abandon Management Studio's primitive scripting options and use a 3rd party tool for this. They'll have already dealt with many of the issues you haven't yet come across, but will. I blogged about this:
http://bertrandaaron.wordpress.com/2012/04/20/re-blog-the-cost-of-reinventing-the-wheel/