473,416 Members | 1,734 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

How to specify DEFAULT for optional parameter to stored procedure wrapper function

My problem is this (apologies if this is a little long ... hang in there):

I can define a function in VB.NET with optional parameters that wraps a SQL procedure:

Expand|Select|Wrap|Line Numbers
  1.  Sub Test(Optional ByVal Arg1 As Integer = 0, _
  2.            Optional ByVal Arg2 As Integer = 0, _
  3.            Optional ByVal Arg3 As Integer = 0)
  4.  
  5.     ' Call my SQL proc with the same signature
  6.  
  7.   End Sub
And I can test for a missing argument by testing for the default I set:

Expand|Select|Wrap|Line Numbers
  1.  If (Arg1 = 0) Then
  2.       ' Arg1 is missing so leave it off the call to the stored proc
  3.     Else
  4.       ' Arg1 is provided so add it to the call to the stored proc
  5.     End If
Great, so in principle I can leave off unspecified optional parameters when calling the stored procedure and let the stored procedure default those parameters based on whatever defaults are specified in the stored procedure.

But hang on, what if my choice of default for the optional parameter is a valid value to send to the stored procedure? What if Arg1 can be 0 and that is different to the default set on the stored procedure?

Maybe I could use "Nothing" as my default for the optional parameter, and test using IsNothing. This works for complex types like String and any Objects. But fails for simple types like Integer, as setting an Integer to Nothing actually sets it to the value 0 and a subsequent call to IsNothing returns False:

Expand|Select|Wrap|Line Numbers
  1. Dim i As Integer
  2.     i = Nothing
  3.     If (IsNothing(i)) Then
  4.       ' this arm is never executed
  5.     Else
  6.       ' this will print 0
  7.       Debug.Print(i)
  8.     End If
Okay, so it looks like I need to replicate all the default values I have on the stored procedure into the wrapper VB.NET function. This is unfortunate as it duplicates code and leaves space for the two to become out of sync.

I want to be able to write something like:

Expand|Select|Wrap|Line Numbers
  1. Sub Test(Optional ByVal Arg1 As Integer = Default, _
  2.            Optional ByVal Arg2 As Integer = Default, _
  3.            Optional ByVal Arg3 As Integer = Default)
  4.  
  5.     ' Call my SQL proc with the same signature
  6.  
  7.   End Sub
And test for this special "Default" value on any type and not pass the stored proc parameter if this is set.

I have tried defining Structures that attempt to extend the base types (a bit like
those is System.Data.SqlTypes) but then I hit the problem that Optional parameters cannot be Structures (only classes or simple types).

I have also considered using Overloads rather than Optional parameters, but this doesn't work either as it seems you cannot replicate the same functionality you have with Optional parameters with Overloads. Considering my original function:

Expand|Select|Wrap|Line Numbers
  1. Sub Test(Optional ByVal Arg1 As Integer = 0, _
  2.            Optional ByVal Arg2 As Integer = 0, _
  3.            Optional ByVal Arg3 As Integer = 0)
I could re-write this using overloads as:

Expand|Select|Wrap|Line Numbers
  1. Sub Test(ByVal Arg1 As Integer, _
  2.            ByVal Arg2 As Integer, _
  3.            ByVal Arg3 As Integer)
  4.   End Sub
  5.  
  6.   Sub Test(ByVal Arg1 As Integer, _
  7.            ByVal Arg2 As Integer)
  8.   End Sub
  9.  
  10.   Sub Test(ByVal Arg1 As Integer)
  11.   End Sub
But I cannot do:

Expand|Select|Wrap|Line Numbers
  1. Sub Test(ByVal Arg2 As Integer, _
  2.            ByVal Arg3 As Integer)
  3.   End Sub
As this has the same signature as one of the previous versions. So although I can happily do this using optional parameters:

Expand|Select|Wrap|Line Numbers
  1. Test(Arg2:=3,Arg3:=1)
I cannot seem to achieve the same with an overload.

Can anyone think up a way of setting an optional parameter to some value I can detect as missing that is distinct from any default I may have set in the stored procedure that function wraps?

Thanks
Sep 18 '09 #1
7 7029
Plater
7,872 Expert 4TB
Well, I don't know is VB supports it, but in C# I can do this:
Expand|Select|Wrap|Line Numbers
  1. int? i = null;
  2. if (i == null)
  3. {//this code fires
  4.    int b = 4;
  5. }
  6.  
Adding a ? to the end of a value type allows it to be nullable. Maybe look to see if there is a VB equivilent to nullable value types?
Sep 18 '09 #2
tlhintoq
3,525 Expert 2GB
If all your real world data is positive numbers then you could use a default of -1 to be your "null"

Microsoft does it all the time. Look at a listbox. The items in the listbox are indexed zero and up. If the selected index is -1 then nothing is selected.
Sep 18 '09 #3
tlhintoq
3,525 Expert 2GB
TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out.
Sep 18 '09 #4
Thanks for the suggestions,

I had considered the "special values" solution, but it feels like a kludge. You never know, one day date.MinValue might be a valid parameter value!

After much casting about I found a sort of solution (not as elegant as I had hoped but does the job) using generics.

I define a generic type that can accept Nothing even for simple intrinsic types (like integer) and then I can test IsNothing on all the inputs to see if they were specified. One nifty thing here is the Widening / Narrowing functions that allow the type to accept integers, strings, dates, etc. without an explicit Newing or type converting.

However I am not 100% happy with this solution, as to my mind "Nothing" means de-reference me. I wanted to use a constant like "DefaultValue", but I could not get the compiler to accept it no matter what I tried. So I ended up taking MS at face value:

http://msdn.microsoft.com/en-us/libr...7z(VS.80).aspx

... "Nothing - Represents the default value of any data type."

For those interested my code is:
Expand|Select|Wrap|Line Numbers
  1. '------------------------------------------------------------------------------
  2. ' Defaultable(Of dataType) Generic Class
  3. '
  4. ' Author: JC
  5. ' Created date: 21 Sep 2009
  6. ' Description: Generic class which enables simple intrinsic types to
  7. '  accept the Nothing so that IsNothing returns true
  8. '  Providing a means to detect default values for optional parameters
  9. '  Also enables all types to accept System.DB.Null values
  10. '------------------------------------------------------------------------------
  11. Public Class Defaultable(Of dataType)
  12.   Implements IComparable(Of dataType), _
  13.              System.Data.SqlTypes.INullable
  14.  
  15.   '----------------------------------------------------------------------------
  16.   ' Member variables
  17.   '----------------------------------------------------------------------------
  18.   Private _Value As dataType
  19.   Private _bIsNull As Boolean
  20.  
  21.   '----------------------------------------------------------------------------
  22.   ' New (Generic Overloaded)
  23.   '----------------------------------------------------------------------------
  24.   Public Sub New(ByVal newvalue As dataType)
  25.     _Value = newvalue
  26.   End Sub
  27.  
  28.   '----------------------------------------------------------------------------
  29.   ' New (System.DBNull Overloaded)
  30.   '----------------------------------------------------------------------------
  31.   Public Sub New(ByVal newvalue As System.DBNull)
  32.     _bIsNull = True
  33.     _Value = Nothing
  34.   End Sub
  35.  
  36.   '----------------------------------------------------------------------------
  37.   ' Value 
  38.   '----------------------------------------------------------------------------
  39.   Public Property Value() As dataType
  40.     Get
  41.       Return _Value
  42.     End Get
  43.     Set(ByVal newvalue As dataType)
  44.       _Value = newvalue
  45.     End Set
  46.   End Property
  47.  
  48.   '----------------------------------------------------------------------------
  49.   ' Widening CType (Overloaded)
  50.   '----------------------------------------------------------------------------
  51.   Public Shared Widening Operator CType(ByVal d As dataType) As Defaultable(Of dataType)
  52.     Return New Defaultable(Of dataType)(d)
  53.   End Operator
  54.  
  55.   '----------------------------------------------------------------------------
  56.   ' Widening CType (Overloaded)
  57.   '----------------------------------------------------------------------------
  58.   Public Shared Widening Operator CType(ByVal d As System.DBNull) As Defaultable(Of dataType)
  59.     Return New Defaultable(Of dataType)(d)
  60.   End Operator
  61.  
  62.   '----------------------------------------------------------------------------
  63.   ' Narrowing CType
  64.   '----------------------------------------------------------------------------
  65.   Public Shared Narrowing Operator CType(ByVal d As Defaultable(Of dataType)) As dataType
  66.     Return d.Value
  67.   End Operator
  68.  
  69.   '----------------------------------------------------------------------------
  70.   ' CompareTo
  71.   '----------------------------------------------------------------------------
  72.   Public Function CompareTo(ByVal other As dataType) As Integer Implements System.IComparable(Of dataType).CompareTo
  73.     If (TypeOf _Value Is IComparable(Of dataType)) Then
  74.       Return CType(_Value, IComparable(Of dataType)).CompareTo(other)
  75.     Else
  76.       Return _Value.GetType.ToString.CompareTo(other.GetType.ToString)
  77.     End If
  78.   End Function
  79.  
  80.   '----------------------------------------------------------------------------
  81.   ' IsNull
  82.   '----------------------------------------------------------------------------
  83.   Public ReadOnly Property IsNull() As Boolean Implements System.Data.SqlTypes.INullable.IsNull
  84.     Get
  85.       Return _bIsNull
  86.     End Get
  87.   End Property
  88.  
  89. End Class
I can now do this with my test function:
Expand|Select|Wrap|Line Numbers
  1.   Private Sub Test(Optional ByRef int1 As Defaultable(Of Integer) = Nothing, _
  2.                    Optional ByRef int2 As Defaultable(Of Integer) = Nothing, _
  3.                    Optional ByRef int3 As Defaultable(Of Integer) = Nothing)
  4.  
  5.     Dim strCmd As String = "exec mystoredproc "
  6.  
  7.     If (Not IsNothing(int1)) Then
  8.       strCmd &= "@int1=" & int1.Value.ToString & ", "
  9.     End If
  10.  
  11.     If (Not IsNothing(int2)) Then
  12.       strCmd &= "@int2=" & int2.Value.ToString & ", "
  13.     End If
  14.  
  15.     If (Not IsNothing(int3)) Then
  16.       strCmd &= "@int3=" & int3.Value.ToString & ", "
  17.     End If
  18.  
  19.     Debug.Print(strCmd)
  20.  
  21.   End Sub
Still I'd quite like to define my own Keyword "Default" that works like Nothing (i.e. causes no type conversion errors) but is detectable distinct from Nothing as I think MS have rather overloaded the meaning of Nothing here.
Sep 21 '09 #5
Plater
7,872 Expert 4TB
Wow VB makes it a long way to get the same as the ? nullable datatypes in C#
Sep 21 '09 #6
It is actually easy to define a Nullable type in VB just do:

Dim aVariable As Nullable(Of Integer)

And there you go, aVariable can now be set to Nothing (null) quite happily.

Problem: Nullable(Of T) is a Structure not a Class so you can't use it for optional parameters (not that those exist in c# anyway) and you can't test IsNothing on it you have to do .HasValue instead.

I need a type that can be used as an optional parameter hence the solution above.
Sep 22 '09 #7
Plater
7,872 Expert 4TB
Optional parameters exist in C#, using the params object[] notation I believe.
Although, I've not found a use for optional parameters in my own work yet.
Sep 22 '09 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Jason | last post by:
I have a function which performs a query and returns a table. The one parameter that can get passed in is a date which defaults to NULL. There is an IF statement in the function that will set the...
3
by: Mariusz | last post by:
I want to write function to call another function which name is parameter to first function. Other parameters should be passed to called function. If I call it function('f1',10) it should call...
1
by: ganesh wayachal via SQLMonster.com | last post by:
In which system table the information about the optional parameters passed to stored procedure are stored. I know about the tbl_columns and all that stuff. From where can i can come to know the...
2
by: The Plankmeister | last post by:
Hi... I have a query which I'm accessing through PHP as a stored procedure. However, I need to be able not to pass a couple of parameters in certain situations. When I do this, I get an error: ...
3
by: Marco Segurini | last post by:
Hi, Actually I am calling from VB some functions imported from a c++ dll. Some of these functions require as parameter a pointer. Example: extern "C" int DllCall(int * pvInt, int iLen); ...
5
by: Enyi | last post by:
Just like my last post I cannot solve this problem with a stored procedure in MSSQL Server 2000 Developer Edition. I am trying to use the parameter in VB.NET 2003. When I run the VB code and...
2
by: bh | last post by:
Is there such thing as a default exception value? I'm trying to pass an optional parameter, containing an exception back to a calling procedure. In the pseudocode, below, what might I put in...
9
by: serge | last post by:
/* Subject: How to build a procedure that returns different numbers of columns as a result based on a parameter. You can copy/paste this whole post in SQL Query Analyzer or Management Studio...
4
by: | last post by:
I there a way to provide a default value for a parameter in a method? E.g. private void somemethod(string whatever, string whatever2 = "someval")
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.