SQL table trailing space cause errors - sql

I had an error in my C# code and after debugging found that
this is because on entry in a table has a trailing space.
For example 'aaa '
Now in my C# code try to set a Selected values of a combo box to this(combobox as an item with value of 'aaa' and this fails.
Clearly The solution is to fix the DB 'aaa '
Now I go to DB
and do this :
Select * from mytable
where Name='aaa'
I get Name 'aaa'
Select * from mytable
where Name='aaa '
Again I get Name 'aaa'
Select len(name) from My table
where name ='aaa'
I get 3
My question is: how by querying the table I know it has an extra space for 'aaa '?

SQL server len function excludes trailing blanks.
Consider using the DATALENGTH (Transact-SQL) function which does not trim the string.
So you can check if datalength(column) <> datalength(rtrim(column)) to find if it contains trailing spaces.
Note: if processing a unicode string, DATALENGTH will return twice the number of characters.

As Giorgi Nakeuri has explained, 'a ' and 'a' are considered equal. But you can easily find trailing spaces with LIKE:
select * from mytable where name like '% ';
And here is how to update:
update mytable set name = rtrim(name) where name like '% ';

Related

Search SQL Server table column which has multiple leading and trailing spaces only

I am selecting data from a SQL Server table which has leading space characters (could be one, two or more) and also has trailing spaces (could be one, two, and more) also.
I have used LIKE ' %' to search leading spaces value and used LIKE '% ' for trailing spaces records, but the search result displayed only returns with records which has only one space as leading/trailing space. But I am not sure the number spaces available in records.
This is the query that I tried:
SELECT [ColumName1], [ColumName], *
FROM [table1]
WHERE [ColumName] LIKE ' %' OR [ColumName] LIKE '% '
Expected result:
' Testdata1', 'Test2 ', ' Test3',' Test4 '
But actual result is :
'Test3 '
There's an easier way to do this, without using likes. TRIM cuts off trailing whitespaces, you can use that to filter. What you're doing here is comparing the trimmed version of every [ColumName] to the untrimmed version, and returning those that differ. This accomplishes what you want.
select
[ColumName1], [ColumName], *
from [table1]
WHERE TRIM([ColumName]) <> [ColumName]
This produces all fields that have any (one or more) trailing or leading whitespaces.
Depending on your version of SQL Server, TRIM might not be available. No matter, there's a workaround around that as well:
select
[ColumName1], [ColumName], *
from [table1]
WHERE LTRIM([ColumName]) <> [ColumName]
OR RTRIM([ColumName]) <> [ColumName]
Try to use LTRIM with RTRIM and LIKE operator to find spaces. Let me show an example:
DECLARE #tbl TABLE
(
FooColumn VARCHAR(100)
)
INSERT INTO #tbl
VALUES
(' Example1'),
(' Example2'),
('Example3 '),
('Example4 '),
('Example5')
SELECT
t.FooColumn
FROM #tbl t
WHERE RTRIM(t.FooColumn) LIKE '% %' OR LTRIM(t.FooColumn) LIKE '% %'
You can try this,
DECLARE #Temp_Table TABLE
(
ColumnName VARCHAR(100)
)
INSERT INTO #Temp_Table
VALUES
(' Test1'),
(' Test2'),
('Test3 '),
('Test4 '),
('Test5')
SELECT ColumnName
FROM #Temp_Table
WHERE (LEFT(ColumnName,1)=' ' OR RIGHT(ColumnName,1)=' ')
If I am not mistaken, SQL Server's LIKE allows character sets. We can use this to find control and whitespace characters by excluding characters that we allow (letters and numbers). Please try:
SELECT *
FROM [table1]
WHERE [ColumName] LIKE '[^A-Za-z0-9]%' OR [ColumName] LIKE '%[^A-Za-z0-9]';
Finally i found that column values has been saved with special ascii values, hence those characters were not removed while using LTRIM, RTRIM.
This worked : LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(plaincitation, CHAR(10), CHAR(32)),CHAR(13), CHAR(32)),CHAR(160), CHAR(32)),CHAR(9),CHAR(32))))

Spaces in WHERE clause for SQL Server [duplicate]

This question already has answers here:
Why the SQL Server ignore the empty space at the end automatically?
(2 answers)
Closed 4 years ago.
I want to find out the records in which a certain column contains exactly one space and nothing else. So I wrote the first of the following queries:
select COUNT(*)
from mytable
where col = ' ' -- One space
select COUNT(*)
from mytable
where col = ' ' -- Two spaces
select COUNT(*)
from mytable
where col = ' ' -- Three spaces
However, all three queries return the exact same records. Does Microsoft SQL Server not distinguish between the amount of spaces? How can I query exactly for one, two or more spaces?
Yes, it ignores trailing spaces in comparisons.
You can try to append a delimiting character.
SELECT count(*)
FROM mytable
WHERE col + 'X' = ' X';
You can combine DATALENGTH clause with your query:
select COUNT(*)
from mytable
where col = ' '
and DATALENGTH(col) = 1
The link posted by Ivan Starostin in the comments of the OP provides a good explanation and I think it deserves a full answer instead of just a comment.
To summarize, try using LIKE instead of equality:
select COUNT(*)
from mytable
where col LIKE ' ' -- one space
And you can also use DATALENGTH to calculate how many bytes are in the field to double-check field length:
select col, DATALENGTH(col)
from mytable;
Please note that DATALENGTH will return a different value if col is a VARCHAR vs NVARCHAR. VARCHAR stores each character as 1 byte where NVARCHAR stores each character as 2 bytes since NVARCHAR is stored in Unicode.
You can replace the single space with a single character (for exampe §) and then put this character in your where condition:
declare #tmp table(col varchar(50))
insert into #tmp values
(' '),
(' '),
(' ')
select COUNT(*) as one_space_count
from #tmp
where replace(col,' ','§')='§'
select COUNT(*) as two_space_count
from #tmp
where replace(col,' ','§')='§§'
select COUNT(*) as three_space_count
from #tmp
where replace(col,' ','§')='§§§'
Results:

How to replace underscore with a blank space with a regular expression in SQL

I'm trying to insert post codes into my database but getting rid of the underscores.
I have a table called FeedDataSetMapping that is used to map the fields before they get inserted:
INSERT INTO FeedDataSetMapping (
[source_field]
,[database_field]
,[template_id]
,[conversion_id]
,[order_id]
,[values_group]
,[direct_value]
,[value_regex]
,[condition_regex]
,[split_separator]
,[enclosing_character]
,[cumulative_field]
,[cumulative_format])
VALUES
('manufacturerId','manufacturer_Id',#template_id,0,0,null,null,null,null,null,null,null,null),
('dealership','leasing_broker_name',#template_id,0,0,null,null,null,null,null,null,null,null),
('manufacturersDealerId','supplier_ref',#template_id,0,0,null,null,19,null,null,null,null,null),
('address1','address1',#template_id,0,0,null,null,null,null,null,null,null,null),
('address2','address2',#template_id,0,0,null,null,null,null,null,null,null,null),
('postcode','post_code',#template_id,0,0,null,null,null,null,null,null,null,null),
('telephone','telephone',#template_id,0,0,null,null,null,null,null,null,null,null),
('fax','fax_number',#template_id,0,0,null,null,null,null,null,null,null,null),
('email','email',#template_id,0,0,null,null,null,null,null,null,null,null),
('website','web_address',#template_id,0,0,null,null,null,null,null,null,null,null),
('NewCarSales','service_mask',#template_id,0,0,null,1,null,'^(?!(?i:^0$|^n$|^no$|^f$|^false$|^$))',null,null,1,null),
('UsedCarSales','service_mask',#template_id,0,0,null,2,null,'^(?!(?i:^0$|^n$|^no$|^f$|^false$|^$))',null,null,1,null),
('Servicing','service_mask',#template_id,0,0,null,8,null,'^(?!(?i:^0$|^n$|^no$|^f$|^false$|^$))',null,null,1,null),
('Repairs','service_mask',#template_id,0,0,null,16,null,'^(?!(?i:^0$|^n$|^no$|^f$|^false$|^$))',null,null,1,null),
('Longitude','longitude',#template_id,0,0,null,null,null,null,null,null,null,null),
('Latitude','latitude',#template_id,0,0,null,null,null,null,null,null,null,null)
This already contains some condition regex that in case that this field contains some text it converts it to true or false respectively.
What I need is a condition_regex that gets rid of these underscores and replaces it with a blank space i.e: 'GDB_A45' to 'GDB A45'. I don't know much about regex so any idea would be greatly appreciated. Thanks in advance!
SQL Server does not have much of regular expression support, but in this case I don't think you need it. You can do a simple replace:
UPDATE mytable
SET mycolumn = REPLACE(mycolumn, '_', ' ')
WHERE mycolumn LIKE '%[_]%'
To do this while updating you can use INSERT ... SELECT instead of INSERT ... VALUES:
INSERT INTO mytable (mycolumn)
SELECT REPLACE('my data 1', '_', ' ') UNION
SELECT REPLACE('my data 2', '_', ' ') UNION
SELECT REPLACE('my_data_3', '_', ' ') UNION
...
There will be some maximum number of unions you can do, so you should split your inserts into batches with this method.
Or, you could define a trigger on the target table that will do the job for you:
CREATE TRIGGER mytrigger ON mytable
AFTER INSERT AS
BEGIN
UPDATE mytable
SET mytable.mycolumn = REPLACE(i.mycolumn, '_', ' ')
FROM mytable
INNER JOIN inserted i
ON i.id = mytable.id
AND i.mycolumn LIKE '%[_]%'
END
... where it is assumed your table has a primary key named id.
Well after been thinking a while I got to the conclusion that would be easier if I replace the underscore from the scraped data during the scraping (in the c# code) before I generate the XML file. That would avoid me a lot of headaches. Anyway thank you for your help guys ;)

Look for trailing spaces in a table

I'd like to know how I can identify trailing spaces in a table. I'm using SQL Server 2008 and create the following table as a test
CREATE TABLE first_test_name
(
firstName varchar(255)
)
And then inserted a record like this:
insert into first_test_name (firstName)
values('Bob')
I then tried inserting a space and then adding a new record like this:
insert into first_test_name (firstName)
values('Bob ') -- just 1 space
And for a 3rd time,
insert into first_test_name (firstName)
values('Bob ') -- two spaces used this time.
Now if I query for for 'Bob' (no spaces), I still get a count of 3.
My query was:
select count(*) from first_test_name WHERE firstName = 'Bob'
Shouldn't the answer have been 1?
Also, I used sp_help on this table and the value for "Trim Trailing Blanks" is set to no.
So why am I getting a count of 3? I was expecting just 1.
On a related note, if I search using this query
select * from first_test_name
where firstName like '% '
I then get the right answer of two rows found.
So just to reiterate, the question is why I get a count of 3 when searching for 'Bob'.
Also, what does "Trim Trailing Blanks" mean in this case?
Why I get a count of 3 when searching for 'Bob'?
SQL Server ignores trailing spaces in most string comparisons.
Also, what does "Trim Trailing Blanks" mean in this case?
This tells you the ANSI_PADDING option set when the table was created.
How can I identify those two with 1 or 2 trailing spaces?
Here's one way.
SELECT *
FROM first_test_name
WHERE firstName LIKE 'Bob '
And to find ones with no trailing space
SELECT *
FROM first_test_name
WHERE firstName LIKE 'Bob' AND firstName NOT LIKE 'Bob '
SQL Server will expand strings with whitespace during comparisons.
This is what I would do:
SELECT COUNT(*)
FROM first_test_name
WHERE REPLACE(firstName, ' ', '_') = 'Bob'
SELECT *
FROM USERS
WHERE DATALENGTH(Username) <> DATALENGTH(RTrim(Username))
Another way might be to append something on the string.
declare #test table(
id varchar(4) not null,
firstname varchar(255) not null)
insert into #test values('1', 'Bob')
insert into #test values('2', 'Bob ')
insert into #test values('3', 'Bob ')
insert into #test values('4', ' Bob')
select count((firstname + 'end')) from #test
where (firstname + 'end') not like '% %'
The query will return a count of 1.
A good clean way to do this would be to compare your original string against an Rtrim version of itself where they don't match e.g.:
SELECT *
FROM First_Test_Name
WHERE Firstname <> RTrim(Firstname)
This should return all records where Firstname has trailing spaces (I think ...)
I was looking recently and couldn't find the answer to this. Thought I'd share since coming across one.
https://stackoverflow.com/a/14188944/1953837
LEN trims trailing whitespaces by default. Using the below they are moved to the front and then the field length is counted.
Hope this helps anyone searching in the future.
(LEN(REVERSE(FieldName))

using trim in a select statement

I have a table, my_table, that has a field my_field. myfield is defined as VARCHAR(7). When I do:
SELECT myfield
FROM my_table;
I get what appears to be the entire 7 characters, but I only want the actual data.
I tried:
SELECT TRIM(myfield)
FROM my_table;
and several variations. But instead of getting 'abcd', I get 'abcd '.
How do I get rid of the trailing blanks?
As others have said:
trim whitespace before data enters the database ("Mop the floor...);
ensure this is not actually a column of type CHAR(7).
Additionally, add a CHECK constraint to ensure no trailing spaces ("...fix the leak.") While you are at it, also prevent leading spaces, double spaces and zero-length string e.g.
CREATE TABLE my_table
(
myfield VARCHAR(7) NOT NULL
CONSTRAINT myfield__whitespace
CHECK (
NOT (
myfield = ''
OR myfield LIKE ' %'
OR myfield LIKE '% '
OR myfield LIKE '% %'
)
)
);-
VARCHAR columns will not pad the string you insert, meaning if you are getting 'ABCD ', that's what you stored in the database. Trim your data before inserting it.
Make sure you are not using the CHAR datatype, which will pad your data in the way you suggest. In any case:
SELECT TRIM(myfield) FROM mytable;
will work.
Make sure also that you are not confusing the way the SQL interpreter adds padding chars to format the data as a table with the actual response.
Make sure that you are not inserting data in this column from a CHAR(7) field.
You need to trim your result when selecting as opposed to when inserting, eg:
SELECT TRIM(myfield) FROM my_table;