how to handle optional parameters in a update stored procedure - sql-server-2005

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.

Related

Accepting NULLS into Stored Procedures

I've got the below stored procedure that is very simple, but it allows NULL values to be passed in.
I'm just wondering what best practice is here, and how to deal with NULLs in cases such as this?
ALTER PROCEDURE [dbo].[spGetClient]
#ClientID int
AS
BEGIN
SET NOCOUNT ON;
SELECT
......
FROM
Client
WHERE
ClientID = #ClientID
You can raise a custom error:
ALTER PROCEDURE [dbo].[spGetClient]
#ClientID int
AS
BEGIN
SET NOCOUNT ON;
if #ClientID is null
BEGIN
raiserror('The value for ClientID should not be null', 15, 1)
return;
END
SELECT
......
FROM
Client
WHERE
ClientID = #ClientID
END
The simplest thing would be to just declare the argument as NOT NULL:
ALTER PROCEDURE [dbo].[spGetClient] (
#ClientID int NOT NULL
)
. . .
However, that is not quite allowed for all stored procedures.
Your stored procedure is fine. If a NULL value is passed in, then it will return no rows. This seems reasonable, because ClientId is probably never NULL in the Client table, so I don't see a problem.

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.

Stored procedure to update multiple tables

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

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

Stored Procedure NULL Parameter

I have a database table I am trying to do an UPDATE/INSERT to with a stored procedure. Let's define the table like so:
CREATE TABLE Foo
(
Id INT IDENTITY(1, 1),
Name VARCHAR(256) NOT NULL,
ShortName VARCHAR(32),
Sort INT
);
I have written a stored procedure similar to the following:
CREATE PROCEDURE Put_Foo
(
#Id INT = NULL OUTPUT,
#Name VARCHAR(256),
#ShortName VARCHAR(32) = NULL,
#Sort INT = NULL
)
AS
BEGIN
SET NOCOUNT ON;
SELECT
#Id = F.Id
FROM
Foo AS F
WHERE
F.Name = #Name;
IF (#Id IS NOT NULL)
BEGIN
UPDATE
Foo
SET
ShortName = #ShortName,
Sort = #Sort
WHERE
Id = #Id;
END
ELSE
BEGIN
INSERT
INTO Foo
(
Name,
ShortName,
Sort
)
VALUES
(
#Name,
#ShortName
#Sort
);
SET #Id = SCOPE_IDENTITY();
END
RETURN;
END;
I've greatly simplified the data structures I am dealing with but I hope this serves my point. My question is in regards to how the parameters are processed. Is there a way to determine within the procedure if #Sort was passed in as NULL or set NULL by the default declaration in the parameter list?
EDIT:
The purpose of this is that I don't want NULL parameters to override any columns in the UPDATE statement unless they are explicitly passed in that way.
No, you can't detect how #Sort became NULL. If your goal is to capture when it is explicitly set versus it being set by the default, I would suggest using a different default value (maybe one that wouldn't normally be used, like -1). Then you can assume that if #Sort is NULL, it was explicitly passed in, but if it is -1, you know it was set by default.
I think this is what your looking for. If one of the parameters is null, it will updatedit with the value in the database. The other option is update one column at a time.
UPDATE Foo
SET
ShortName = ISNULL(#ShortName, ShortName)
, Sort = ISNULL(#Sort, Sort)
WHERE Id = #Id;
Take out the default value and and then the code calling the proc must provide a value (either a real value or NULL)