Advertisement
scottashipp

Stored Procedures with optional parameters

Mar 29th, 2013
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 4.33 KB | None | 0 0
  1. /* create the example table */
  2. CREATE TABLE customer(
  3.     id  int not null,
  4.     first   nvarchar(200),
  5.     last    nvarchar(200),
  6.     city    nvarchar(200),
  7.     state   nvarchar(40),
  8.     zip     nvarchar(10),
  9.     country nvarchar(100)
  10.     PRIMARY KEY(id),
  11.     UNIQUE(id)
  12. )
  13.  
  14. /* populate some test data */
  15. insert into customer values(1, 'Joe', 'Public', 'Seattle', 'WA', '98144', 'USA')
  16. insert into customer values(2, 'Jane', 'Public', 'Amsterdam', 'BT', '1063', 'NLD')
  17. insert into customer values(3, 'Jennifer', 'Public', 'Miami', 'FL', '33101', NULL)
  18.  
  19. /* create the stored procedure (the wrong way) */
  20. CREATE PROC retrieve_customers_by_location(
  21.                 @city   NVARCHAR(100),
  22.                 @state NVARCHAR(2),
  23.                 @zip NVARCHAR(9),
  24.                 @country NVARCHAR(10)
  25.         )
  26.         As
  27.        
  28.         Begin
  29.  
  30.         select * from customer where city=@city and state=@state and zip=@zip and country = @country
  31.  
  32.         End
  33.  
  34. /* Confirm that this doesn't work as expected by passing in only one or two parameters (these all return nothing) */
  35. exec retrieve_customers_by_location null,null,null,null
  36. exec retrieve_customers_by_location null,null,null,'USA'
  37. exec retrieve_customers_by_location null,'BT',null,null
  38. exec retrieve_customers_by_location 'Seattle','WA',null,null
  39.  
  40. /* so what will return a result? only those with all parameters supplied, which isn't very useful */
  41. exec retrieve_customers_by_location 'Seattle','WA','98144','USA'
  42.  
  43. /* alter the stored procedure according to another blog, this improves it a lot but it has a huge gotcha! */
  44. ALTER PROC retrieve_customers_by_location(
  45.                 @city   NVARCHAR(100),
  46.                 @state NVARCHAR(2),
  47.                 @zip NVARCHAR(9),
  48.                 @country NVARCHAR(10)
  49.         )
  50.         As
  51.        
  52.         Begin
  53.  
  54.         select * from customer where city = ISNULL(@city,city) and state = ISNULL(@state,state) and zip=ISNULL(@zip,zip) and country=ISNULL(@country,country)
  55.  
  56.         End
  57.  
  58. /* The gotcha is that this will always exclude any rows in the database with a null value in any of the columns.
  59.     Notice that Jennifer Public is never returned, even though she should match the first query and the last.
  60.  */
  61. exec retrieve_customers_by_location null,null,null,null
  62. exec retrieve_customers_by_location null,null,null,'USA'
  63. exec retrieve_customers_by_location null,'BT',null,null
  64. exec retrieve_customers_by_location 'Seattle','WA',null,null
  65. exec retrieve_customers_by_location null,null,'33101',null
  66.  
  67.  
  68. /* now alter the stored procedure...this finally works */
  69. ALTER PROC retrieve_customers_by_location(
  70.                 @city   NVARCHAR(100),
  71.                 @state NVARCHAR(2),
  72.                 @zip NVARCHAR(9),
  73.                 @country NVARCHAR(10)
  74.         )
  75.         As
  76.        
  77.         Begin
  78.  
  79.         select * from customer
  80.                 where
  81.                 (city = @city or @city is null) and
  82.                 (state= @state or @state is null) and
  83.                 (zip = @zip or @zip is null) and
  84.                 (country = @country or @country is null)
  85.  
  86.         End
  87.  
  88.  
  89. /* Retry those queries from above, and voila, works as expected */
  90. exec retrieve_customers_by_location null,null,null,null
  91. exec retrieve_customers_by_location null,null,null,'USA'
  92. exec retrieve_customers_by_location null,'BT',null,null
  93. exec retrieve_customers_by_location 'Seattle','WA',null,null
  94.  
  95. /* now try this */
  96. exec retrieve_customers_by_location
  97.  
  98. /* It returns something like "...expects parameter...which was not supplied." right? */
  99.  
  100. /* So make the stored procedure even better, by making the parameters optional (or in other words supply default parameters),
  101. no more need to pass in null when the value is not supplied */
  102. ALTER PROC retrieve_customers_by_location(
  103.                 @city   NVARCHAR(100) = null,
  104.                 @state NVARCHAR(2) = null,
  105.                 @zip NVARCHAR(9) = null,
  106.                 @country NVARCHAR(10) = null
  107.         )
  108.         As
  109.        
  110.         Begin
  111.  
  112.         select * from customer
  113.                 where
  114.                 (city = @city or @city is null) and
  115.                 (state= @state or @state is null) and
  116.                 (zip = @zip or @zip is null) and
  117.                 (country = @country or @country is null)
  118.  
  119.         End
  120.  
  121.  
  122. /* now you can issue this query, and it will return all results */
  123. exec retrieve_customers_by_location
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement