I have a Sql Server 2K8 R2 DB with a table in which column values contain values separated by characters (char 13 and char 10).
I am creating a script to import data into a properly normalized schema.
There is something like this in my source table:
ID | Value ________________ 1 | line 1 line 2 ________________ 2 | line 3 ________________ 3 | line 4 line 5 line 6 ________________
etc.
[edit] FYI, Id is an integer, and the value is nvarchar (3072) [/ edit]
What I want is to query the table so that it looks like this:
ID | Value ________________ 1 | line 1 ________________ 1 | line 2 ________________ 2 | line 3 ________________ 3 | line 4 ________________ 3 | line 5 ________________ 3 | line 6 ________________
I read a lot of answers here on SO, as well as on the Internet, and I believe that using master..sptvalues
should be the solution. I especially tried to reproduce the solution to the question Split one column into several rows . However, without success (suspecting the presence of two characters causing problems).
Now I wrote this query:
SELECT T.ID, T.Value, RIGHT(LEFT(T.Value,spt.Number-1), CHARINDEX(char(13)+char(10),REVERSE(LEFT(char(13)+char(10)+T.Value,spt.Number-1)))) as Extracted FROM master..spt_values spt, ContactsNew T WHERE Type = 'P' AND spt.Number BETWEEN 1 AND LEN(T.Value)+1 AND (SUBSTRING(T.Value,spt.Number,2) = char(13)+char(10) OR SUBSTRING(T.Value,spt.Number,2) = '')
This request, unfortunately, is returned:
ID | Value | Extracted ________________________________ 1 | line 1 | <blank> line 2 | ________________________________ 1 | line 1 | line 2 line 2 | ________________________________ 2 | line 3 | <blank> ________________________________ 3 | line 4 | <blank> line 5 | line 6 | ________________________________ 3 | line 4 | line 5 line 5 | line 6 line 6 | ________________________________ 3 | line 4 | line 6 line 5 | line 6 | ________________________________
<blank>
is an empty string, not an empty string.
I would appreciate help setting up my request.
[Edit2] My source table contains less than 200 entries, and performance is optional, so I am aiming for a simple solution, not an efficient one [Edit2]
[Edit3] The source database is read-only. I cannot add a stored procedure, function or type clr. I have to do this in one request. [Edit3]
[Edit4] Something strange ... it seems that spaces are also considered as delimiters.
If I run the following query:
SELECT T.ID, replace(T.Value, '#', ' '), replace(RIGHT( LEFT(T.Value,spt.Number-1), CHARINDEX( char(13) + char(10),REVERSE(LEFT(char(10) + char(13)+T.Value,spt.Number-0))) ), '#', ' ') FROM master..spt_values spt, ( select contactID, replace(Value,' ', '#') Value from ContactsNew where Value is not null ) T WHERE Type = 'P' AND spt.Number BETWEEN 1 AND LEN(T.Value)+1 AND (SUBSTRING(T.Value,spt.Number,2) = char(13) + char(10) OR SUBSTRING(T.Value,spt.Number,1) = '')
I received the correct number of returns (however, still having the wrong values) during the execution of this request:
SELECT T.ID, T.Value, RIGHT( LEFT(T.Value,spt.Number-1), CHARINDEX( char(13) + char(10),REVERSE(LEFT(char(10) + char(13)+T.Value,spt.Number-0))) ) FROM master..spt_values spt, ( select contactID, Value from ContactsNew where Value is not null ) T WHERE Type = 'P' AND spt.Number BETWEEN 1 AND LEN(T.Value)+1 AND (SUBSTRING(T.Value,spt.Number,2) = char(13) + char(10) OR SUBSTRING(T.Value,spt.Number,1) = '')
splits into spaces also