It occurs to me that a lot of the examples are for cross tab queries involving aggregation, which yours does not appear to need. While I do not necessarily condone Dynamic SQL, the below should give you the results you want.
Create table #Contacts (id int)
Declare @ContactTypes int
Declare @CAD varchar(100)
Declare @I int
Declare @sql nvarchar(4000)
Set @i = 1
Select @ContactTypes =
Sum(sub.Types)
from ( Select Count(1) as Types from contacts
group by ContactName, Designation) as sub
Print @ContactTypes
While @i <= @ContactTypes
Begin
set @sql = 'alter table #Contacts Add ContactName' +
Cast(@I as varchar(10)) + ' varchar(100)'
exec sp_executesql @sql
Set @I = @i + 1
End
Insert into #Contacts (id) values (1)
Set @i = 1
Declare crsPivot cursor
for Select ContactName + ' ' + Designation
from contacts
open crsPivot
Fetch next from crsPivot into @CAD
While (@@Fetch_Status = 0)
Begin
Set @sql = 'Update #Contacts set ContactName'
+ Cast(@I as varchar(10)) +' = ' + quotename(@CAD,'''')
exec sp_executesql @sql
Set @i = @i + 1
Fetch next from crsPivot into @CAD
End
close crsPivot
Deallocate crsPivot
select * From #Contacts