473,947 Members | 13,621 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

charindex with error handling?

6 New Member
Hello all,


I am trying to write a script which breaks down a single address field into individual fields, with char(10) or a carriage return as the delimiter.
"empltable" is the table I am using, and "address" is the field I am looking to split.

So far I have managed to:

Split the field into 3

SELECT emplid, name,
CHARINDEX(char( 10),address) first_cr,

CHARINDEX(char( 10), address, CHARINDEX(char( 10), address)+1) second_cr,

LEFT(address, charindex(char( 10), address, -1)) as [address1],

SUBSTRING(addre ss, CHARINDEX(char( 10), address)+1, CHARINDEX(char( 10), address, CHARINDEX(char( 10), address)+1)-CHARINDEX(char( 10), address)) as [address2],

RIGHT(address,L EN(address)-CHARINDEX(char( 10),address,CHA RINDEX(char(10) ,address)+1 )) as [address3]

FROM empltable




...but this only works on the test database, where I am inserting carriage returns into the field to allow the query to work. Basically, when there are less than 2 carriage returns in the address field, the query fails, as there is no error handling in the query.
So, on from that, I tried to introduce ISNULL into the query:

SELECT SUBSTRING(addre ss, 1, NULLIF(CHARINDE X(char(10), address) - 1, -1)) AS [Address1],
SUBSTRING(addre ss, CHARINDEX(char( 10), address) + 1, LEN(address)) AS [Address2]
FROM empltable



...This splits the address field into 2. I am having difficulty returning the middle section though without encountering the errors.
Ideally I would rewrite it to handle any number of returns!

Can someone please help!?
Sep 18 '07 #1
7 4010
azimmer
200 Recognized Expert New Member
Hello all,


I am trying to write a script which breaks down a single address field into individual fields, with char(10) or a carriage return as the delimiter.
"empltable" is the table I am using, and "address" is the field I am looking to split.

So far I have managed to:

Split the field into 3

SELECT emplid, name,
CHARINDEX(char( 10),address) first_cr,

CHARINDEX(char( 10), address, CHARINDEX(char( 10), address)+1) second_cr,

LEFT(address, charindex(char( 10), address, -1)) as [address1],

SUBSTRING(addre ss, CHARINDEX(char( 10), address)+1, CHARINDEX(char( 10), address, CHARINDEX(char( 10), address)+1)-CHARINDEX(char( 10), address)) as [address2],

RIGHT(address,L EN(address)-CHARINDEX(char( 10),address,CHA RINDEX(char(10) ,address)+1 )) as [address3]

FROM empltable




...but this only works on the test database, where I am inserting carriage returns into the field to allow the query to work. Basically, when there are less than 2 carriage returns in the address field, the query fails, as there is no error handling in the query.
So, on from that, I tried to introduce ISNULL into the query:

SELECT SUBSTRING(addre ss, 1, NULLIF(CHARINDE X(char(10), address) - 1, -1)) AS [Address1],
SUBSTRING(addre ss, CHARINDEX(char( 10), address) + 1, LEN(address)) AS [Address2]
FROM empltable



...This splits the address field into 2. I am having difficulty returning the middle section though without encountering the errors.
Ideally I would rewrite it to handle any number of returns!

Can someone please help!?
Question 1: if you have less CRs than fields in the broken up address how do you map the fields?

Question 2: wouldn't it help to first append three CRs to the string then split it up and eventually remove CRs from the end of the last bit?

Question 3: do you absolutely have to do it in one SELECT? Just because it may first help to work it out on several lines (with or without a cursor) and then squeeze it into one SELECT should it be a must.
Sep 18 '07 #2
iritchie
6 New Member
Question 1: if you have less CRs than fields in the broken up address how do you map the fields?

Question 2: wouldn't it help to first append three CRs to the string then split it up and eventually remove CRs from the end of the last bit?

Question 3: do you absolutely have to do it in one SELECT? Just because it may first help to work it out on several lines (with or without a cursor) and then squeeze it into one SELECT should it be a must.

1. There are not less carriage returns than fields - I do not need to map the postcode to "address 4" for example, I just need to break up the field based on how many carriage returns there are (or at least into 3 parts) There are a few incomplete addresses, and a few empty cells, leaving either no or one carriage return, which is where the error is returning. The mapping is purely based on the position of the carriage return position, and I have the statement to the point where I make the value NULL for "no CR's" in which case the statement runs through fine, until the point where I add in the statement selecting the mid-part (or second portion) of the field, and there is a record with 1 CR...
2. Yes, this would be a lot easier, and to be honest it is the way I did this on the test DB. As things stand, I cannot make changes to the data within the production DB, although the only records causing problems are the ones with missing or incomlpete values anyway.
3. Simply, no. I can do this in multiple select statements if there is an easier way of doing this, but I tried this briefly and still found difficulties with the middle portions of the field. Anything outside of the first portion, either from the left or right of the field, becomes very messy due to all the charindex references I've found, and I'm a bit stumped as to adding error handling to it still...



Basically, I know this may not be the best method of returning the results I need, but it is the only method I have tried where I have been making some headway. My T-SQL is a bit rusty, as I only had to run a few updates and inserts, along with editing a couple of Stored Procedures in my last job.
If anyone knows of a better way of doing this, then please let me know :)

I'd like to get this method working, but if it turns out not to be the best way to do it, then I'd be glad to hear alternatives.

Thanks.
Sep 18 '07 #3
azimmer
200 Recognized Expert New Member
1. There are not less carriage returns than fields - I do not need to map the postcode to "address 4" for example, I just need to break up the field based on how many carriage returns there are (or at least into 3 parts) There are a few incomplete addresses, and a few empty cells, leaving either no or one carriage return, which is where the error is returning. The mapping is purely based on the position of the carriage return position, and I have the statement to the point where I make the value NULL for "no CR's" in which case the statement runs through fine, until the point where I add in the statement selecting the mid-part (or second portion) of the field, and there is a record with 1 CR...
2. Yes, this would be a lot easier, and to be honest it is the way I did this on the test DB. As things stand, I cannot make changes to the data within the production DB, although the only records causing problems are the ones with missing or incomlpete values anyway.
3. Simply, no. I can do this in multiple select statements if there is an easier way of doing this, but I tried this briefly and still found difficulties with the middle portions of the field. Anything outside of the first portion, either from the left or right of the field, becomes very messy due to all the charindex references I've found, and I'm a bit stumped as to adding error handling to it still...



Basically, I know this may not be the best method of returning the results I need, but it is the only method I have tried where I have been making some headway. My T-SQL is a bit rusty, as I only had to run a few updates and inserts, along with editing a couple of Stored Procedures in my last job.
If anyone knows of a better way of doing this, then please let me know :)

I'd like to get this method working, but if it turns out not to be the best way to do it, then I'd be glad to hear alternatives.

Thanks.
Here you have a working sample that illustrates the idea. It is possible to do it more intelligently; it is only to show a mindset:
Expand|Select|Wrap|Line Numbers
  1. declare @address varchar(255)
  2. declare @address1 varchar(255), @address2 varchar(255), @address3 varchar(255)
  3. declare @start int, @end int
  4.  
  5. set @address = 'Address Line 1' + char(10)
  6. set @address = @address + 'Address Line 2' + char(10)
  7. set @address = @address + 'Address Line 3' + char(10)
  8. -- select @emplid=emplid, @name=name, @address=@address from empltable
  9.  
  10. set @start = 1
  11.  
  12. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  13. set @address1 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  14. set @start = @end+1
  15.  
  16. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  17. set @address2 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  18. set @start = @end+1
  19.  
  20. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  21. set @address3 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  22. set @start = @end+1
  23.  
  24. print @address
  25. print '->1:'+@address1+'<-'
  26. print '->2:'+@address2+'<-'
  27. print '->3:'+@address3+'<-'
  28.  
Comment out lines 5,6 and 7 and uncomment line 8 to get the actual data from the table. If you comment out lines 6 and/or 7 only you can check the result of an incomplete address set
Sep 18 '07 #4
iritchie
6 New Member
Here you have a working sample that illustrates the idea. It is possible to do it more intelligently; it is only to show a mindset:
Expand|Select|Wrap|Line Numbers
  1. declare @address varchar(255)
  2. declare @address1 varchar(255), @address2 varchar(255), @address3 varchar(255)
  3. declare @start int, @end int
  4.  
  5. set @address = 'Address Line 1' + char(10)
  6. set @address = @address + 'Address Line 2' + char(10)
  7. set @address = @address + 'Address Line 3' + char(10)
  8. -- select @emplid=emplid, @name=name, @address=@address from empltable
  9.  
  10. set @start = 1
  11.  
  12. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  13. set @address1 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  14. set @start = @end+1
  15.  
  16. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  17. set @address2 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  18. set @start = @end+1
  19.  
  20. set @end = case when charindex(char(10),@address,@start)>0 then charindex(char(10),@address,@start) else len(@address) end
  21. set @address3 = case when @end-@start>=0 then substring(@address, @start, @end-@start) else null end
  22. set @start = @end+1
  23.  
  24. print @address
  25. print '->1:'+@address1+'<-'
  26. print '->2:'+@address2+'<-'
  27. print '->3:'+@address3+'<-'
  28.  
Comment out lines 5,6 and 7 and uncomment line 8 to get the actual data from the table. If you comment out lines 6 and/or 7 only you can check the result of an incomplete address set


Thanks a lot for that!
It only seems to work for one record though, and only returns NULL for all values?
I tried to put the CR position into an array as well, but am I right in saying you can't set an array to be a table value?
Sep 19 '07 #5
azimmer
200 Recognized Expert New Member
Thanks a lot for that!
It only seems to work for one record though, and only returns NULL for all values?
I tried to put the CR position into an array as well, but am I right in saying you can't set an array to be a table value?
The example works for one record. You either put the whole story into a function and apply that to each row (in a SELECT) or define a cursor and process each row in a cycle.
Sep 19 '07 #6
azimmer
200 Recognized Expert New Member
The example works for one record. You either put the whole story into a function and apply that to each row (in a SELECT) or define a cursor and process each row in a cycle.
I don't know if you still follow this thread but here you have a function you can use:
Expand|Select|Wrap|Line Numbers
  1. create function nth_substring(@string varchar(255), @n int)
  2. returns varchar(255)
  3. as
  4. begin
  5. declare @start int, @end int, @section int
  6.  
  7. set @start = 1
  8. set @section = 1
  9. while (@start > 0) and (@section<@n)
  10.     begin
  11.         set @start=charindex(char(10),@string,@start)
  12.         if (@start > 0)
  13.             begin
  14.                 set @section=@section+1
  15.                 set @start=@start+1
  16.             end
  17.     end
  18. if (@section=@n)
  19.     begin
  20.         set @end=charindex(char(10),@string,@start)
  21.         if (@end=0)
  22.             set @end=len(@string)+1
  23.         return substring(@string,@start,@end-@start)
  24.     end
  25.  
  26. return NULL
  27. end
  28. go
  29.  
Use it like this:
Expand|Select|Wrap|Line Numbers
  1. declare @s varchar(255)
  2.  
  3. set @s='Line1'
  4. set @s=@s+char(10)+'Line2'
  5. set @s=@s+char(10)+'Line3'
  6.  
  7. print dbo.nth_substring(@s,2)
  8.  
or like this:
Expand|Select|Wrap|Line Numbers
  1. SELECT ..., dbo.nth_substring(address,1), dbo.nth_substring(address,2), dbo.nth_substring(address,3) 
  2. FROM ...
  3.  
Sep 19 '07 #7
iritchie
6 New Member
I don't know if you still follow this thread but here you have a function you can use:
Expand|Select|Wrap|Line Numbers
  1. create function nth_substring(@string varchar(255), @n int)
  2. returns varchar(255)
  3. as
  4. begin
  5. declare @start int, @end int, @section int
  6.  
  7. set @start = 1
  8. set @section = 1
  9. while (@start > 0) and (@section<@n)
  10.     begin
  11.         set @start=charindex(char(10),@string,@start)
  12.         if (@start > 0)
  13.             begin
  14.                 set @section=@section+1
  15.                 set @start=@start+1
  16.             end
  17.     end
  18. if (@section=@n)
  19.     begin
  20.         set @end=charindex(char(10),@string,@start)
  21.         if (@end=0)
  22.             set @end=len(@string)+1
  23.         return substring(@string,@start,@end-@start)
  24.     end
  25.  
  26. return NULL
  27. end
  28. go
  29.  
Use it like this:
Expand|Select|Wrap|Line Numbers
  1. declare @s varchar(255)
  2.  
  3. set @s='Line1'
  4. set @s=@s+char(10)+'Line2'
  5. set @s=@s+char(10)+'Line3'
  6.  
  7. print dbo.nth_substring(@s,2)
  8.  
or like this:
Expand|Select|Wrap|Line Numbers
  1. SELECT ..., dbo.nth_substring(address,1), dbo.nth_substring(address,2), dbo.nth_substring(address,3) 
  2. FROM ...
  3.  

Awesome!
Thanks a lot azimmer! :)

I was going to go for the method of adding in CR's in the end, but this works great.

Much appreciated.
Sep 20 '07 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

5
41585
by: M Wells | last post by:
Hi All, Just wondering if it's any more efficient to use the following SQL statement to return a partial match from a column as opposed to the second statement. SELECT * FROM Table1 WHERE CHARINDEX('value', mycol) > 0 Versus:
2
8640
by: Little PussyCat | last post by:
Hello, I need to be able to replace only the first occurance of a space character in a column. Reason being is the data in the column I am trying to replace seems to have umpteen space characters after each entry, so a simple replace function will replace all the spaces after it with what I want! I have thought of RTRIM to get rid of the spaces after and then replace, I have also thought of CHARINDEX to find the first occurance of a...
5
42051
by: Willem | last post by:
Hello I am quite hopeless and of course a newbe. The situation: Sql2k / query I would like it ot break down the following string: 2004 Inventory:Ex.Plant Farm1:1st Cut:Premium:0094
3
6016
by: csomberg | last post by:
SQL Server 2000 Ya know, it is always the simplest stuff that gets ya !! I am having the hardest time getting a simple piece of code working. Must be brain dead today. Goal: Get the users full name from a string Here is sample data:
0
2276
by: prav78 | last post by:
hi there i have a field name(fil_srt_cond) with the values of cmpnt_name,ASC,1,2 cmpnt_stuff,DESC,2,3 i used the char index:- substring(BSSF.fil_srt_cond,charindex(BS.column_name,BSSF.fil_srt_cond) + LEN(BS.column_name) +1 ,3) ord,
1
3703
by: db55 | last post by:
This script doesn't work. Why? UPDATE SET = LTRIM(SUBSTRING(, 1, convert(bigint, CHARINDEX(',', Comments)-1))) WHERE NOT( IS NULL) AND LEN() > 8 Basically, I'm trying to move everything before a comma into and everything after the comma into . The comments 2 script works. See below.
0
1574
by: Laura-Jayne | last post by:
Join Date: May 2006 Posts: 6 Help - SQL Query Anaylzer -------------------------------------------------------------------------------- Hi I am using the following code to give me everything after a space in a field: DECLARE @NM CHAR(30)
2
3013
by: matthewwhaley | last post by:
What is the best way to essentially use the charindex(find) function if the value is could be more than one variable (A or B or C) I can't seem to get an "or", "if" or "select if" to work Below is the code that works, I need 'GOV' to be either 'GOV' or 'FWD' or 'LIB' sqlstring = "SELECT Distinct substring(," _
1
6191
by: jeremy | last post by:
Hello, I was hoping someone could help me with this SQL statement. The column 'options.optionDescrip' is a varchar field. Some values of the 'options.optionDescrip' contain commas, some do not. We are trying to evaluate against any data in the
0
9983
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11168
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
11348
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10693
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7431
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6117
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4947
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4539
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3543
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.