How to convert empty spaces into null values, using SQL Server? - sql-server

I have a table and the columns on this table contains empty spaces for some records. Now I need to move the data to another table and replace the empty spaces with a NULL value.
I tried to use:
REPLACE(ltrim(rtrim(col1)),' ',NULL)
but it doesn't work. It will convert all of the values of col1 to NULL. I just want to convert only those values that have empty spaces to NULL.

I solved a similar problem using NULLIF function:
UPDATE table
SET col1 = NULLIF(col1, '')
From the T-SQL reference:
NULLIF returns the first expression if the two expressions are not equal. If the expressions are equal, NULLIF returns a null value of the type of the first expression.

Did you try this?
UPDATE table
SET col1 = NULL
WHERE col1 = ''
As the commenters point out, you don't have to do ltrim() or rtrim(), and NULL columns will not match ''.

SQL Server ignores trailing whitespace when comparing strings, so ' ' = ''. Just use the following query for your update
UPDATE table
SET col1 = NULL
WHERE col1 = ''
NULL values in your table will stay NULL, and col1s with any number on space only characters will be changed to NULL.
If you want to do it during your copy from one table to another, use this:
INSERT INTO newtable ( col1, othercolumn )
SELECT
NULLIF(col1, ''),
othercolumn
FROM table

This code generates some SQL which can achieve this on every table and column in the database:
SELECT
'UPDATE ['+T.TABLE_SCHEMA+'].[' + T.TABLE_NAME + '] SET [' + COLUMN_NAME + '] = NULL
WHERE [' + COLUMN_NAME + '] = '''''
FROM
INFORMATION_SCHEMA.columns C
INNER JOIN
INFORMATION_SCHEMA.TABLES T ON C.TABLE_NAME=T.TABLE_NAME AND C.TABLE_SCHEMA=T.TABLE_SCHEMA
WHERE
DATA_TYPE IN ('char','nchar','varchar','nvarchar')
AND C.IS_NULLABLE='YES'
AND T.TABLE_TYPE='BASE TABLE'

A case statement should do the trick when selecting from your source table:
CASE
WHEN col1 = ' ' THEN NULL
ELSE col1
END col1
Also, one thing to note is that your LTRIM and RTRIM reduce the value from a space (' ') to blank (''). If you need to remove white space, then the case statement should be modified appropriately:
CASE
WHEN LTRIM(RTRIM(col1)) = '' THEN NULL
ELSE LTRIM(RTRIM(col1))
END col1

Maybe something like this?
UPDATE [MyTable]
SET [SomeField] = NULL
WHERE [SomeField] is not NULL
AND LEN(LTRIM(RTRIM([SomeField]))) = 0

here's a regex one for ya.
update table
set col1=null
where col1 not like '%[a-z,0-9]%'
essentially finds any columns that dont have letters or numbers in them and sets it to null. might have to update if you have columns with just special characters.

Related

Update SQL Query for varchar(max) column

How to update a varchar(max) column to an empty string from null value?
Here is the pseudo code:
UPDATE tablename
SET all varchar(max) columns =''
WHERE varchar(max) == NULL
Need to create something like this, any help will be appreaciated!
Please use this. where ColumnName IS NULL for NULL comparison equal does not work with default ANSI_NULLS.
ColumnName -> VARCHAR(MAX)
Update tablename
SET field =''
where ColumnName IS NULL
Regarding this question, When you gonna Update the column try to put the empty string inside the quotes
You can check this code hopefully you will get the Idea
UPDATE Table_Name (v VARCHAR(4))
SET (' ')
WHERE condition;
Output
SELECT CONCAT ('(', v, ')') FROM Table_Name;
| CONCAT('(', v, ')')
| ( )
In order to UPDATE to all row which has null values use ANSI SQL COALESCE() function
UPDATE tablename
SET
Column = COALESCE(Column, ''), Column1 = COALESCE(Column1, ''),
....
Column4 = COALESCE(Column4, '')
Since use of COALESCE(), it would just update the column values to blank where it found the null values.

SQL Server 2016 How to use a simple Regular Expression in T-SQL?

I have a column with the name of a person in the following format: "LAST NAME, FIRST NAME"
Only Upper Cases Allowed
Space after comma optional
I would like to use a regular expression like: [A-Z]+,[ ]?[A-Z]+ but I do not know how to do this in T-SQL. In Oracle, I would use REGEXP_LIKE, is there something similar for SQL Server 2016?
I need something like the following:
UPDATE table
SET is_correct_format = 'YES'
WHERE REGEXP_LIKE(table.name,'[A-Z]+,[ ]?[A-Z]+');
First, case sensitivity depends on the collation of the DB, though with LIKE you can specify case comparisons. With that... here is some Boolean logic to take care of the cases you stated. Though, you may need to add additional clauses if you discover some bogus input.
declare #table table (Person varchar(64), is_correct_format varchar(3) default 'NO')
insert into #table (Person)
values
('LowerCase, Here'),
('CORRECTLY, FORMATTED'),
('CORRECTLY,FORMATTEDTWO'),
('ONLY FIRST UPPER, LowerLast'),
('WEGOT, FormaNUMB3RStted'),
('NoComma Formatted'),
('CORRECTLY, TWOCOMMA, A'),
(',COMMA FIRST'),
('COMMA LAST,'),
('SPACE BEFORE COMMA , GOOD'),
(' SPACE AT BEGINNING, GOOD')
update #table
set is_correct_format = 'YES'
where
Person not like '%[^A-Z, ]%' --check for non characters, excluding comma and spaces
and len(replace(Person,' ','')) = len(replace(replace(Person,' ',''),',','')) + 1 --make sure there is only one comma
and charindex(',',Person) <> 1 --make sure the comma isn't at the beginning
and charindex(',',Person) <> len(Person) --make sure the comma isn't at the end
and substring(Person,charindex(',',Person) - 1,1) <> ' ' --make sure there isn't a space before comma
and left(Person,1) <> ' ' --check preceeding spaces
and UPPER(Person) = Person collate Latin1_General_CS_AS --check collation for CI default (only upper cases)
select * from #table
The tsql equivalent could look like this. I'm not vouching for the efficiency of this solution.
declare #table as table(name varchar(20), is_Correct_format varchar(5))
insert into #table(name) Values
('Smith, Jon')
,('se7en, six')
,('Billy bob')
UPDATE #table
SET is_correct_format = 'YES'
WHERE
replace(name, ', ', ',x')
like (replicate('[a-z]', charindex(',', name) - 1)
+ ','
+ replicate('[a-z]', len(name) - charindex(',', name)) )
select * from #table
The optional space is hard to solve, so since it's next to a legal character I'm just replacing with another legal character when it's there.
TSQL does not provide the kind of 'repeating pattern' of * or + in regex, so you have to count the characters and construct the pattern that many times in your search pattern.
I split the string at the comma, counted the alphas before and after, and built a search pattern to match.
Clunky, but doable.

Cannot remove trailing space in SQL Server 2005

This is in SQL Server 2005. I have a varchar column and some rows contain trailing space, e.g. abc, def.
I tried removing the trailing space with this command:
update thetable
set thecolumn = rtrim(thecolumn)
But the trailing space remains. I tried to find them using:
select *
from thetable
where thecolumn <> rtrim(thecolumn)
But it returned nothing.
Are there some settings that I am not aware that influences trailing space check?
EDIT:
I know that there is trailing space from SSMS, when I copy paste the value from the grid to the editor, it has trailing space.
Check if the spaces that are not removed have the ASCII code 32.
Try this to replace "hard space" with "soft space":
update thetable set thecolumn = rtrim(replace(thecolumn, char(160), char(32)))
the query was missing equal sign
Are you certain that it is a space (ascii 32) character? You can get odd behavior with other "non-visible" characters. Try running
select ascII(right(theColumn, 1))
from theTable
and see what you get.
Use this Function:
Create Function [dbo].[FullTrim] (#strText varchar(max))
Returns varchar(max) as
Begin
Declare #Ch1 char,#ch2 char
Declare #i int,#LenStr int
Declare #Result varchar(max)
Set #i=1
Set #LenStr=len(#StrText)
Set #Result=''
While #i<=#LenStr
Begin
Set #ch1=SUBSTRING(#StrText,#i,1)
Set #ch2=SUBSTRING(#StrText,#i+1,1)
if ((#ch1=' ' and #ch2=' ') or (len(#Result)=0 and #ch1=' '))
Set #i+=1
Else
Begin
Set #Result+=#Ch1
Set #i+=1
End
End
Return #Result
End
In SQL, CHAR(n) columns are right-padded with spaces to their length.
Also string comparison operators (and most functions too) do not take the trailing spaces into account.
DECLARE #t TABLE (c CHAR(10), vc VARCHAR(10))
INSERT
INTO #t
VALUES ('a ', 'a ')
SELECT LEN(c), LEN(vc), с + vc
FROM #t
--
1 1 "a a"
Please run this query:
SELECT *
FROM thetable
WHERE thecolumn + '|' <> RTRIM(thecolumn) + '|'
and see if it finds something.
It sounds like either:
1) Whatever you are using to view the values is inserting the trailing space (or the appearance thereof- try a fixed-width font like Consolas).
2) The column is CHAR, not VARCHAR. In that case, the column will be padded with spaces up to the length of the column, e.g. inserting 'abc' into char(4) will always result in 'abc '
3) You are somehow not committing the updates, not updating the right column, or other form of user error. The update statement itself looks correct on the face of it.
I had the same issues with RTRIM() AND LTRIM() functions.
In my situation the problem was in LF and CR chars.
Solution
DECLARE #test NVARCHAR(100)
SET #test = 'Declaration status '
SET #test = REPLACE(REPLACE(#test, CHAR(10), ''), CHAR(13), '')

Adding Dyanmic In() Conditions in Sql Server

Facing problem for generating SQL Server Query
In the Following query dynamic conditions are added to check whether value is null or not
Select *
From tblEmployees
where EmployeeName = Case
When #EmployeeName Is Not Null
Then #EmployeeName
Else EmployeeName
End
But I need to add IN () Conditions and the parameter with in the IN () could be null or blank also ,if the parameter /string which is passed to the IN condition is blank then i donot want to add that condition in the query.
So how can i Achieve this.A helping hand will be very useful for me.
Thanks and Regards,
D.Mahesh
Depending on value of your parameter (blank of not), you can create SQL string accordingly.
DECLARE #sqlCommand VARCHAR(1000)
IF(ISNULL(#YourParameter,'')='')
#sqlCommand = 'your query goes here'
ELSE
#sqlCommand = 'your query goes here'
and then, run it using dynamic query execution
EXEC (#sqlCommand)
If not dynamic query then,
SELECT ....
FROM ....
WHERE CASE WHEN ISNULL(#YourParameter,'')='' THEN '' ELSE EmployeeName END IN (ISNULL(#YourParameter,''))
See if this works...
I think the Dynamic query is the best solution, however you could put the "IS NULL" and "IS BLANK" condition in OR with your IN clause.
Something like that
Select *
From tblEmployees
where #EmployeeName is null or EmployeeName in (#EmployeeName)
When #EmployeeName is null, your IN clause will be ignored
If i get this right you have #EmployeeName = 'Name1,Name2,Name3' and you want to get the employees that is named Name1 or Name2 or Name3, also the variable #EmployeeName can be null or contain an empty string.
Instead of using IN you can split the string #EmployeeName on , and store it in a table variable or temporary table. Then you can use that table in a join against tblEmployees to get the rows you need.
There are a lot of posts in S.O. about how to split a string. Here is one recent variant.
Group by sql query on comma joined column
This will work for SQL Server 2005 or later.
declare #EmployeeName varchar(100) = 'Name2,Name3,Name5'
-- Null or empty will have a comma
set #EmployeeName = coalesce(#EmployeeName, '') + ','
-- cteNames splits the string to rows
;with cteNames
as
(
select
left(#EmployeeName, charindex(',', #EmployeeName)-1) as Name,
right(#EmployeeName, len(#EmployeeName)-charindex(',', #EmployeeName)) as EmployeeName
union all
select
left(EmployeeName, charindex(',', EmployeeName)-1) as Name,
right(EmployeeName, len(EmployeeName)-charindex(',', EmployeeName)) as EmployeeName
from cteNames
where charindex(',', EmployeeName) > 1
)
select E.*
from tblEmployees as E
inner join cteNames as N
on E.Name = N.Name or
#EmployeeName = ','
-- #EmployeeName = ',' will give you all names when #EmployeeName is null of empty

SQL if statement in where clause for searching database

I'm creating a stored procedure to return search results where some of the parameters are optional.
I want an "if statement" in my where clause but can't get it working. The where clause should filter by only the non-null parameters.
Here's the sp
ALTER PROCEDURE spVillaGet
-- Add the parameters for the stored procedure here
#accomodationFK int = null,
#regionFK int = null,
#arrivalDate datetime,
#numberOfNights int,
#sleeps int = null,
#priceFloor money = null,
#priceCeil money = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select tblVillas.*, tblWeeklyPrices.price from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where
If #accomodationFK <> null then
accomodationTypeFK = #accomodationFK
#regionFK <> null Then
And regionFK = #regionFK
IF #sleeps <> null Then
And sleeps = #sleeps
IF #priceFloor <> null Then
And price >= #priceFloor And price <= #priceCeil
END
Any ideas how to do this?
select tblVillas.*, tblWeeklyPrices.price
from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where (#accomodationFK IS null OR accomodationTypeFK = #accomodationFK)
AND (#regionFK IS null or regionFK = #regionFK)
AND (#sleeps IS null OR sleeps = #sleeps)
AND (#priceFloor IS null OR (price BETWEEN #priceFloor And #priceCeil))
We've used a lot of COALESCE here in the past for "dynamic WHERE clauses" like you're talking about.
SELECT *
FROM vehicles
WHERE ([vin] LIKE COALESCE(#vin, [vin]) + '%' ESCAPE '\')
AND ([year] LIKE COALESCE(#year, [year]) + '%' ESCAPE '\')
AND ([make] LIKE COALESCE(#make, [make]) + '%' ESCAPE '\')
AND ([model] LIKE COALESCE(#model, [model]) + '%' ESCAPE '\')
A big problem arises though when you want to optionally filter for a column that is also nullable... if the data in the column is null for a given row AND the user didn't enter anything to search by for that column (so the user input is also null), then that row won't even show up in the results (which, if your filters are optional, is incorrect exclusionary behavior).
In order to compensate for nullable fields, you end up having to do messier looking SQL like so:
SELECT *
FROM vehicles
WHERE (([vin] LIKE COALESCE(#vin, [vin]) + '%' ESCAPE '\')
OR (#vin IS NULL AND [vin] IS NULL))
AND (([year] LIKE COALESCE(#year, [year]) + '%' ESCAPE '\')
OR (#year IS NULL AND [year] IS NULL))
AND (([make] LIKE COALESCE(#make, [make]) + '%' ESCAPE '\')
OR (#make IS NULL AND [make] IS NULL))
AND (([model] LIKE COALESCE(#model, [model]) + '%' ESCAPE '\')
OR (#model IS NULL AND [model] IS NULL))
Just so you understand, IF is procedural code in T-SQl. It canot be used in an insert/update/delete/select statement it can only be used to determine which of two statements you want to run. When you need different possibilities within a statement, you can do as above or use a CASE statement.
You can also use IsNull or Coalesce function
Where accomodationTypeFK = IsNull(#accomodationFK, accomodationTypeFK)
And regionFK = Coalesce(#regionFK,regionFK)
And sleeps = IsNull(#sleeps,sleeps )
And price Between IsNull(#priceFloor, Price) And IsNull(priceCeil, Price)
This does the same thing as Michael's suggestion above...
IsNull(), and Coalesce() work more or less the same way, they return the first non-Null argument in the list, except iSNull only allows 2 arguments, and Coalesce can take any number...
http://blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx
Try putting your IF statement around the entire SQL statement. That means will have one SQL statement for each condition. That worked for me.

Resources