Update stored procedure using C#? - sql

I have 10 database servers and most procedures are the same.
So I plan to make procedure distribute program.
For convenient application, I want to use "the procedure modify code made by tool" itself.
For example, when I click modify button of the procedure on SSMS the code is like below.
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[HongTestProcedure] Script Date: 2020-08-28 오전 11:09:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: hong
-- Create date: 2020-03-07
-- =============================================
ALTER PROCEDURE [dbo].[HongTestProcedure]
-- Add the parameters for the stored procedure here
#ID varchar(10)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT *
FROM table
END
And then, if I want to modify the parameter of the procedure.
Maybe the code is like below:
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[HongTestProcedure] Script Date: 2020-08-28 오전 11:09:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: hong
-- Create date: 2020-03-07
-- =============================================
ALTER PROCEDURE [dbo].[HongTestProcedure]
-- Add the parameters for the stored procedure here
#ID varchar(10)
#ID2 varchar(10) -- it is added.
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT *
FROM table
END
I consider that program has a textbox and button.
and I want to insert all above code.
maybe it looks like it:
So, I try the code like below:
public bool UpdateProcedure(string dbip, string query)
{
DataSet ds = new DataSet();
SqlConnection sqlConn = new SqlConnection("server = " + dbip + dbInfo);
sqlConn.Open();
SqlCommand sqlComm = new SqlCommand(query, sqlConn);
sqlComm.ExecuteNonQuery();
return true;
}
If it run successfully, I will run query on 10 database servers.
But it return error message. even it can be run in SSMS.
incorrect syntax near 'GO'
CREATE/ALTER PROCEDURE must be the first statement in a query batch
Can I solve it?

Yes. Since you can construct it as an Dynamic SQL in C# and Open an SQL Connection and pass the Dynamic SQL to EXEC sp_executesql #DynamicSQL. This will create the required SP in the required Database.

Related

How to add header comments when altering stored procedures in SQL Server

I have a stored procedure where there are no header comments. I want to add them, but whenever I try, it is not included.
In SQL Server Management Studio I :
1.Right-click my stored procedure and click modify
USE [ABigDB]
GO
/****** Object: StoredProcedure [dbo].[spDoWork] Script Date: 21/08/2015 14:11:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spDoWork]
#Id uniqueidentifier,
#Session nvarchar(50),
#XMLData xml
WITH EXECUTE AS OWNER
AS
BEGIN
--etc etc...
END
2.I paste comments above the stored procedure and run the script :
-- Stored Procedure
-- Author: Dave
-- Create date: 21/08/2015
-- Description: Does Stuff
-- Change history
-- 07/08/2015 - Overlord - Done stuff
-- 06/08/2015 - Kerrigan - Done more stuff
USE [ABigDB]
GO
/****** Object: StoredProcedure [dbo].[spDoWork] Script Date: 21/08/2015 14:11:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spDoWork]
#Id uniqueidentifier,
#Session nvarchar(50),
#XMLData xml
WITH EXECUTE AS OWNER
AS
BEGIN
--etc etc...
END
3.When I modify the same stored procedure it appears as :
USE [ABigDB]
GO
/****** Object: StoredProcedure [dbo].[spDoWork] Script Date: 21/08/2015 14:11:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spDoWork]
#Id uniqueidentifier,
#Session nvarchar(50),
#XMLData xml
WITH EXECUTE AS OWNER
AS
BEGIN
--etc etc...
END
So how do I get the comments to appear there?
I solved it by doing the following:
USE [ABigDB]
GO
/****** Object: StoredProcedure [dbo].[spDoWork] Script Date: 21/08/2015 14:11:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Stored Procedure
-- Author: Dave
-- Create date: 21/08/2015
-- Description: Does Stuff
-- Change history
-- 07/08/2015 - Overlord - Done stuff
-- 06/08/2015 - Kerrigan - Done more stuff
ALTER PROCEDURE [dbo].[spDoWork]
#Id uniqueidentifier,
#Session nvarchar(50),
#XMLData xml
WITH EXECUTE AS OWNER
AS
BEGIN
--etc etc...
END
Consider using the meta data in addition to your procedures, tables, columns, etc. for documentation purposes.
See the following that helps when reviewing your db objects.
Is it possible to add a description/comment to a table in Microsoft SQL 2000+

SQLDependency throwing thousands of invalid notifications with stored proc

I've built a vb.net service to update Exchange appointments as appointment changes are made in our accounting suite. Everything works fine if I run the SQL query straight from VB.net but if I reference a stored proc with the exact same code I receive thousands of "invalid" notifications. I was wondering if anyone could tell me why?
I'm using VS2012, SQL Server 2008, and .NET 4.0
I pass each "option" into the query string and execute it before starting the dependency with this query:
select Dispatch_Id, Schedule_Time, Dispatch_Time, Arrival_Time, Departure_Time from dbo.Ticket_Dispatch
The stored proc is:
USE [database]
GO
/****** Object: StoredProcedure [dbo].[watch] Script Date: 1/22/2014 5:28:28 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
-- Create date:
-- Description:
-- =============================================
ALTER PROCEDURE [dbo].[watch]
-- Add the parameters for the stored procedure here
AS
BEGIN
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET QUOTED_IDENTIFIER ON;
SET NUMERIC_ROUNDABORT ON;
SET ARITHABORT ON;
select Dispatch_Id, Schedule_Time, Dispatch_Time, Arrival_Time, Departure_Time from dbo.Ticket_Dispatch
END
Before any of this I test for permissions. The user has ownership over the table and the proc so there shouldn't be any problems there.

Invalid Object Name - Stored Procedure

I am creating a stored procedure in SQL Server via SSMS.
I have written the stored procedure below, however when I click execute it am given the error:
Msg 208, Level 16, State 6, Procedure NewQuestion, Line 11
Invalid object name 'hgomez.NewQuestion'.
the table is ownership is correct. (hgomez.Questions)
USE [devworks_oscar]
GO
/****** Object: StoredProcedure [hgomez].[NewQuestion] Script Date: 10/23/2011 23:55:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [hgomez].[NewQuestion]
(
#QUESTIONNAME nvarchar(50),
#QUESTION_ID int OUTPUT
)
AS
/* SET NOCOUNT ON */
INSERT INTO [Questions] (QuestionText) VALUES (#QUESTIONNAME)
SET #QUESTION_ID = SCOPE_IDENTITY();
RETURN
Thanks in advance
I was a fan of always prepending my CREATE statements with an explicit check for existence and dropping if it was found.
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'NewQuestion' AND ROUTINE_SCHEMA = 'hgomez')
BEGIN
DROP PROCEDURE hgomez.NewQuestion
END
GO
-- this is always a CREATE
CREATE PROCEDURE [hgomez].[NewQuestion]
(
#QUESTIONNAME nvarchar(50),
#QUESTION_ID int OUTPUT
)
AS
/* SET NOCOUNT ON */
INSERT INTO [Questions] (QuestionText) VALUES (#QUESTIONNAME)
SET #QUESTION_ID = SCOPE_IDENTITY();
RETURN
That can be a bit of hassle with regard to permissions so others use an approach wherein they create a stub method only to immediately ALTER it.
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'NewQuestion' AND ROUTINE_SCHEMA = 'hgomez')
BEGIN
EXEC ('CREATE PROCEDURE hgomez.NewQuestion AS SELECT ''stub version, to be replaced''')
END
GO
-- This is always ALTER
ALTER PROCEDURE [hgomez].[NewQuestion]
(
#QUESTIONNAME nvarchar(50),
#QUESTION_ID int OUTPUT
)
AS
/* SET NOCOUNT ON */
INSERT INTO [Questions] (QuestionText) VALUES (#QUESTIONNAME)
SET #QUESTION_ID = SCOPE_IDENTITY();
RETURN
This script tries to modify a procedure that already exists; it doesn't create the procedure.
To create the procedure use CREATE PROCEDURE
CREATE PROCEDURE [hgomez].[NewQuestion]
Once the procedure exists, you can modify its definition by using ALTER PROCEDURE
ALTER PROCEDURE [hgomez].[NewQuestion]
This solution https://stackoverflow.com/a/26775310/2211788 explained
If you drop and re-create a stored procedure it gets a new objectid - the list of stored procedures in SSMS is linked to the id it knows at the time the list was built. If you re-create it but don't refresh the stored procedures folder then any attempts to edit it will indicate the procedure is not found as the id has changed.
This happened to me once when I had two instances of SSMS open and I was working on the one I opened first. Closed them both down, reopened and it worked fine.

EntityFramework and sp_executesql

Why when running the following auto-generated SQL from Entity Framework ObjectContext.ExecuteStoreCommand(), the parameters all result in NULL.
exec sp_executesql
N'SaveModel',
N'#ModelID int,#Name nvarchar(24),#Description nvarchar(34)',
#ModelID=4,
#Name=N'Status',
#Description=N'The status of a model.'
I've taken this SQL from Profiler after the ExecuteStoreCommand runs, as you can see the #ModelID param is being set to 4, Name = 'Status', Description = 'The status of the model'. However, when doing a print of ModelID in the stored procedure SaveModel, it is NULL. Here is the stored procedure demonstrating the null parameters:
USE [Bluewater]
GO
/****** Object: StoredProcedure [dbo].[SaveModel] Script Date: 08/09/2011 13:15:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Nicholas Barger
-- Create date: 08/07/2011
-- Description: Save model entity (create/update).
-- =============================================
ALTER PROCEDURE [dbo].[SaveModel]
#ModelID int = null,
#Name varchar(255) = null,
#Description varchar(1000) = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
PRINT ('ModelID: ' + CAST(ISNULL(#ModelID, 0) AS VARCHAR(10)));
END
-- POST ANSWER --
The problem was the original call using ExecuteStoreCommand(), I thought the first parameter requested only the name of the stored procedure, not the full stored procedure syntax. Here is an example of BROKEN code:
e.ExecuteStoreCommand("SaveModel", new SqlParameter[] {
new SqlParameter("ModelID", model.ModelID),
new SqlParameter("Name", model.Name),
new SqlParameter("Description", model.Description)
})
And here is the WORKING code:
e.ExecuteStoreCommand("SaveModel #ModelID, #Name, #Description", new SqlParameter[] {
new SqlParameter("ModelID", model.ModelID),
new SqlParameter("Name", model.Name),
new SqlParameter("Description", model.Description)
})
The sql that is generated there is not correct, the following sql yields the result you are expecting...
exec sp_executesql
N'SaveModel #ModelID, #Name, #Description',
N'#ModelID int,#Name varchar(24),#Description varchar(34)',
#ModelID=4,
#Name=N'Status',
#Description=N'The status of a model.'
Looks to me like this is either
A) A bug in Entity Framework
B) A problem with your Entity Model

How to Deal with SET ANSI_NULLS ON or OFF?

I want to call this procedure that sends one value that can be NULL or any int value.
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId =#SubDomainId
I simply want to use this single query rather than what i m doing right now in below given code.
I searched for this how could i do this then i got this Link.
According to this I have to set ANSI_NULLS OFF
I am not able to set this inside this procedure before executing my sql query and then reset it again after doing this.
ALTER PROCEDURE [Tags].[spOnlineTest_SubDomainSelect]
#SubDomainId INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF #SubDomainId IS NULL
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId IS NULL
ELSE
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId =#SubDomainId
END
What will be the better practice to do deal with ANSI_NULLS or Using If Else
SET ANSI_NULLS is ony defined at stored proc create time and cannot be set at run time.
From CREATE PROC
Using SET Options
The Database Engine saves the settings
of both SET QUOTED_IDENTIFIER and SET
ANSI_NULLS when a Transact-SQL stored
procedure is created or modified.
These original settings are used when
the stored procedure is executed.
Therefore, any client session settings
for SET QUOTED_IDENTIFIER and SET
ANSI_NULLS are ignored when the stored
procedure is running. Other SET
options, such as SET ARITHABORT, SET
ANSI_WARNINGS, or SET ANSI_PADDINGS
are not saved when a stored procedure
is created or modified. If the logic
of the stored procedure depends on a
particular setting, include a SET
statement at the start of the
procedure to guarantee the appropriate
setting. When a SET statement is
executed from a stored procedure, the
setting remains in effect only until
the stored procedure has finished
running. The setting is then restored
to the value the stored procedure had
when it was called. This enables
individual clients to set the options
they want without affecting the logic
of the stored procedure.
The same applies to SET QUOTED_IDENTIFIER
In this case, use IF ELSE because SET ANSI_NULLS will be ON in the future.
Or Peter Lang's suggestion.
To be honest, expecting SubDomainId = #SubDomainId to work when #SubDomainId is NULL is not really correct usage of NULL...
Can't you use a single query?
SELECT DomainName, DomainCode
FROM Tags.tblDomain
WHERE ( #SubDomainId IS NULL AND SubDomainId IS NULL )
OR ( SubDomainId = #SubDomainId )
FYI, I'm pretty sure ...
ANSI_NULLS OFF
Applies to the procedure when you create/edit it, it's like a setting of the procedure.
So either the procedure has it ON or OFF. Your example was a query not a procedure so I'm a little confused.
But if you have SQL 2005/2008 for example if you "edit" procedure it opens up your procedure in a new tab you'll see the ANSI_NULLS OFF near the top.
You can edit it there and set it ON or OFF and update it to change ...