Wednesday 18 November 2015

Split string using multiple delimiters in SQL SERVER


Many times we are Using split function in SQL SERVER for split a string using some delimiters

Example:

If we have a string like  '10:0,11:1,12:3,13:4,15:5,16:6'

And we need to split the string using comma delimiter then usually we will use some split functions

Example :

CREATE FUNCTION dbo.SplitFunction(@String varchar(8000), @Delimiter char(1))        
returns @temptable TABLE (items varchar(8000))        
as        
begin        
 declare @idx int        
 declare @slice varchar(8000)        
       
 select @idx = 1        
  if len(@String)<1 or @String is null  return        
       
 while @idx!= 0        
 begin        
  set @idx = charindex(@Delimiter,@String)        
  if @idx!=0        
   set @slice = left(@String,@idx - 1)        
  else        
   set @slice = @String        
     
  if(len(@slice)>0)   
   insert into @temptable(Items) values(@slice)        
   
  set @String = right(@String,len(@String) - @idx)        
  if len(@String) = 0 break        
 end    
return        
end   
   

Then we can call this function like

select items from dbo.SplitFunction('10:0,11:1,12:3,13:4,15:5,16:6',',')

Output :

Items
------
10
0,11
1,12
3,13
4,15
5,16
6

This is normally we all have done
But here we want to split a string using multiple delimiters
Example in our above string we want to split using “comma” and “semicolon”
We can see how we can do that.

Method 1:

This is one of the simplest methods. Use the below function it will do the task
CREATE FUNCTION dbo.MultipleDelemiterSplit
(
   @List       NVARCHAR(MAX),
   @Delemiter1 Varchar(100),
   @Delemiter2 Varchar(100)
)
RETURNS  TABLE
AS

   RETURN
   ( 
      SELECT Item = FirstSet.cnt.value('(./text())[1]', 'nvarchar(4000)')
      FROM
      (
        SELECT x = CONVERT(XML, '<cnt>'
          + REPLACE(REPLACE(@List, ISNULL(@Delemiter1,''), '</cnt><cnt>') , ISNULL(@Delemiter2,''), '</cnt><cnt>')
          + '</cnt>').query('.')
      ) AS a CROSS APPLY x.nodes('cnt') AS FirstSet(cnt)
   );

GO 

Select * From dbo.MultipleDelemiterSplit ('10:0,11:1,12:3,13:4,15:5,16:6',',',':')

OutPut:
Item
------
10
0
11
1
12
3
13
4
15
5
16
6

Method 2:

We can use REPLACE function
select REPLACE('10:0,11:1,12:3,13:4,15:5,16:6',':',',')
It will replace all occurance of semicolon with a comma,after replacing we can use normal split function for splitting
Example :

select items from dbo. SplitFunction (REPLACE('10:0,11:1,12:3,13:4,15:5,16:6',':',','),',') This will also give the same result.
Method 3:

We can use CROSS APPLY for doing the same

SELECT e.items from dbo. SplitFunction ('10:0,11:1,12:3,13:4,15:5,16:6',',') d
CROSS APPLY dbo. SplitFunction (d.items,':') e
This will also give the expected output.

Method 4  : 

Generalized approach for N number of delimiters

alter FUNCTION dbo.MultipleDelemiterSplit
(
   @List       NVARCHAR(MAX)
 
)
RETURNS  TABLE
AS

   RETURN
   (

      SELECT Item = FirstSet.cnt.value('(./text())[1]', 'nvarchar(4000)')
      FROM
      (
        SELECT x = CONVERT(XML, '<cnt>'
          + @List
          + '</cnt>').query('.')
      ) AS a CROSS APPLY x.nodes('cnt') AS FirstSet(cnt)
   );

GO
-----------------------------

DECLARE @yourDelimiterString VARCHAR(1000)
DECLARE @teststring VARCHAR(1000)

SET @yourDelimiterString = '_(){}.-+-'
SET @teststring = 'test(arun)need.to{remove}all+unwanted-'

;WITH CTE AS
(
  SELECT SUBSTRING(@yourDelimiterString, 1, 1) AS [String], 1 AS [Start], 1 AS [Counter]
  UNION ALL
  SELECT SUBSTRING(@yourDelimiterString, [Start] + 1, 1) AS [String], [Start] + 1, [Counter] + 1 
  FROM CTE 
  WHERE [Counter] < LEN(@yourDelimiterString)
)

SELECT @teststring = REPLACE(@teststring, CTE.[String], '</cnt><cnt>') FROM CTE
if right(@teststring,11) = '</cnt><cnt>'  
set @teststring=(select substring(@teststring, 1, (len(@teststring) - 11)))
if left(@teststring,11) = '</cnt><cnt>' 
set @teststring=Stuff(@teststring, 1, 11, '')
select * from dbo.MultipleDelemiterSplit(@teststring)

Output 
---------
item
----
test
arun
need
to
remove
all
unwanted







Tuesday 17 November 2015

VARCHAR Vs NVARCHAR

Before Going for nvarchar and varchar we have to think about unicode ,non-unicode and ascii character set.

Unicode Character

Unicode's character set includes ALL human language's and written symbols.they are defined in unicode character table.

Non Unicode Character

a non unicode character is most probably a character or symbol mainly used in European countrys , simple example is English characters

ascii

There is a set of characters that are common in most generally used non-Unicode character sets and code pages. These characters are known as the ASCII characters. They include the common characters used in the English language and they occupy the first 128 code points (Hex 00-9F) in the non-Unicode code pages.

Point :
·         simply ascii is a subset of unicode
·        varchar only store non unicode characters while nvarchar can store Unicode character too


In the below example the chinese characters are unicode characters so they can  store only using nvarchar , varchar does not support those .

select '奥曼克' as testingone

Output :

testingone
------------
???
select N'奥曼克' as testingtwo

Output:

testingtwo
------------

奥曼克
declare  @test1 varchar(10) =N'奥曼克'
declare  @test2 nvarchar(10) =N'奥曼克'
declare  @test3 nvarchar(10) ='奥曼克'

select @test1

Output :
???
select @test2
Output:

奥曼克
select @test3

Output:
 ???
  • N actually stands for National language character set
  • N used for representing unicode characters.
  • N tells to sql server  the data is unicode data and it is not a character data 


A little more information about varchar and nvarchar

select DATALENGTH(@test1) as data

Output 3 (varchar only occupy 1 byte for each character)
select DATALENGTH(@test2) as data
Output 6 (varchar only occupy 2 byte for each character)

so the maximum userdefined size for varchar will be 8000 and nvarchar will be 4000
declare @a nvarchar(4001)
will give error(maximum limit is 4000 characters)

declare @aa varchar(4001) this will  works fine

Generate column values as comma separated in SQL SERVER

 Method 1: Using XML PATH.


We can take an example table for this :

Table name is : CommaSeperatedExampleTbl


Id         name                            age
-----------------------------------------------------
1          Arun                             24
2          Jijo                               25
3          Prasanth                       26
4          Nikhil                            26
5          Hareesh                        20
8          Santhosh                      24
10         Achu                            22

Now we are going to make the second column of the above table as comma separated using XML PATH


SELECT Stuff(
  (SELECT N', ' + cast (name as nvarchar ) FROM
                  CommaSeperatedExampleTbl
                   as a FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'')as Name

It will results :

Name
-----------
Arun, Jijo, Prasanth, Nikhil, Hareesh, Santhosh, Achu


Method  2: Using coalesce

DECLARE @str nVARCHAR(MAX) 
select @str=  coalesce(@str + ',', '') + CAST(a.name AS nVARCHAR)
FROM CommaSeperatedExampleTbl a
select @str as Name

The result will be :

Name
-----------

Arun,Jijo,Prasanth,Nikhil,Hareesh,Santhosh,Achu

Monday 16 November 2015

Remove unwanted space between words in a string In SQL SERVER


Many times we are faced lot of difficulties with unwanted space between words, it is easy to remove these types of unwanted spaces in a string using JavaScript or jquery or any server side languages

But here we are discussing about how we can do it in SQL Server


The  simplest solution is given below


DECLARE @example nvarchar(100)
SET @example= '   Secrets   of     programming   '

SELECT  REPLACE(REPLACE(REPLACE(@example,' ','<>'),'><',''),'<>',' ')as [Result]


The above query will result the string like below with out no unwanted spaces between words


Result
---------------------------------
Secrets of programming

Custom Sorting in SQL SERVER

Today we are discussing about custom sorting in SQL SERVER

First of all we can create a simple table:

CREATE TABLE CustSortExampleTbl
(
id int primary key
,Name nvarchar(100)
,age int
)

Now we can enter some sample values to our table

insert into CustSortExampleTbl values(1,'Arun',24)
insert into CustSortExampleTbl values(2,'Jijo',25)
insert into CustSortExampleTbl values(3,'Prasanth',26)
insert into CustSortExampleTbl values(5,'Hareesh',20)
insert into CustSortExampleTbl values(4,'Nikhil',26)
insert into CustSortExampleTbl values(10,'Achu',22)
insert into CustSortExampleTbl values(8,'Santhosh',24)

Now our table values look like below
Id    name        age
------------------------------------
1     Arun            24
2     Jijo              25
3     Prasanth      26
4     Nikhil           26
5     Hareesh       20
8     Santhosh      24
10    Achu           22

If we need to sort the details based on id then we simply do

1)Select * from CustSortExampleTbl order by id desc

Or

2)Select * from CustSortExampleTbl order by id asc

First query will sort the details in descending order and the Second query will sort it in ascending order .This is the most commonly sorting we are used, also we used some sorting using case we can look on that too .


Example :
Select * from CustSortExampleTbl order by (case when id=5 then null else id end)

The above query will results data like below

id    Name        age
-------------------------
5     Hareesh     20
1     Arun          24
2     Jijo            25
3     Prasanth    26
4     Nikhil         26
8     Santhosh    24
10    Achu         22

The interesting this now we want to sort the details in some custom order, that is we define the order and we need to sort the data in that order.

Example :

Id    name        age
----------------------
3     Prasanth    26
4     Nikhil         26
10    Achu         22
5     Hareesh     20
1     Arun          24
2     Jijo            25
8     Santhosh   24

Look at the above result I need to sort the data like above
That is in a custom id order like : 3,4,10,5,1,2,8

How can we do this ??

Very simple look at the following query

SELECT *
FROM CustSortExampleTbl Cst
WHERE id IN (3,4,10,5,1,2,8)
ORDER BY CHARINDEX(','+CONVERT(varchar, Cst.id)+',', ',3,4,10,5,1,2,8,')

Result :

id    Name        age
---------------------------
3     Prasanth    26
4     Nikhil         26
10    Achu         22
5     Hareesh     20
1     Arun          24
2     Jijo            25
8     Santhosh    24