数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
直接从SQL语句问题贴子数据建表并生成建表语句的存储过程

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

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




相关文章

相关软件