July 24, 2003 at 7:15 am
I have a table that has fields 'ColPosition'(int) and 'ColName'(char200) and a 'Jobid'(int). I will not know how many 'ColPosition' there are. From this I would like to create a table with as many fields as there are ColPositions for a particular Jobid, then parse the ColName and insert it into the ColPosition field. My hang up is in creating a table with an unknown amount of fields. Here is what I currently have for code. Any help would be appreciated. Thanks!
create proc Weblayout
@jobid int
as
declare @colnames as varchar(1000)
declare @firstloop as int
declare @secondloop as int
declare @splitstring as varchar(200)
declare @counter as int
drop table Webtable
create table Webtable
(
colname VARCHAR(1000)
)
set @counter = 1
set @firstloop = 'select max(ColPosition) from frtabledef where jobid ='& @jobid
while @firstloop > 0
begin
set @splitstring = 'select colname from frtabledef where jobid ='& @jobid & ' and colposition ='& @counter
--select dbo.ufn_parsestring('Recall 1 | Total Completes | Rotation A 431 1st/825 2nd'
insert into Webtable(colname) values (dbo.ufn_parsestring(@splitstring,'|',@counter))
set @counter = @counter + 1
end
select * from WebTable
July 24, 2003 at 7:29 am
Hi RKS,
quote:
I have a table that has fields 'ColPosition'(int) and 'ColName'(char200) and a 'Jobid'(int). I will not know how many 'ColPosition' there are. From this I would like to create a table with as many fields as there are ColPositions for a particular Jobid, then parse the ColName and insert it into the ColPosition field. My hang up is in creating a table with an unknown amount of fields. Here is what I currently have for code. Any help would be appreciated. Thanks!create proc Weblayout
@jobid int
as
declare @colnames as varchar(1000)
declare @firstloop as int
declare @secondloop as int
declare @splitstring as varchar(200)
declare @counter as int
drop table Webtable
create table Webtable
(
colname VARCHAR(1000)
)
set @counter = 1
set @firstloop = 'select max(ColPosition) from frtabledef where jobid ='& @jobid
while @firstloop > 0
begin
set @splitstring = 'select colname from frtabledef where jobid ='& @jobid & ' and colposition ='& @counter
--select dbo.ufn_parsestring('Recall 1 | Total Completes | Rotation A 431 1st/825 2nd'
insert into Webtable(colname) values (dbo.ufn_parsestring(@splitstring,'|',@counter))
set @counter = @counter + 1
end
select * from WebTable
maybe I am missing something, but webtable has only one field!
What about making your CREATE TABLE statement dynamic like this?
SET @stmt = N'CREATE TABLE ' + @tname +
..and then loop through your string?
EXEC sp_executeSQL @stmt
Is this going your direction?
Cheers,
Frank
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
July 24, 2003 at 7:59 am
Thanks Frank. I think you've got it but let me make sure. You're saying create the 'Create Table' statement dynamically by adding a field, (@tname) to the 'Create Table' statement during my loop then execute (@stmt) it at the end? I'm fairly new to SQL and still figuring out the syntax, what does the N in N'Create Table' do? And would I have to add the '(' after CREATE TABLE and ')' to the end of @stmt right before executing?
Thanks,
Richard.
July 24, 2003 at 8:39 am
Hi Richard,
quote:
Thanks Frank. I think you've got it but let me make sure. You're saying create the 'Create Table' statement dynamically by adding a field, (@tname) to the 'Create Table' statement during my loop then execute (@stmt) it at the end?
well, the code I took it from looks like this
CREATE PROCEDURE blabl @tname nvarchar(50) AS
DECLARE @stmt nvarchar(whatever)
SET @stmt = N'CREATE TABLE ' + @tname +
' ( [id] [int] IDENTITY (1, 1) NOT NULL,[image] NULL ,
[filename] [varchar] (50) NULL ,
[description] [varchar] (100) NULL ,
[sender] [varchar] (50) NULL)
ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]'
EXEC sp_executeSQL @stmt
in your case, you will have to loop through your string, plug in the return value from your function like
DECLARE @stmt nvarchar(4000)
DECLARE @retVal1 varchar(50), @retVal2 varchar(50)
DECLARE @a int
SET @retVal1='1'
SET @retVal2='1'
SET @stmt = N'CREATE TABLE MyTable ( '
SET @a=0
WHILE (@a<10)
BEGIN
SET @stmt = @stmt + '
[' +@retVal1 +'] [int] NULL,
[' +@retVal2 +'] [int] NULL)'
SET @a=@a+1
END
PRINT @stmt
till the WHILE condition is met.
Then execute the string
quote:
I'm fairly new to SQL and still figuring out the syntax, what does the N in N'Create Table' do?
actually it ensures the use of unicode characters. I guess not really needed, but I stick to it, because my first dynamic SQL statement I've built this way.
quote:
And would I have to add the '(' after CREATE TABLE and ')' to the end of @stmt right before executing?
yes, it will not work without.
HTH
Cheers,
Frank
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
July 24, 2003 at 9:01 am
You are on the right track with Frank's reply. Just wanted to point out to watch out for the ampersands in your original procedure. The concatenation operator in SQL is the "+", not the "&". It's a common mistake if you're coming from Access to SQL Server. The "&" operator is the bitwise AND operator in SQL Server, something I'm pretty sure you didn't intend 🙂
July 25, 2003 at 8:02 am
Is this what you want
declare @max int
declare @ct int
declare @sql nvarchar(4000)
select @max = max(ColPosition)
from frtabledef
where jobid = @jobid
create table #newtable (Jobid int)
set @ct=0
while (@ct < @max)
begin
set @ct=@ct+1
set @sql = 'alter table #newtable add Col'+
cast(@ct as varchar)+
' varchar(20) null'
exec sp_executesql @sql
end
insert into #newtable (Jobid) values (@Jobid)
set @ct=0
while (@ct < @max)
begin
set @ct=@ct+1
set @sql = 'update a set a.Col'+
cast(@ct as varchar)+
' = dbo.ufn_parsestring(b.ColName,''|'','+
cast(@ct as varchar)+
')) from #newtable a inner join frtabledef b on b.Jobid = a.jobid and b.ColPosition = '+
cast(@ct as varchar)+
' where a.Jobid = '+
cast(@Jobid as varchar)
exec sp_executesql @sql
end
select * from #newtable
Sorry Frank, is that better.
Edited by - davidburrows on 07/28/2003 06:55:23 AM
Far away is close at hand in the images of elsewhere.
Anon.
July 25, 2003 at 8:07 am
quote:
declare @max int
declare @ct int
declare @sql nvarchar(4000)
select @max = max(ColPosition) from frtabledef where jobid = @jobid
create table #newtable (Jobid int)
set @ct=0
while (@ct < @max)
begin
set @ct=@ct+1
set @sql = 'alter table #newtable add Col'+cast(@ct as varchar)+' varchar(20) null'
exec sp_executesql @sql
end
insert into #newtable (Jobid) values (@Jobid)
set @ct=0
while (@ct < @max)
begin
set @ct=@ct+1
set @sql = 'update a set a.Col'+cast(@ct as varchar)+' = dbo.ufn_parsestring(b.ColName,''|'','+cast(@ct as varchar)+')) from #newtable a inner join frtabledef b on b.Jobid = a.jobid and b.ColPosition = '+cast(@ct as varchar)+' where a.Jobid = '+cast(@Jobid as varchar)
exec sp_executesql @sql
end
select * from #newtable
what I really hate in this forum software is the missing automatic line wrap.
It's not very read-friendly !
Cheers,
Frank
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
July 28, 2003 at 6:56 am
Sorry Frank, is that better.
Far away is close at hand in the images of elsewhere.
Anon.
July 28, 2003 at 7:02 am
quote:
Sorry Frank, is that better.
Hi David,
that's an inherent error in the forum software, it wasn't your post
But to answer I had to scroll vertical again
Cheers,
Frank
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
July 30, 2003 at 1:06 pm
Thanks Frank and Dave. Sorry for the delay, I got pulled into something else. I was able to get to where I needed to go from your input. Here's what I came up with.
CREATE procedure FTW
@jobid int
as
declare @max int
declare @maxouter int
declare @ct int
declare @gl int
declare @sql nvarchar(4000)
declare @pstring nvarchar(255)
--get max # of columns and create table with that many columns
select @max = max(ColPosition) from frtabledef where jobid = @jobid
create table #newtable (RowNum int identity (1,1) primary key, Jobid varchar(50))
set @ct=0
while (@ct < @max)
begin
set @ct=@ct+1
set @sql = 'alter table #newtable add Col'+
cast(@ct as varchar)+
' varchar(255) null'
exec sp_executesql @sql
end
--begin outer loop for amount of rows
set @maxouter = (select GroupLevels from frtableinfo where jobid = @jobid)
set @gl =0
while (@gl < @maxouter)
begin
set @gl=@gl+1
insert into #newtable (Jobid) values (@Jobid)
set @ct=0
--begin inner loop to populate columns
while (@ct < @max)
begin
set @ct=@ct+1
set @pstring = dbo.ufn_parsestring((select ColName from frtabledef where jobid = @jobid and ColPosition = @ct),'|',@gl)
--print @pstring
set @sql = 'update a set a.Col'+
cast(@ct as varchar)+
' = '''+@pstring+
''' from #newtable a inner join frtabledef b on b.Jobid = a.jobid and b.ColPosition = '+
cast(@ct as varchar)+
' where a.Jobid = '+
cast(@Jobid as varchar)+' and a.RowNum = '+cast(@gl as varchar)
exec sp_executesql @sql
--print @sql
end
end
select * from #newtable
GO
and here's the function I used to parse the string.
CREATE function ufn_parsestring (
@string nvarchar(255),
@delimiter nchar(1),
@value int)
returns nvarchar(255)
as
begin
declare @index int
declare @charpos int
declare @startpos int
set @index = 0
set @charpos = 1
set @startpos = 0
set @string = @string + @delimiter
while @index < @value - 1 and @charpos <= len(@string)
begin
set @charpos = @charpos + 1
if substring(@string,@charpos,1) = @delimiter
begin
set @index = @index + 1
end
end
if @charpos > len(@string)
begin
return NULL
end
if @value = 1
set @startpos = -1
else
set @startpos = @charpos + 1
set @charpos = @startpos
while substring(@string,@charpos,1) <> @delimiter and @charpos <= len(@string)
begin
set @charpos = @charpos + 1
end
if @charpos > len(@string)
begin
return NULL
end
return ltrim(substring(@string,@startpos,(@charpos) - @startpos))
end
Thanks again,
Richard.
Viewing 10 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply