If you use business entities, mark every properties by custom attribute with (mask = 1, 2, 4, 8..., required = true/false).
class Product
{
[FieldAttribute(Required=true, Mask= 0)]
public int Id {get; set;}
...
[FieldAttribute(Required=false, Mask=1)]
public string ProductName { get; set;}
}
then you can use reflection to read all required properties and pass them to sp. if some not required parameters is null (use Nullable<>) don't increment mask (mask &= propertyMask).
Use integer mask to partial update.
/*
exec dbo.Update_Product @product_id = 1, @quantity = 3, @mask = 0x0004
exec dbo.Update_Product @product_id = 1, @product_name = 'new name', @comment = 'new comment', @mask = 0x0003
*/
alter proc dbo.Update_Product
@product_id int
,@product_name nvarchar(100) = NULL -- 0x0001
,@comment nvarchar(255) = NULL -- 0x0002
,@quantity int = NULL -- 0x0004
,@mask int
AS
update dbo.Product
SET
ProductName = CASE WHEN (@mask & 0x0001) > 0 THEN @product_name ELSE ProductName END
,Comment = CASE WHEN (@mask & 0x0002) > 0 THEN @comment ELSE Comment END
,Quantity = CASE WHEN (@mask & 0x0004) > 0 THEN @quantity ELSE Quantity END
WHERE id = @product_id
2) For select, use two masks (select, and where)
/*
exec dbo.Select_Product @select_mask = 0x0001, @where_mask = 0
exec dbo.Select_Product @select_mask = 0x0003, @where_mask = 0
exec dbo.Select_Product @select_mask = 0x0003, @where_mask = 0x0004, @quantity = 2
*/
alter proc dbo.Select_Product
@select_mask int
,@where_mask int
,@product_name nvarchar(100) = NULL -- 0x0001
,@comment nvarchar(255) = NULL -- 0x0002
,@quantity int = NULL -- 0x0004
as
DECLARE @select varchar(max)
DECLARE @where varchar(max)
SET @select = 'select Id '
IF (@select_mask & 0x0001) > 0
SET @select = @select + ',ProductName'
IF (@select_mask & 0x0002) > 0
SET @select = @select + ',Comment'
IF (@select_mask & 0x0004) > 0
SET @select = @select + ',Quantity'
SET @select = @select + ' from dbo.Product'
IF @where_mask > 0
SET @where = ' where ' + CASE WHEN (@where_mask & 0x0001) > 0 THEN 'ProductName = ''' + @product_name + '''' ELSE '' END
+ CASE WHEN (@where_mask & 0x0002) > 0 THEN 'Comment = ''' + @comment + '''' ELSE '' END
+ CASE WHEN (@where_mask & 0x0004) > 0 THEN 'Quantity = ' + CONVERT(varchar(10), @quantity) ELSE '' END
PRINT @select + @where
exec (@select + @where)