分享
 
 
 

直接从SQL语句问题贴子数据建表并生成建表语句的存储过程

王朝mssql·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

下面的存储过程,可帮你在回答SQL语句问题时,直接从贴子的样本数据建表并生成建表语句,省去大量的手工输入数据的工作。

/*Create Table from your web page data

* 2004-JAN-1, OpenVMS,V0.1

* 2004-JAN-2, V0.5, add tab & blank values logical

* 2004-JAN-3, V1.0, add SQL Statement generation

* 2004-JAN-4, V1.1, fix datatype like decimal(4,2) bug

* 2004-JAN-4, V1.2, fix field name bug

*

* Sample Call: in SQL Query Analyzer

exec dbo.create_table '##t2','varchar(20),datetime k','

ID AnDate

99101 2002-11-24 00:00:00.000

99101 2003-11-15 00:00:00.000

99101 2003-11-29 00:00:00.000

99101 2003-12-20 00:00:00.000'

注意:

1 如用临时表名,只能用全局临时表 ##,否则不可访问

2 如果没有列名,则需要在第一行数据手动加上列名

3 字段名称不允许含空格

4 至少一行数据,否则没有意义

5 字段值为空需要写上NULL,字段值中的任何符号作为值的一部分

6 没有对定义类型和值的类型匹配检查

7 可指定值中含有空格,方法为在该类型定义中的尾部加字母 k, 如 datatime k,

8 如过值中含有单引号,需要复写 ' -》''

*/

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'create_table'

AND type = 'P')

DROP PROCEDURE create_table

go

create proc dbo.create_table

@table_name varchar(60),--- Table name

@datatype varchar(1000),--- separated by comma ','

@str nvarchar(3000) --- input string pasted from web page

AS

BEGIN

declare @dt table(id int identity(1,1),fld_name varchar(30),fld_type varchar(20),blank int)

declare @sqlt table(sql_statement varchar(8000))

declare @tmp varchar(1000),@num1 int,@num2 int,@sql nvarchar(4000)

declare @a nvarchar(3000),@i int,@j int,@k int,@m int,@x nvarchar(1000)

SET NOCOUNT ON

if object_id(@table_name) is not null

begin

set @a='TABLE '+@table_name+' exists,choose a new one!'

RAISERROR (@a,16,1)

return

end

--提取类型名

set @datatype=lower(replace(@datatype,' ',''))

set @tmp=@datatype

set @i=1

set @num1=0

while @i>0

begin

select @i=charindex(',',@datatype)

--check datatype like decimal(10,4)

if @i>charindex('(',@datatype) and @i<charindex(')',@datatype)

set @i=charindex(')',@datatype)+1

select @j=charindex('k',@datatype)

set @m=0

if (@j>1 and @j<@i) or (@i=0 and @j=len(@datatype)) set @m=-1

if @i>1

begin

insert into @dt(fld_type,blank)

values(left(@datatype,@i-1+@m),case when @m=-1 then 1 else 0 end)

select @datatype=right(@datatype,len(@datatype)-@i)

end

if @i=0 and len(@datatype)>0

insert into @dt(fld_type,blank) values(left(@datatype,len(@datatype)+@m),

case when @m=-1 then 1 else 0 end)

if @i=1 or len(@datatype)=0

begin

RAISERROR ('error data type,comma sign can not be a prefix or surfix',16,1)

return

end

set @num1=@num1+1

end

--检查类型

if exists (select fld_type from @dt

where (case when charindex('(',fld_type)>0 then

left(fld_type,charindex('(',fld_type)-1)

else fld_type end) not in (select name from systypes) or

charindex('(',fld_type)*charindex(')',fld_type)=0 and

charindex('(',fld_type)+charindex(')',fld_type)>0)

begin

RAISERROR ('error data type.', 16, 1)

return

end

--提取字段和数据

set @a=replace(@str,char(9),' ') --- TAB char

set @a=rtrim(ltrim(@a))

if charindex(char(13)+char(10),right(@a,len(@a)-1))=0 or len(@a)=0

begin

RAISERROR ('input data error,check your data.', 16, 1)

return

end

if object_id('tempdb.dbo.#xx') is not null drop table #xx

select identity(int,1,1) ID,space(50) val into #xx where 1=2

set @k=0

set @num2=0

set @m=0

while len(@a)>0

begin

set @i=1

set @x=left(@a,1)

if @x=char(10) begin

if @m>@num2 and @num2>0 and charindex('k',@datatype)=0 begin

RAISERROR ('number of data is greater than the columns,you should add k in data type difinition.', 16, 1)

return

end

set @m=0

end

if @x not in (' ',char(13),char(10))

begin

set @i=charindex(' ',@a)

set @j=charindex(char(13)+char(10),@a)

set @m=@m+1

if @k<>-1 set @k=@k+1

if @j>0 and (@j<@i or @j>@i and substring(@a,@i,@j-@i)=space(@j-@i)) begin

set @i=@j

if @k>@num2 and @k<>-1 set @num2=@k

set @k=-1

end

if @i=0 set @i=(case when @j>0 then @j else len(@a)+1 end)

select @j=max(ID) from #xx

if @m=1 or @j<=@num1 or (select blank from @dt where ID=@m-1) <> 1

begin

if @j<@num1 set @x='['+replace(rtrim(left(@a,@i-1)),']',']]')+']'

else set @x=rtrim(left(replace(@a,'''',''''''),@i-1))

insert into #xx(val) values(@x)

end

else

begin

update #xx set val=val+' '+rtrim(left(@a,@i-1)) where ID=@j

set @m=@m-1

end

end

if @i<len(@a) set @a=ltrim(right(@a,len(@a)-@i))

else set @a=''

end

update #xx set val='' where val='NULL'

update #xx set val=''''+val+'''' where ID>@num2

if @num1<>@num2

begin

RAISERROR ('datatype dismatch the columns',16,1)

return

end

-- if use the exists template table,drop it

if object_id('tempdb.dbo.'+@table_name) is not null

exec('drop table '+@table_name)

-- 建表

update a

set a.fld_name=b.val

from @dt a,#xx b

where a.ID=b.ID and a.ID<=@num1

set @a=''

select @a=@a+fld_name+' '+fld_type+',' from @dt where ID<=@num1

set @a=left(@a,len(@a)-1)

set @sql='create table '+@table_name+'('+@a+')'

exec(@sql)

insert into @sqlt select @sql

--插入数据

set @i=@num1+1

while @i<=(select max(ID) from #xx)

begin

set @a=''

set @sql='select @s=@s+val+'','''+' from (select top '+convert(varchar(10),@num1)

+' val from #xx where ID>='+convert(varchar(10),(@i))+') a'

exec sp_executesql @sql,N'@s nvarchar(3000) output',@a output

set @a=left(@a,len(@a)-1)

set @sql='insert into '+@table_name+' select '+@a

if len(@a)>0 exec(@sql)

insert into @sqlt select @sql

set @i=@i+@num1

end

select * from @sqlt

--select * from @dt

exec('select * from '+@table_name)

SET NOCOUNT OFF

END

测试

exec dbo.create_table '##t2','varchar(20),datetime k','

ID AnDate

99101 2002-11-24 00:00:00.000

99101 2003-11-15 00:00:00.000

99101 2003-11-29 00:00:00.000

99101 2003-12-20 00:00:00.000'

结果

sql_statement

--------------------------------------------------------

create table ##t2(ID varchar(20),AnDate datetime)

insert into ##t2 select '99101','2002-11-24 00:00:00.000'

insert into ##t2 select '99101','2003-11-15 00:00:00.000'

insert into ##t2 select '99101','2003-11-29 00:00:00.000'

insert into ##t2 select '99101','2003-12-20 00:00:00.000'

ID AnDate

-------------------- ---------------------------

99101 2002-11-24 00:00:00.000

99101 2003-11-15 00:00:00.000

99101 2003-11-29 00:00:00.000

99101 2003-12-20 00:00:00.000

ORACLE的写法在测试中。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有