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

存储过程|数据|问题|语句

下面的存储过程,可帮你在回答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的写法在测试中。

时间: 2024-11-16 05:28:06

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

oracle11g-使用sql语句select插入数据时怎么用行号补0为流水号做完单号保存

问题描述 使用sql语句select插入数据时怎么用行号补0为流水号做完单号保存 使用select语句像某个表中插入数据,表的单号要为该语句的ItemCode的值+5位流水号.流水号的规则是查询出来的"RowNum"的值自动补0为5为流水号.怎么出入,查询数据如图 解决方案 新增一列numerical order 类型为字符串 然后写个方法计算numerical order ,insert进去. 但只用sql语句的话,还没想到. 解决方案二: 试试这个: select itemcode

sqlserver中一条sql语句把插入数据的ID返回出来,oracle中sql语句要怎么写?

问题描述 sqlserver中一条sql语句把插入数据的ID返回出来,oracle中sql语句要怎么写? sqlserver中一条sql语句把插入数据的ID返回出来,oracle中sql语句要怎么写? 解决方案 oracle,sqlserver分页查询sql语句重复的数据只取一条,SQL语句如何写 解决方案二: select test.currval from dual 解决方案三: oracle里面不是差不多的吗

SQl 语句(常见) 新建,删除,修改表结构(转载)

SQl 语句(常见) 新建,删除,修改表结构 新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default '默认值' null ,[字段2] ntext null ,[字段3] datetime,[字段4] money null ,[字段5] int default 0,[字段6] Decimal (12,4) default 0,[字段7] image null ,) 删除表

求SQL语句,将多个表合成一个表,每个表的结构不一样。要过滤重复的字段和行

问题描述 求SQL语句,将多个表合成一个表,每个表的结构不一样.要过滤重复的字段和行如:tb1(idintprimarykey,namevarchar(10),titlevarchar(10),)tb2(idint,namevarchar(10),titlevarchar(10),addressvarchar(10)foreignkey(id)referencestb1(id))tb3(idint,namevarchar(10),telvarchar(10),addressvarchar(10)

sql语句查询数据库中的表名/列名/主键/自动增长值实例_MsSql

sql语句查询数据库中的表名/列名/主键/自动增长值 ----查询数据库中用户创建的表 ----jsj01 为数据库名 select name tablename from jsj01..sysobjects where type='U' and name not in ('dtproperties') --查询表里的字段信息 ---docs为表名 ---- select * from syscolumns where id = object_id('docs') ----查询数据库中所有类型

用sql语句动态的创建access表

用sql语句动态的创建access表的代如下! <% nowtime = now() tablename = cstr(year(nowtime))+"_"+cstr(second(nowtime)) response.write tablename db_path = "test.mdb" Set conn= Server.CreateObject("ADODB.Connection") connstr = "Provider=

java-新手求助:sql语句,从多个表中取出最新时间的记录,组成一个新表

问题描述 新手求助:sql语句,从多个表中取出最新时间的记录,组成一个新表 解决方案 mysql的实现: insert into zongbiao(id, name ,vd,co2,wendu,time) select t1.id,t1.name,t1.vd,t2.co2,t2.wendu,t2.time from biao1 t1 join biao2 t2 on(t1.id=t2.id) order by t2.time desc limit 1; 解决方案二: 1.mysql和oracle

sql语句如何将三张表所有要的属性显示

问题描述 sql语句如何将三张表所有要的属性显示 SQL大神指教指教,谢谢! 表一:XS Sno Sname Sex birthday Pid class department (表一属性) 表二:CJ Sno Courseno Score (表二属性) 表三:KC Courseno Coursename credit (表三属性) 要求:"用相关查询语句"查询选修课程号为"xx" 的学生的相关信息 解决方案 select XS.Sno, Sname,Sex, bi

dedecms-织梦中标签里面的sql语句中arc是什么表?

问题描述 织梦中标签里面的sql语句中arc是什么表? 这是arclist标签中的一段. 这个arc是什么表,估计是dede_archives ,但是怎么能这样写的呢? $query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,tp.namerule2,tp.ispart, tp.moresite,tp.siteurl,tp.sitepath $addfields