Stored procedure to update multiple tables - sql

I have a stored procedure that updates two tables. The first table is always the same table, but the second table changes depending on a parameter that is passed in. Is it more efficient to write it all into one big procudure, as such
CREATE PROCEDURE MyBigProc
#id int
#param int,
#value1 int,
#value2 int
AS
BEGIN
SET NOCOUNT ON;
-- First table to update
UPDATE MyTable SET field1 = #value1 WHERE id = #id
-- Then choose which table to update based on #param
IF #param = 1
UPDATE MySecondTable SET field2 = #value2 WHERE id = #id
IF #param = 2
UPDATE MyThirdTable SET field2 = #value2 WHERE id = #id
END
Or should I write a separate procedure for each table and then call EXEC the procedure from the main procedure.
I suppose the latter is more flexible, say if I wanted to update a subtable but no the main table?

I suppose the latter is more flexible, say if I wanted to update a
subtable but no the main table?
Exactly, you have a good reason to split the work on 2 separate procs. If it makes sense for you for everything else, I don't see why not follow that approach.
One possible reason not to do it, would be if you need both updates to succeed or fail at the same time. Under a scenario like this, I would leave everything in one proc and enclose everything in one transaction.

CREATE PROCEDURE MyBigProc
#id int,
#param int,
#value1 int,
#value2 int
AS
BEGIN
SET NOCOUNT ON;
-- First table to update
UPDATE MyTable SET field1 = #value1 WHERE id = #id;
-- Then choose which table to update based on #param
IF #param = 1
exec SP_MySecondTable #id,#value2;
IF #param = 2
exec SP_MyThirdTable #id,#value2;
END
CREATE PROCEDURE SP_MySecondTable
#id int,
#value2 int
AS
BEGIN
UPDATE MySecondTable SET field2 = #value2 WHERE id = #id;
END
CREATE PROCEDURE SP_MyThirdTable
#id int,
#value2 int
AS
BEGIN
UPDATE MyThirdTable SET field2 = #value2 WHERE id = #id;
END

Its better to have different stored procedures and then call them all at a single place. It'll help you a lot while performing maintenance activities.

Best option is to use a CASE statement to update your tables

Related

Dynamic update of string values in tables using Stored procedure

The following is my stored procedure to update a column in SQL SERVER
ALTER PROCEDURE [dbo].[AspPageUpdate]
(#type varchar(50),#comp varchar(50),
#place varchar(50))
AS
BEGIN
SET NOCOUNT ON;
DECLARE #tid varchar;
DECLARE #ph int;
SET #ph = CAST(#place AS int);
select #tid = Type_Id
from TypeTable
where Type_Name = #type
UPDATE TypeSetupTable
SET PLACE_HOLDERS = #ph
WHERE complexity = #comp
AND Type_Id = #tid
END
But the table is not getting updated. I think the problem is with Quotes(Strings need to be in quotes, right?).
If i'm giving static values, it is execting, like:
UPDATE TypeSetupTable SET PLACE_HOLDERS = #ph WHERE complexity = 'Simple' AND Type_Id = 'SSRS'
Please tell me a solution.
Thanks in Advance.
you didn't set the size of the variable #tid.
Are you sure of the content of that variable while executing the stored procedure?
Try to put a raiserror(#tid,15,1) and check the content of that variable.
There are blogs about the habit not to size varchar variables.
It is also officially documented that the size of unsized varchars is 1.

insert the null record in the print lable

I am trying to create a SP which print the label of my vendor, vendor name. I want the user set the startposition, before the startposition I just simply insert a null value. I want be able to reuse the label sheet.
I have the SP code like this:
Alter PROCEDURE [dbo].[z_sp_APVendorLabel]
(#VendorGroup bGroup ,
#StartPosition int)
AS
BEGIN
SET NOCOUNT ON;
Create table #data_null
(Vendor int,
Name varchar(60)null)
Declare #counter int
SET #counter = 0
WHILE #counter < #StartPosition
BEGIN
UPDATE #data_null SET Vendor='',Name=' '
SET #counter = #counter + 1
END
Create table #detial
(Vendor int,
Name varchar (60)null)
select Vendor, Name into #data from APVM
WHERE VendorGroup= #VendorGroup
select * from #data_null
Union All
select * from #detial
END
It is very simple, but when I test it, I did not get any data.
You're creating the table #data_null, and updating it, but never inserting any rows. If you inspect ##rowcount after each update, you'll see it's zero.
Before you change that loop to insert instead of update, please consider setting up a permanent table to select from. A loop to generate N values on every invocation of the procedure is really not the best use of your server's time, or yours. ;-)

Store the result of a stored procedure without using an output parameter

I have 2 stored procedures: up_proc1 and up_proc2.
This is (a simplified version of) up_proc2:
CREATE PROCEDURE dbo.up_proc2
#id_campaign uniqueidentifier, #id_subcampaign uniqueidentifier,
#id_lead uniqueidentifier, #offer NVARCHAR(1000) = NULL
AS
SET NOCOUNT ON
DECLARE #id UNIQUEIDENTIFIER
SELECT #id = id FROM prospects WHERE id_lead = #id_lead
AND id_campaign = #id_campaign AND id_subcampaign = #id_subcampaign
IF #id IS NULL
BEGIN
SET #id = newid ()
INSERT INTO prospects (id, id_campaign, id_subcampaign, id_lead, offer)
values (#id, #id_campaign, #id_subcampaign, #id_lead, #offer)
END
ELSE
BEGIN
UPDATE prospects set offer = #offer WHERE id=#id
END
SELECT #id AS ID
GO
From up_proc1 I call up_proc2. What I would like to achieve is to store the #id of up_proc2 in a variable declared in up_proc1. Is this possible without using an output parameter?
This is how up_proc1 looks like:
CREATE PROCEDURE dbo.up_proc1
AS
SET NOCOUNT ON
DECLARE #fromProc2 UNIQUEIDENTIFIER
-- NOT WORKING
-- select #fromProc2 = exec up_insertProspects [snip]
-- ALSO NOT WORKING
-- exec #fromProc2 = up_insertProspects [snip]
What you could do is store the output into a table variable:
DECLARE #tmpTable TABLE (ID UNIQUEIDENTIFIER)
INSERT INTO #tmpTable
EXEC dbo.up_proc2 ..........
and then go from there and use that table variable later on.
You can certainly consume this as an output parameter in proc2 without affecting how your C# code retrieves the eventual resultset.
ALTER PROCEDURE dbo.up_proc2
#id_campaign uniqueidentifier,
#id_subcampaign uniqueidentifier,
#id_lead uniqueidentifier,
#offer NVARCHAR(1000) = NULL,
#fromProc2 UNIQUEIDENTIFER = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
...
C# can ignore the new parameter since it is nullable (but since a single output parameter is more efficient than a data reader, you may consider updating your C# code to take advantage of the output parameter later).
Now in proc1:
ALTER PROCEDURE dbo.up_proc1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #fromProc2 UNIQUEIDENTIFIER;
EXEC dbo.up_proc2
--... other parameters ...,
#fromProc2 = #fromProc2 OUTPUT;
-- now you can use #fromProc2
END
GO

how to handle optional parameters in a update stored procedure

I need to write a generic procedure that set value for one column or no of a columns in a table depending on parameters. Any idea how to do it.
I would guess you want something like:
CREATE PROC UpdateProc
#RowID UNIQUEIDENTIFIER,
#Parameter1 NVARCHAR(50) NULL,
#Parameter2 INT NULL
AS
SET NOCOUNT ON
GO
IF #Parameter1 IS NOT NULL
BEGIN
UPDATE MyTable
SET Column1 = #Parameter1
WHERE ID = #RowID
END
IF #Parameter2 IS NOT NULL
BEGIN
UPDATE MyTable
SET Column2 = #Parameter2
WHERE ID = #RowID
END
It doesn't feel particularly elegant but if you don't know/can't guarantee which parameters will be passed I don't know of a better way than to test them in turn for NULL.

SQL Server Stored Procedure store return value

Helo,
My question is I have one Stored Procedure in SQL Server that returns counts of a field. I want to store the results of this Stored Procedure in a variable (scalar?) of a different stored procedure.
sp_My_Other_SP:
CREATE PROCEDURE [dbo].sp_My_Other_SP
#variable int OUTPUT -- The returned count
AS
BEGIN -- SP
SET NOCOUNT ON;
SET #SQL = "SELECT COUNT(*) FROM blah"
EXEC(#SQL)
END -- SP
I currently do it like:
DECLARE #count int
EXEC sp_My_Other_SP #count OUTPUT
Then I use it like
IF (#count > 0)
BEGIN
...
END
However its returning the other Stored Procedure results as well as the main Stored Procedure results which is a problem in my .NET application.
-----------
NoColName
-----------
14
-----------
MyCol
-----------
abc
cde
efg
(Above is an attempted representation of the results sets returned)
I would like to know if there is a way to store the results of a Stored Procedure into a variable that doesn't also output it.
Thanks for any help.
You can capture the results of the stored procedure into a temp table so it is not returned by the calling stored procedure.
create table #temp (id int, val varchar(100))
insert into #temp
exec sp_My_Other_SP #value, #value, #value, #count OUTPUT
Well, the easiest way to fix this is to recode the stored proc so that the select statement that returns the 'other' result set you don't want in this case is conditionally extecuted, only when you are NOT asking for the count
Add another parameter called #GetCount
#GetCount TinyInt Defualt = 0 // or
#GetCount Bit Default = 0
Then
instead of just
Select ...
write
If #GetCount = 1
Select ...
Have you tried changing
SET #SQL = "SELECT COUNT(*) FROM blah"
EXEC(#SQL)
to
SELECT #variable = COUNT(*) FROM blah"
-- don't do EXEC(#SQL)
?
THE FIRST PROCEDURE:
CREATE PROC DD43
#ID INT OUTPUT AS
(SELECT #ID=COUNT(*) FROM CS2)
SECOND PROCEDURE:
CREATE PROC DD45 AS
DECLARE #COUNT INT
DECLARE #COUN INT
EXEC DD43 #COUN OUT --CALLING THE FIRST PROCEDURE
SET #COUNT= (SELECT #COUN)
SELECT #COUNT
EXEC DD45