Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 SQL Split or Like ? Stuck for hours , help !!!

Author  Topic 

sushant17284
Starting Member

12 Posts

Posted - 2010-04-15 : 15:34:01
Guys , I am facing a small problem to which I just can't seem to find any solution.I am stuck for the last 2 days please help.
Here is the scenario.
I have a user table which has 3 columns : id,name and email.
Now I have an SP in which another SP is called which returns a name of the user on the basis of some criteria.My problem is to find the email ID of that User.
I used this following SQL which is very simple.
Select email from User where name=@EMP_NAME
Here @EMP_NAME is the name returned by the stored proc which is being called within the stored proc which finds this email Id.This works perfectly fine when @EMP_NAME returns only one name like "John,Powell"
Till now everything is fine.The problem happened when my client changed their Stored Proc to return multiple names in the @EMP_NAME separated with a delimiter.
Now I get the value of @EMP_NAME as "John ,Powell / Gary, Mak "
Note that the actual delimiter is "/". Commas are already inserted in the name field.
Now since I get multiple names here , my existing select query fails and return null because there is no name with that value of @EMP_NAME.

I would like anyone of you to help me on how to resolve this.Now I want to retrieve the email id of both the name within the @EMP_NAME.How is it possible ??
The other condition is I can't change client's SP in anyway, So would have to deal with it within my SP.
I don;t know I am stuck I tried using Like as well as split but no luck.I don't want to hardcode the splitted names as well because there can be more than two names also in the @EMP_NAME field in the future.
PLEASE HELP ME !!!!!!!!!!! You guys have always helped me out.I will really appreciate your help.
It looks like it should be a small modification in the query but I just can't seem to get it done. :(
Btw , I am using MS SQL server

malpashaa
Constraint Violating Yak Guru

264 Posts

Posted - 2010-04-15 : 15:55:24
SELECT email
FROM User
WHERE CHARINDEX(name, @EMP_NAME) > 0;
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2010-04-15 : 16:42:14
1st of all, BAD BAD client! I feel your pain.
you can loop each name or you can generate a nvarchar statement string and use sqlexecute to run it.

declare @SQLSTRING NVARCHAR(MAX);
set @EMP_NAME = ''''+replace(ltrim(rtrim(@EMP_NAME)),' / ',''',''')+'''';
SET @SQLSTRING = N'SELECT EMAIL FROM YOURTABLE WHERE NAME IN ('+@SQLSTRING+')';
EXECUTE SP_EXECUTESQL @SQLSTRING;



quote:
Originally posted by sushant17284

Guys , I am facing a small problem to which I just can't seem to find any solution.I am stuck for the last 2 days please help.
Here is the scenario.
I have a user table which has 3 columns : id,name and email.
Now I have an SP in which another SP is called which returns a name of the user on the basis of some criteria.My problem is to find the email ID of that User.
I used this following SQL which is very simple.
Select email from User where name=@EMP_NAME
Here @EMP_NAME is the name returned by the stored proc which is being called within the stored proc which finds this email Id.This works perfectly fine when @EMP_NAME returns only one name like "John,Powell"
Till now everything is fine.The problem happened when my client changed their Stored Proc to return multiple names in the @EMP_NAME separated with a delimiter.
Now I get the value of @EMP_NAME as "John ,Powell / Gary, Mak "
Note that the actual delimiter is "/". Commas are already inserted in the name field.
Now since I get multiple names here , my existing select query fails and return null because there is no name with that value of @EMP_NAME.

I would like anyone of you to help me on how to resolve this.Now I want to retrieve the email id of both the name within the @EMP_NAME.How is it possible ??
The other condition is I can't change client's SP in anyway, So would have to deal with it within my SP.
I don;t know I am stuck I tried using Like as well as split but no luck.I don't want to hardcode the splitted names as well because there can be more than two names also in the @EMP_NAME field in the future.
PLEASE HELP ME !!!!!!!!!!! You guys have always helped me out.I will really appreciate your help.
It looks like it should be a small modification in the query but I just can't seem to get it done. :(
Btw , I am using MS SQL server

Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2010-04-15 : 16:52:04
Check out this set of articles about using Arrays in SQL:
http://www.sommarskog.se/arrays-in-sql.html

This should help guide you to using a Split/Parse function to do what you need.

If the data is stored as "John ,Powell" then you probably have bigger issues. However, the first response above will not be able to use an index do to the use of a function. The second response uses dynamic sql, which I'd be shy to use unless you use the sp_executesql stored procedure to help prevent malicious code from executing. But moreover, I'd suggest using a Split/Parse fucntion and avoid dynamic SQL altogether.

Go to Top of Page

malpashaa
Constraint Violating Yak Guru

264 Posts

Posted - 2010-04-15 : 17:38:39
quote:
Originally posted by Lamprey

the first response above will not be able to use an index do to the use of a function


You need to revise your informations regarding index usage when functions used, because not all functions prevent index usage, and in this specific case the optimizer will be able use the index if it exists.
Go to Top of Page

DBA in the making
Aged Yak Warrior

638 Posts

Posted - 2010-04-15 : 17:44:35
See if you can get your hands on the original sp that returned a single name, and inline it into your own sp, or add it back to the database under a different name.

------------------------------------------------------------------------------------
Any and all code contained within this post comes with a 100% money back guarantee.
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2010-04-15 : 18:03:05
quote:
Originally posted by malpashaa

quote:
Originally posted by Lamprey

the first response above will not be able to use an index do to the use of a function


You need to revise your informations regarding index usage when functions used, because not all functions prevent index usage, and in this specific case the optimizer will be able use the index if it exists.

You are correct, it might use an index by scanning the index. But, I'm not sure that is very effecient when it can be written as a seek.
Go to Top of Page

sushant17284
Starting Member

12 Posts

Posted - 2010-04-16 : 01:33:54
First of All, I would like to thank all of you for giving me so many ideas to resolve this problem.I really appreciate and would like to thank all of you with warm regards.I was able to try all of the ways mentioned here in the post.And thankfully hanbingl reply sorted it out for me.I am so happy......thanks to sql team and effort of all you guys who made your contributions.It makes me believe in this forum more than ever before.
Now I am able to get the email like the following query :
declare @SQLSTRING NVARCHAR(MAX);
set @EMP_NAME = ''''+replace(ltrim(rtrim(@EMP_NAME)),' / ',''',''')+'''';
SET @SQLSTRING = N'SELECT EMAIL FROM YOURTABLE WHERE NAME IN ('+@SQLSTRING+')';
EXECUTE SP_EXECUTESQL @SQLSTRING;


However there was a small problem with the query and that was that I had to change the SET @SQLSTRING line where name in ('+@SQLSTRING+')' to ('+@EMP_NAME+')'.

This is the final result.

email
------------
johnp@company.com
garym@company.com

IT WORKS !!!!!!!!! WOW
Now the only problem is how to get the email field as merged into one.
I know I keep going round in circles.First I wanted to split the names to get the email and now I have to merge the emails back into one field with ";"(semicolon as delimiter)

Can anyone tell me how to merge this email field into one row and not multiple rows ?
Thanks alot to all of you once again.
Cheers,
Sushant

quote:
Originally posted by hanbingl

1st of all, BAD BAD client! I feel your pain.
you can loop each name or you can generate a nvarchar statement string and use sqlexecute to run it.

declare @SQLSTRING NVARCHAR(MAX);
set @EMP_NAME = ''''+replace(ltrim(rtrim(@EMP_NAME)),' / ',''',''')+'''';
SET @SQLSTRING = N'SELECT EMAIL FROM YOURTABLE WHERE NAME IN ('+@SQLSTRING+')';
EXECUTE SP_EXECUTESQL @SQLSTRING;



quote:
Originally posted by sushant17284

Guys , I am facing a small problem to which I just can't seem to find any solution.I am stuck for the last 2 days please help.
Here is the scenario.
I have a user table which has 3 columns : id,name and email.
Now I have an SP in which another SP is called which returns a name of the user on the basis of some criteria.My problem is to find the email ID of that User.
I used this following SQL which is very simple.
Select email from User where name=@EMP_NAME
Here @EMP_NAME is the name returned by the stored proc which is being called within the stored proc which finds this email Id.This works perfectly fine when @EMP_NAME returns only one name like "John,Powell"
Till now everything is fine.The problem happened when my client changed their Stored Proc to return multiple names in the @EMP_NAME separated with a delimiter.
Now I get the value of @EMP_NAME as "John ,Powell / Gary, Mak "
Note that the actual delimiter is "/". Commas are already inserted in the name field.
Now since I get multiple names here , my existing select query fails and return null because there is no name with that value of @EMP_NAME.

I would like anyone of you to help me on how to resolve this.Now I want to retrieve the email id of both the name within the @EMP_NAME.How is it possible ??
The other condition is I can't change client's SP in anyway, So would have to deal with it within my SP.
I don;t know I am stuck I tried using Like as well as split but no luck.I don't want to hardcode the splitted names as well because there can be more than two names also in the @EMP_NAME field in the future.
PLEASE HELP ME !!!!!!!!!!! You guys have always helped me out.I will really appreciate your help.
It looks like it should be a small modification in the query but I just can't seem to get it done. :(
Btw , I am using MS SQL server



Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2010-04-16 : 02:32:31
[code]
declare @SQLSTRING NVARCHAR(MAX);
set @EMP_NAME = ''''+replace(ltrim(rtrim(@EMP_NAME)),' / ',''',''')+'''';
SET @SQLSTRING = N'SELECT EMAIL FROM YOURTABLE WHERE NAME IN ('+@EMP_NAME+')';
EXECUTE SP_EXECUTESQL @SQLSTRING;
[/code]
Surely SQL injection risk there?

Also requires the user to have underlying SELECT permissions on the table, rather than just Sproc execute permission (unless use impersonation ... which is a whole layer of complexity to be added if the O/P does not currently have that)

I don't know how long these lists could be, but if they can be large then IN will be very inefficient.

Best solution in my opinion would be to use a SPLIT function (as Lamprey said) to convert "xxx/yyy/zzz" formatted string into a pseudo table - i.e. a row for each valuye "xxx", "yyy", "zzz" and then JOIN this to the EMAIL table. That would look like this:
[code]
SELECT email
FROM MyTable AS T
JOIN dbo.MySplitFunction(@EMP_NAME, '/') AS S
ON S.SplitValue = T.[name]
[/code]
this will optimally use any index on [NAME] column, and scale well with a large/huge MyTable and large numbers of names in the @EMP_NAME list.

For a cheap-and-cheerful route then:
[code]
SELECT email
FROM MyTable
WHERE '/' + @EMP_NAME + '/' LIKE '%/' + [name] + '/%'
[/code]
this is not very efficient (it will not use any index on [name] column, and thus requires a table scan) but for reasonable numbers of rows in MyTable (say thousands, maybe tens-of-thousands) and reasonable short @EMP_NAME list (say tens, up to a hundred), and if the requests are not too frequent, then performance will probably be acceptable and not put undue strain on other queries/databases on the same server.

This does not have the permissions problems of dynamic SQL, not the SQL injection risk

NOTE: if you delimiter is space padded - i.e. " / " rather than "/" - as per your initial example data, then some alteration is required. The user will have to use the delimiter exactly - either with one space, or not.

For the SPLIT route this won't be necessary as the Split Function can TRIM the values to remove leading/trailing spaces.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2010-04-16 : 02:52:19
Sample data:

DECLARE @EMP_NAME varchar(1000)
SET @EMP_NAME = 'John ,Powell/Gary, Mak/'');PRINT ''''''SQL Injection Attack!!''''''--'


SELECT *
INTO #MyData
FROM
(
SELECT 'John ,Powell' AS [name], 'johnp@company.com' as [email]
UNION ALL SELECT 'Gary, Mak', 'garym@company.com'
UNION ALL SELECT 'Gary, MakXXX', 'garym3@company.com'
UNION ALL SELECT 'Gary, Ma', 'garym2@company.com'
) AS T


PRINT ''
PRINT 'Method 1'
SELECT email
FROM #MyData
WHERE CHARINDEX(name, @EMP_NAME) > 0

PRINT ''
PRINT 'Method 2'
declare @SQLSTRING NVARCHAR(MAX);
set @EMP_NAME = ''''+replace(ltrim(rtrim(@EMP_NAME)),'/',''',''')+'''';
SET @SQLSTRING = N'SELECT EMAIL FROM #MyData WHERE NAME IN ('+@EMP_NAME+')';
EXECUTE SP_EXECUTESQL @SQLSTRING;

PRINT ''
PRINT 'Method 3'
SELECT email
FROM #MyData
WHERE '/' + @EMP_NAME + '/' LIKE '%/' + [name] + '/%'

DROP TABLE #MyData
Go to Top of Page
   

- Advertisement -