The stored procedure scripts that SQL Server Management Studio 2005 generates for me are like:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[APY_SP_ACH_Transmit_Finish]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql #statement = N'
...
print ''arg!, all the quotes are escaped''
...
'
END
so all the quotes are escaped. is there a way or option to turn this off?
in SQL Server Management Studio 2005. I do the following:
1) In Object Explorer, locate the procedure I want to script out
2) right click, and select script stored procedure as "Create To"
3) selecting file or clipboard has the same effect.
This seems to happen when the scripting option "Include If NOT EXISTS" clause is on.
Do you need this on? If not you can turn it off via the
Tools -> Options -> Scripting
From this Connect item it doesn't look configurable without that.
Related
Whenever I attempt to "modify" or use the "script to" function with a stored procedure within SQL Server Management Studio, every single quote in the SP is replaced with a double quote. Whenever any of my colleagues uses modify or script to, they receive the output in single quotes. The double quotes break the query. It appears to be a setting within SSMS, but I cannot find any such setting.
Any advice would be appreciated.
I believe you are getting dynamic SQL from the scripting options because you have this option selected:
Tools > Options > SQL Server Object Explorer > Scripting > Check for object existence
When this setting is enabled, the script is generated like this:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = ...)
BEGIN
EXEC dbo.sp_executesql #statement = N'ALTER PROCEDURE...'
END
Disable this option, and it should be correct when you use right-click > Modify or right-click > Script stored procedure as > ALTER to >.
I created many numbered stored procedures in SQL Server 2008.
Their names are e.g.: dbo.ProcName, dbo.ProcName;2, dbo.ProcName;3,...
When I use rightclick on procedure name in procedures list in Management Studio 2008 and then click to Modify I can see and edit all stored procedure as I wrote above.
But in Management Studio 2012, after same action, I can see only the first procedure.
How to see and edit all stored procedures with the same name and suffix with semicolon?
Sounds like you are talking about numbered stored procedures.
I can reproduce the same behaviour. After running the following
CREATE PROCEDURE [dbo].[foo];1 #x int AS
PRINT 'x is ' + CONVERT(varchar(8), #x)
GO
CREATE PROCEDURE [dbo].[foo];2 #x char AS
PRINT 'x is ' + #x
GO
Selecting "Foo" in object explorer then "Modify" shows both versions in SSMS 2008 but only the first one in SSMS 2012.
These have been deprecated since 2005 so I wouldn't be surprised if it is a deliberate decision not to support them in the tools any more. Looks like Drop and Create still lists both versions though.
Another workaround:
EXEC sp_helptext 'dbo.ProcName';
You'll have to inject the GOs yourself, though.
You can also get the metadata this way:
SELECT definition
FROM sys.sql_modules
WHERE [object_id] = OBJECT_ID('dbo.ProcName')
UNION ALL
SELECT definition
FROM sys.numbered_procedures
WHERE [object_id] = OBJECT_ID('dbo.ProcName');
And this way:
SELECT [text] FROM syscomments
WHERE id = OBJECT_ID('dbo.ProcName');
And you can go through the Generate Scripts wizard:
right-click your database and choose Tasks > Generate Scripts
On the 'Choose Objects' screen, select 'Select specific database objects, check 'Stored Procedures', and expand to select the root name of the numbered stored procedure(s) you want to script.
On the 'Set Scripting Options' screen, choose 'Save to new query window.'
Click Next > Next > Finish.
I also filed a bug on this:
http://connect.microsoft.com/SQLServer/feedback/details/764197/ssms-2012-inconsistently-handles-numbered-procedures
I have a database in SQL Server 2008 R2 and I created this stored procedure for restoring databases:
CREATE PROCEDURE [dbo].[usp_DBRestore]
#DBName nvarchar(60)
,#BackName nvarchar(120)
,#OutMessage nvarchar(4000) output
--,
--#DataName varchar(60),
--#DataFileName varchar(120),
--#LogName varchar(60),
--#LogFileName varchar(120)
AS
BEGIN TRY
USE [master]
ALTER DATABASE #DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE #DBName FROM
DISK = #BackName WITH
FILE = 1, NOUNLOAD,
REPLACE,
PASSWORD = 'TEST'
SET #OutMessage = 'OK';
ALTER DATABASE #DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE
END TRY
BEGIN CATCH
ALTER DATABASE #DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE
INSERT [dbo].[ErrorLog]
(
[UserName],
[ErrorNumber],
[ErrorSeverity],
[ErrorState],
[ErrorProcedure],
[ErrorLine],
[ErrorMessage]
)
VALUES(
CONVERT(sysname, CURRENT_USER),
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_PROCEDURE(),
ERROR_LINE(),
ERROR_MESSAGE()
)
END CATCH
When I execute code I see this error :
a USE database statement is not allowed in a procedure, function or
trigger.
How can I solve this error?
You cannot do this in that way - you basically have two options:
stick to a stored procedure, but in that case, you have to use dynamic SQL. Your stored procedure creates a string of SQL statements, which allows it to use USE master and it allows it to dynamically set the database name etc., and then it executes that SQL statement using sp_executesql #sqlRestoreStatement. If you want to check this out, you MUST be all means read (and understand) Erland Sommarskog's seminal article The Curse and Blessings of Dynamic SQL
you can use a regular SQL script, possibly with SQLCMD placeholders (if you have SQLCMD mode enabled in your SQL Server Management Studio) and execute the restore from a regular script (which you can put into your own template folder, for instance). In that case, you'd have something like:
:setvar dbname YourDatabaseNameHere
DECLARE #FileName NVARCHAR(255)
SET #FileName = N'D:\YourBackupDirectory\SomeDatabase.bak'
RESTORE DATABASE [$(dbname)]
FROM DISK = #FileName
WITH FILE = 1,
MOVE N'YourDatabase_Data' TO N'D:\MSSQL\Data\$(dbname).mdf',
MOVE N'YourDatbase_Log' TO N'D:\MSSQL\Data\$(dbname)_Log.ldf',
NOUNLOAD, REPLACE,
STATS = 2
GO
With this setup, you can easily use the SQL script as a template and restore any kind of database using it.
You don't need the USE statement. Best is to remove Use statement and create / Alter this sp on master database itself.
If you want to take a backup execute this SP from master DB. I can not see any other way out.
You can create a linked server and have that referenced in your stored procedure.
For example. LinkedServer.database.[dbo].StoredProcedure
Check out this
How to create the linked server for SQL Server 2008 where we have the database from 2000 and 2005
I'm trying to drop and create a procedure in a single script. I tried this:
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'Foo')
DROP PROCEDURE Foo
GO
CREATE PROCEDURE dbo.Foo
-- procedure body here
But I get an error:
Incorrect syntax near 'GO'.
If I remove GO, I get an error:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch
Update
These scripts are being executed by a Java build tool (Maven)
GO is not actually a valid term in T-SQL, it's merely the separator that the Microsoft management tools use to delimit query batches.
What are you using to run the script? If you're trying to do it in code then you'll need to split it into two statements, perhaps using a regex to split on ^GO$
Try
IF OBJECT_ID ('idhere') IS NOT NULL
DROP PROCEDURE idhere
GO
CREATE PROCEDURE idhere
#paramsHere PARAMTYPE
AS
BEGIN
//...code here...
END
GO
This is how I do it, I'm not sure what version of SQL SERVER my work uses, I believe its 2005.
The easiest way I've found for executing a large scripts outside SSMS from a tool is to use the SQLCMD. (iSQL pre sql 2005) This will work with any environment that allows you to run a shell command.
From the MSDN article
The sqlcmd utility lets you enter
Transact-SQL statements, system
procedures, and script files at the
command prompt, in Query Editor in
SQLCMD mode, in a Windows script file
or in an operating system (Cmd.exe)
job step of a SQL Server Agent job.
This utility uses OLE DB to execute
Transact-SQL batches.
It would be better to use this syntax for the existence check:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[foo]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[foo]
GO
As written, if there was a foo sproc in any schema it would try to drop it. Not sure if that will make your problem go away though. If you use SSMS, there is an option to script a stored procedure as DROP and CREATE; that syntax should work.
Check Jon Galloway's post: Handling "GO" Separators in SQL Scripts - the easy way
It might have the answer you are seeking.
I'm using Visual Studio 2005 to script out a database so that I can put it in subversion. Now one complaint that I have is that it puts my stored procedure code in a single literal string, like in the example. below.
/****** Object: StoredProcedure [dbo].[MyStoredProc] Script Date: 08/19/2010 16:40:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[MyStoredProc]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
BEGIN
EXEC dbo.sp_executesql #statement = N'
CREATE PROCEDURE [dbo].[MyStoredProc]
-- My T-SQL code here
END'
END
GO
I don't like this because then the syntax highlighting is useless. Is there anyway that I can turn this behaviour off, i.e. so that it removes this part?
EXEC dbo.sp_executesql #statement = N'
What is the motivation for doing it this way in the first place? String quoting has always been a topic that's somewhat of a blindspot of mine so I'm sure I'm not aware of all the implications. I might be more accepting of this behaviour if I understood what it is for.
SQL Server Management studio scripts out as Execute SQL if you select the option
Include If Not Exists
If you uncheck that the script is generated as you are looking for.