patternsqlMinor
Handling optional parameters in stored procedure
Viewed 0 times
storedhandlingprocedureoptionalparameters
Problem
I have a stored procedure, say "Test" with an optional parameter @Param1 int = NULL. In the procedure, the value of @Param1 is used to update the value of some column in some table, if the caller provided a value. If the parameter is not provided, the column is not updated. Unfortunately, that column allows NULLs, so that the caller isn't able to set the column value to NULL. So, the question is: Is the procedure able to distinguish between the following two calls?
Of course, the procedure can check if
EXEC Test -- intended meaning: don't update the columnEXEC Test @Param1 = NULL -- intended meaning: set the column to NULLOf course, the procedure can check if
@Param1 IS NULL. But can it determine if the parameter has been provided at all?Solution
Maybe something like this might work:-
Test:-
Results (on 15.0.4102.2):-
@@SPID and
CREATE PROC dbo.Test @Param1 INT = NULL
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS
(
SELECT 1
FROM sys.dm_exec_requests AS ER
CROSS APPLY sys.dm_exec_input_buffer(ER.session_id, ER.request_id) AS IB
WHERE ER.session_id = @@SPID
AND IB.event_info LIKE '%@Param1%'
)
BEGIN
IF @Param1 IS NULL
BEGIN
RAISERROR('@Param1 was supplied as NULL', 0, 1) WITH NOWAIT;
END;
ELSE
BEGIN
RAISERROR('@Param1 was supplied as a non-NULL value', 0, 1) WITH NOWAIT;
END;
END;
ELSE
BEGIN
RAISERROR('@Param1 was not supplied and defaulted to NULL', 0, 1) WITH NOWAIT;
END;
END;
GOTest:-
EXEC dbo.Test @Param1 = NULL;
GO
EXEC dbo.Test @Param1 = 123;
GO
EXEC dbo.Test;
GOResults (on 15.0.4102.2):-
@Param1 was supplied as NULL
@Param1 was supplied as a non-NULL value
@Param1 was not supplied and defaulted to NULL
@@SPID and
CURRENT_REQUEST_ID can be used to provide the parameters to sys.dm_exec_input_buffer. No special permissions are needed to use that DMV for the current session. More rights are needed to view details for other sessions.Code Snippets
CREATE PROC dbo.Test @Param1 INT = NULL
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS
(
SELECT 1
FROM sys.dm_exec_requests AS ER
CROSS APPLY sys.dm_exec_input_buffer(ER.session_id, ER.request_id) AS IB
WHERE ER.session_id = @@SPID
AND IB.event_info LIKE '%@Param1%'
)
BEGIN
IF @Param1 IS NULL
BEGIN
RAISERROR('@Param1 was supplied as NULL', 0, 1) WITH NOWAIT;
END;
ELSE
BEGIN
RAISERROR('@Param1 was supplied as a non-NULL value', 0, 1) WITH NOWAIT;
END;
END;
ELSE
BEGIN
RAISERROR('@Param1 was not supplied and defaulted to NULL', 0, 1) WITH NOWAIT;
END;
END;
GOEXEC dbo.Test @Param1 = NULL;
GO
EXEC dbo.Test @Param1 = 123;
GO
EXEC dbo.Test;
GOContext
StackExchange Database Administrators Q#295650, answer score: 5
Revisions (0)
No revisions yet.