I am working on a project that accepts 3 different parameters, the date is required and the First and Last name are optional. We setup the query below, but even if I change the parameters on the report (SSRS) it still looks at #LetterCreated as being '1/1/1950', any ideas on how I can get this to just accept the parameters? We set the date this way because we want the report to show with all of the reports when it is initially opened.
Alter Proc
AS
BEGIN
SET NOCOUNT ON;
DECLARE #LetterCreated DATETIME,
#FirstName VARCHAR(20),
#LastName VARCHAR(20)
SELECT #LetterCreated = '1/1/1950'
SELECT #FirstName = ''
SELECT #LastName = ''
SELECT
LETTERCREATETIME,
Firstname,
LastName,
From RedFlagAddress
WHERE
CASE WHEN #LetterCreated='1/1/1950'
THEN '1/1/1950'
ELSE ISNULL(LETTERCREATETIME, '07/05/81')
END = #LetterCreated
AND (LastName LIKE #LASTNAME + '%' AND FirstName LIKE #FirstNAME + '%')
END
Any suggestions would be greatly appreciated.
You are setting the #lettercreated date in the procedure. Variables defined within the procedure are not visible outside it.
You should declare the parameters as parameters, and set the default in the declaration
ALTER PROC yourproc
(
#LetterCreated DATETIME = '1950-1-1',
#FirstName VARCHAR(20) = '',
#LastName VARCHAR(20) = ''
)
as
begin
select
LETTERCREATETIME,
Firstname,
LastName,
From
RedFlagAddress
where
(
ISNULL(LETTERCREATETIME, '07/05/81') = #LetterCreated
or
#LetterCreated = '1950-1-1'
)
AND LastName LIKE #LASTNAME + '%'
AND FirstName LIKE #FirstNAME + '%'
end
I'm guessing here but what you may want is
IF parameter #LetterCreated is null then it should not be used as a filter at all
IF the data in RedFlagData.LETTERCREATETIME is Null then it should be matched to a filter date of '07/05/81' FWR
Assuming that you have the 'allow nulls' check on the RDL/RDLC set for the #LetterCreated parameter, the where needs to be changed, the optional filter can be set like so:
ISNULL(#LetterCreated, LETTERCREATETIME) = ISNULL(LETTERCREATETIME, '07/05/81')
If you get rid of the magic date, then you can guarantee no date filter applied even if LETTERCREATETIME is null, by the filter:
ISNULL(#LetterCreated, LETTERCREATETIME) = ISNULL(LETTERCREATETIME)
OR
(#LetterCreated IS NULL AND LETTERCREATETIME IS NULL)
Thus:
ALTER PROC XYZ
(
#LetterCreated DATETIME,
#FirstName VARCHAR(20) = NULL,
#LastName VARCHAR(20) = NULL
)
as
begin
select
LETTERCREATETIME,
Firstname,
LastName,
From
RedFlagAddress
where
(
ISNULL(#LetterCreated, LETTERCREATETIME) = LETTERCREATETIME
OR
(#LetterCreated IS NULL AND LETTERCREATETIME IS NULL)
)
AND LastName LIKE ISNULL(#LastName, '') + '%'
AND FirstName LIKE ISNULL(#FirstName, '') + '%'
end
One caveat : The performance of this query will be terrible, given the amount of functional manipulation in the where clause, and the LIKEs and ORs - Hopefully RedFlagAddress is a relatively small table? If not, you may need to rethink your approach
Similar to podiluska's answer, you should set the parameters as part of the SP, as podiluska indicates, but then you should set the default values in SSRS, in the Parameters there.
This will let the users see the defaults and use those for subscriptions, or override them as needed.
Alter Proc Proc_Name
(
#LetterCreated DATETIME,
#FirstName VARCHAR(20) = null,
#LastName VARCHAR(20) = null
)
AS
BEGIN
SET NOCOUNT ON;
This will pass null values as Default values to you Proc now you code should be able to handle null values if no values are provided for FirstName and LastName
Related
If i need to just update one column do i have to give other column previous value or i can just give give the column i need to change and not null values to update in database .. here is procedure code what can i do to this procedure so that i can just need to insert the value i want to update ...
ALTER procedure [dbo].[Customer_update]
( #Id int,
#Firstname nvarchar(40)=,
#Lastname nvarchar(40)=,
#City nvarchar(40)=null,
#Country nvarchar(40)=null,
#Phone nvarchar(20)=null
)
as
begin
update Customer set FirstName=#Firstname,LastName=#Lastname,City=#City,Country=#Country,Phone=#Phone where Id=#Id
end
You almost have it and as Alex K pointed out in the comment above, the most elegant way to handle optional updates is to allow null parameters and update what is sent over.
ALTER PROCEDURE [dbo].[Customer_update]
(#Id INT,
#Firstname NVARCHAR(40) = NULL,
#Lastname NVARCHAR(40) = NULL,
#City NVARCHAR(40) = NULL,
#Country NVARCHAR(40) = NULL,
#Phone NVARCHAR(20) = NULL)
AS
BEGIN
UPDATE Customer
SET FirstName = ISNULL(#Firstname, FirstName)...
WHERE Id = #Id
END
In order to use this in client code with nullable fields, simply omit the parameter altogether or let nulls pass through (one caveat to this is when you really need to set the field to null in which case the field should probably not be nullable. Then you can implicitly send a null over and the field will be set to the proper value)
Nullable fields allow you to omit parameters from a stored procedure call and still perform the operation. This is useful when you need make changes and do not want to impact existing applications, as long as the nullable fields are not required.
Are you asking about Insert/Update in one operation?
Some people do "upserts". I personally do not like having one operation for insert/updates. I feel the client should already know what operation should be performed, also, having one update and one insert procedure makes the procedures more transparent and easier to auto generate.
However, if that is what you were asking then you would create a procedure similar to the one below:
ALTER PROCEDURE [dbo].[Customer_update]
(#Id INT = NULL,
#Firstname NVARCHAR(40) = NULL,
#Lastname NVARCHAR(40) = NULL
#City NVARCHAR(40) = NULL
#Country NVARCHAR(40) = NULL
#Phone NVARCHAR(20) = NULL)
AS
BEGIN
IF (#Id IS NULL)
BEGIN
INSERT INTO Customer...
SET #ID = ##SCOPE_IDENTITY
END
ELSE BEGIN
UPDATE Customer
SET FirtName = ISNULL(#FirstName, FirstName)
WHERE Id = #Id
END
SELECT *
FROM Customer
WHERE Id = #Id
END
You would need to use ISNULL on each column:
ALTER procedure [dbo].[Customer_update]
( #Id int,
#Firstname nvarchar(40)=,
#Lastname nvarchar(40)=,
#City nvarchar(40)=null,
#Country nvarchar(40)=null,
#Phone nvarchar(20)=null
)
as
begin
update Customer
set FirstName=ISNULL(#Firstname,FirstName),
LastName=ISNULL(#Lastname,LastName),
City=ISNULL(#City,City),
Country=ISNULL(#Country,Country),
Phone=ISNULL(#Phone,Phone)
where Id=#Id
end
I have the following user-defined function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName else case when #FirstName = '' then #LastName else (#LastName + ' ' + #FirstName) end end)
return #Result
end
I can't create an Index on a computed column using this function cause it's not deterministic.
Someone could explain why is it not deterministic and eventually how to modify to make it deterministic?
Thanks
You just need to create it with schemabinding.
SQL Server will then verify whether or not it meets the criteria to be considered as deterministic (which it does as it doesn't access any external tables or use non deterministic functions such as getdate()).
You can verify that it worked with
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[FullNameLastFirst]'), 'IsDeterministic')
Adding the schemabinding option to your original code works fine but a slightly simpler version would be.
CREATE FUNCTION [dbo].[FullNameLastFirst] (#IsPerson BIT,
#LastName NVARCHAR(100),
#FirstName NVARCHAR(100))
RETURNS NVARCHAR(201)
WITH SCHEMABINDING
AS
BEGIN
RETURN CASE
WHEN #IsPerson = 0
OR #FirstName = '' THEN #LastName
ELSE #LastName + ' ' + #FirstName
END
END
You need to declare the User Defined Function WITH SCHEMABINDING to appease the 'deterministic' requirement of an index on the computed column.
A function declared WITH SCHEMABINDING will retain additional knowledge about the object dependencies used in the function (e.g. columns in the table), and will prevent any changes to these columns, unless the function itself is dropped beforehand.
Deterministic functions can also assist Sql Server in optimizing its execution plans, most notably the Halloween Protection problem.
Here's an example of creating an index on a computed column using a schema bound function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
with schemabinding
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName
else case when #FirstName = '' then #LastName
else (#LastName + ' ' + #FirstName) end end)
return #Result
end
create table Person
(
isperson bit,
lastname nvarchar(100),
firstname nvarchar(100),
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname)
)
go
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')
go
create index ix1_person on person(fullname)
go
select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'
go
I have the following user-defined function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName else case when #FirstName = '' then #LastName else (#LastName + ' ' + #FirstName) end end)
return #Result
end
I can't create an Index on a computed column using this function cause it's not deterministic.
Someone could explain why is it not deterministic and eventually how to modify to make it deterministic?
Thanks
You just need to create it with schemabinding.
SQL Server will then verify whether or not it meets the criteria to be considered as deterministic (which it does as it doesn't access any external tables or use non deterministic functions such as getdate()).
You can verify that it worked with
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[FullNameLastFirst]'), 'IsDeterministic')
Adding the schemabinding option to your original code works fine but a slightly simpler version would be.
CREATE FUNCTION [dbo].[FullNameLastFirst] (#IsPerson BIT,
#LastName NVARCHAR(100),
#FirstName NVARCHAR(100))
RETURNS NVARCHAR(201)
WITH SCHEMABINDING
AS
BEGIN
RETURN CASE
WHEN #IsPerson = 0
OR #FirstName = '' THEN #LastName
ELSE #LastName + ' ' + #FirstName
END
END
You need to declare the User Defined Function WITH SCHEMABINDING to appease the 'deterministic' requirement of an index on the computed column.
A function declared WITH SCHEMABINDING will retain additional knowledge about the object dependencies used in the function (e.g. columns in the table), and will prevent any changes to these columns, unless the function itself is dropped beforehand.
Deterministic functions can also assist Sql Server in optimizing its execution plans, most notably the Halloween Protection problem.
Here's an example of creating an index on a computed column using a schema bound function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
with schemabinding
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName
else case when #FirstName = '' then #LastName
else (#LastName + ' ' + #FirstName) end end)
return #Result
end
create table Person
(
isperson bit,
lastname nvarchar(100),
firstname nvarchar(100),
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname)
)
go
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')
go
create index ix1_person on person(fullname)
go
select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'
go
Hi I have this stored procedure for Searching employee information. I want the user to have the choice to enter ID, or First Name or Last Name. but when I execute this stored procedure, it requires the other parameters.
create proc searchtry
#empID int,
#firstname varchar(20),
#lastname varchar(20)
as
begin
select fld_EmployeeId,fld_EmployeeFirstName,fld_EmployeeLastName
from Reference.tbl_EmployeeDetails
where fld_EmployeeId like #empID
OR fld_EmployeeFirstName like #firstname
OR fld_EmployeeLastName like #lastname
end
You should give default values to the parameters
create proc searchtry
#empID int = NULL,
#firstname varchar(20) = '',
#lastname varchar(20) = ''
as
begin
select fld_EmployeeId,fld_EmployeeFirstName,fld_EmployeeLastName
from Reference.tbl_EmployeeDetails
where fld_EmployeeId like #empID
OR fld_EmployeeFirstName like #firstname
OR fld_EmployeeLastName like #lastname
end
I have the following user-defined function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName else case when #FirstName = '' then #LastName else (#LastName + ' ' + #FirstName) end end)
return #Result
end
I can't create an Index on a computed column using this function cause it's not deterministic.
Someone could explain why is it not deterministic and eventually how to modify to make it deterministic?
Thanks
You just need to create it with schemabinding.
SQL Server will then verify whether or not it meets the criteria to be considered as deterministic (which it does as it doesn't access any external tables or use non deterministic functions such as getdate()).
You can verify that it worked with
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[FullNameLastFirst]'), 'IsDeterministic')
Adding the schemabinding option to your original code works fine but a slightly simpler version would be.
CREATE FUNCTION [dbo].[FullNameLastFirst] (#IsPerson BIT,
#LastName NVARCHAR(100),
#FirstName NVARCHAR(100))
RETURNS NVARCHAR(201)
WITH SCHEMABINDING
AS
BEGIN
RETURN CASE
WHEN #IsPerson = 0
OR #FirstName = '' THEN #LastName
ELSE #LastName + ' ' + #FirstName
END
END
You need to declare the User Defined Function WITH SCHEMABINDING to appease the 'deterministic' requirement of an index on the computed column.
A function declared WITH SCHEMABINDING will retain additional knowledge about the object dependencies used in the function (e.g. columns in the table), and will prevent any changes to these columns, unless the function itself is dropped beforehand.
Deterministic functions can also assist Sql Server in optimizing its execution plans, most notably the Halloween Protection problem.
Here's an example of creating an index on a computed column using a schema bound function:
create function [dbo].[FullNameLastFirst]
(
#IsPerson bit,
#LastName nvarchar(100),
#FirstName nvarchar(100)
)
returns nvarchar(201)
with schemabinding
as
begin
declare #Result nvarchar(201)
set #Result = (case when #IsPerson = 0 then #LastName
else case when #FirstName = '' then #LastName
else (#LastName + ' ' + #FirstName) end end)
return #Result
end
create table Person
(
isperson bit,
lastname nvarchar(100),
firstname nvarchar(100),
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname)
)
go
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')
go
create index ix1_person on person(fullname)
go
select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'
go