SQL Update if parameter is not null or empty - sql

I searched some ways to check if a SQL Server parameter is not null or empty but I'm not sure what's the best way to use this when updating several columns:
I had this code at first that was updating without checking for empty or Null values:
UPDATE [Users]
SET FirstName = #firstname, City = #city, Address = #address, ....
WHERE ID = #iduser
Then I added an IF clause before updating, it is working this way but I'm not sure if that's the best way to do it, it is going to be long if I have to update several columns.
--Check if parameter is not null or empty before updating the column
IF (#firstname IS NOT NULL AND #firstname != '')
UPDATE [Users]
SET FirstName = #firstname
WHERE ID = #iduser
IF (#city IS NOT NULL AND #city != '')
UPDATE [Users]
SET City = #city
WHERE ID = #iduser
...
...
If the value is Null or Empty I don't need to update, just keep the original value in the database.

not sure what you are trying to achieve if it is blank, but I would try using IsNull() I don't think there is an IsBlank(), but it shouldn't be too hard to write yourself
Using just IsNull your query would look something like...
Update [Users]
set FirstName = IsNull(#FirstName, FirstName),
City = IsNull(#City, City)
....
Where ...
this will Update the row with the param value if they are NOT null, otherwise update it to itself aka change nothing.

Update [Users]
set FirstName = iif(ISNULL(ltrim(rtrim(#FirstName)), '')='', FirstName, #FirstName),
....
Where ...

Related

WHERE clause using values that could be NULL

I need to do something like this:
DECLARE #firstname VARCHAR(35)
DECLARE #lastname VARCHAR(35)
SELECT *
FROM Customers
WHERE Firstname = #firstname AND Lastname = #lastname
The problem is that #firstname and #lastname could sometimes be NULL. In those cases, the query above would fail to find matching rows because NULL is never equal to NULL.
If one of these variables is NULL, I'd like to return a match if the corresponding value in the database is also NULL. But, of course, SQL Server uses IS to compare for NULL. And if either value is NULL in the example above, it is not considered a match.
Is there any way to accomplish this?
Just use AND/OR logic e.g.
SELECT *
FROM Customers
WHERE ((Firstname IS NULL AND #firstname IS NULL) OR Firstname = #firstname)
AND ((Lastname IS NULL AND #lastname IS NULL) OR Lastname = #lastname);
You can leverage INTERSECT in a correlated subquery to do this. This works because set-based operations compare NULLs as equal.
The compiler will automatically compile this down to an IS comparison, there should not be any performance hit.
DECLARE #firstname VARCHAR(35)
DECLARE #lastname VARCHAR(35)
SELECT *
FROM Customers c
WHERE EXISTS (SELECT c.Firstname, c.Lastname
INTERSECT
SELECT #firstname, #lastname)
The logic is: for every row, create a one-row virtual table with the two values, intersect it with the two variables and there must be a result.
For a <> semantic, change EXISTS to NOT EXISTS, rather than changing to EXCEPT, I find the former optimizes better.
All credit to Paul White for this trick.

Why does my SQL query return a record that doesn't match the where clause?

This query returns a result of one record where both the [E-mail] and [E-mail 2] are equal to 'e'. Most definitely the result of a lazy salesman. Any idea why this is the case though?
My query is as shown below so I should only get records where the email is equal to 'emailfromsomeone#hotmail.com' correct?
declare #email as varchar
set #email = 'emailfromsomeone#hotmail.com'
select
C.[No_],
C.[First Name] firstname,
C.[Surname] lastname,
C.[E-Mail] as email,
C.[E-Mail 2] as email_2,
C.[GDPR Opt-in] as GDPR_opt_in,
C.[Salesperson Code] as sales_person
from
[Contact] as C
where
lower(C.[E-Mail]) = lower(#email)
or lower(C.[E-Mail 2]) = lower(#email)
You've declared #email to be a VARCHAR, meaning a single VARCHAR. When you're setting the #email variable, it's being truncated to just the first character.
Try changing VARCHAR to something like VARCHAR(100).
I got it. So i declared the variable like so and then it worked
declare #email VARCHAR(255)
sorry for bothering you stakoverflow!

Use ISNULL or "LIKE"

I have a stored procedure which takes in a few parameters which could be NULL or maybe not.
I can use the ISNULL option if I have a clear value for a parameter, but if I want to use a "LIKE" instead of null I'm not sure how to do it. See below:
Parameters are:
#org_id as int,
#deleted as bit = NULL,
#firstname as char = NULL,
#lastname as char = NULL
Select statement is:
select user_id, firstname,lastname,firstname +' ' + lastname as fullname, email, phone, is_tech, is_admin,is_cust
from users
where users.org_id=#org_id and is_tech=1 and delete_flag=ISNULL(#deleted,delete_flag)
order by lastname,firstname asc
If the firstname and lastname params are not null, but are instead a character e.g."J" ,how can I write something similar to the delete_flag clause ..and firstname like 'J%' but if not use null?
Any ideas?
You can use this:
WHERE field LIKE #param OR #param IS NULL

Building dynamic WHERE clause in stored procedure

I'm using SQL Server 2008 Express, and I have a stored procedure that do a SELECT from table, based on parameters. I have nvarchar parameters and int parameters.
Here is my problem, my where clause looks like this:
WHERE [companies_SimpleList].[Description] Like #What
AND companies_SimpleList.Keywords Like #Keywords
AND companies_SimpleList.FullAdress Like #Where
AND companies_SimpleList.ActivityId = #ActivityId
AND companies_SimpleList.DepartementId = #DepartementId
AND companies_SimpleList.CityId = #CityId
This parameters are the filter values set by the user of my ASP.NET MVC 3 application, and the int parameters may not be set, so their value will be 0. This is my problem, the stored procedure will search for items who have 0 as CityId for example, and for this, it return a wrong result. So it will be nice, to be able to have a dynamic where clause, based on if the value of int parameter is grater than 0, or not.
Thanks in advance
Try this instead:
WHERE 1 = 1
AND (#what IS NULL OR [companies_SimpleList].[Description] Like #What )
AND (#keywords IS NULL OR companies_SimpleList.Keywords Like #Keywords)
AND (#where IS NULL OR companies_SimpleList.FullAdress Like #Where)
...
If any of the parameters #what, #where is sent to the stored procedure with NULL value then the condition will be ignored. You can use 0 instead of null as a test value then it will be something like #what = 0 OR ...
try something like
AND companies_SimpleList.CityId = #CityId or #CityID = 0
Here is another easy-to-read solution for SQL Server >=2008
CREATE PROCEDURE FindEmployee
#Id INT = NULL,
#SecondName NVARCHAR(MAX) = NULL
AS
SELECT Employees.Id AS "Id",
Employees.FirstName AS "FirstName",
Employees.SecondName AS "SecondName"
FROM Employees
WHERE Employees.Id = COALESCE(#Id, Employees.Id)
AND Employees.SecondName LIKE COALESCE(#SecondName, Employees.SecondName) + '%'

SQL nested/complicated select statement

I to write a script that will update/insert a record about a property. I have determined a method to ensure that the script will not create duplicates but I'm not entirely sure how to implement it.
We take an import from a CSV file that will have a load of properties. This property has a third party reference number from the agent. This can create a duplicate because obviously a separate agent may use the same reference.
In the table it needs to be updated/inserted either buildingNumber, buildingName or AddressLine1 will not be null. Then I need to check the existing records postcode and whichever column isn't null against the column I will be inserting.
I know the table structure is shit. I didn't design it and there's no way I can change it.
I'm looking for something like this.
if exists(
select * from tblMemberProperties
where ThirdPartyReference = #PropertyThirdPartyReference
and ((if buildingNumber is not null (then BuildingNumber = #BuildingNumber)
or (if buildingName is not null and above if isn't satisfied (then buildingName = #BuildingName)
or (if AddressLine1 is not null and above 2 are null (then AddressLine1 = #AddressLine1))
and (postcode = #postcode)
if exists(
select * from tblMemberProperties
where Postcode = #Postcode
and BuildingNumber = #BuildingNumber
and BuildingNumber is not null
or
Postcode = #Postcode
and BuildingName = #BuildingName
and BuildingName is not null
or
Postcode = #Postcode
and AddressLine1 = #AddressLine1
and AddressLine1 is not null)