飘灵儿 发表于 2015-1-16 22:28:22

MSSQL编程:间接从SQL语句成绩贴子数据建表并天生建...

MySQL最初的开发者的意图是用mSQL和他们自己的快速低级例程(ISAM)去连接表格。经过一些测试后,开发者得出结论:mSQL并没有他们需要的那么快和灵活。存储历程|数据|成绩|语句
上面的存储历程,可帮你在回覆SQL语句成绩时,间接从贴子的样本数据建表并天生建表语句,省往大批的手工输出数据的事情。

/*CreateTablefromyourwebpagedata
*2004-JAN-1,OpenVMS,V0.1
*2004-JAN-2,V0.5,addtab&blankvalueslogical
*2004-JAN-3,V1.0,addSQLStatementgeneration
*2004-JAN-4,V1.1,fixdatatypelikedecimal(4,2)bug
*2004-JAN-4,V1.2,fixfieldnamebug
*
*SampleCall:inSQLQueryAnalyzer
execdbo.create_table##t2,varchar(20),datetimek,
IDAnDate
991012002-11-2400:00:00.000
991012003-11-1500:00:00.000
991012003-11-2900:00:00.000
991012003-12-2000:00:00.000

注重:
1如用一时表名,只能用全局一时表##,不然不成会见
2假如没有列名,则必要在第一行数据手动加上列名
3字段称号不同意含空格
4最少一行数据,不然没成心义
5字段值为空必要写上NULL,字段值中的任何标记作为值的一部分
6没有对界说范例和值的范例婚配反省
7可指定值中含有空格,办法为在该范例界说中的尾部加字母k,如datatimek,
8如过值中含有单引号,必要复写-》
*/

IFEXISTS(SELECTname
FROMsysobjects
WHEREname=Ncreate_table
ANDtype=P)
DROPPROCEDUREcreate_table
go

createprocdbo.create_table
@table_namevarchar(60),---Tablename
@datatypevarchar(1000),---separatedbycomma,
@strnvarchar(3000)---inputstringpastedfromwebpage
AS
BEGIN
declare@dttable(idintidentity(1,1),fld_namevarchar(30),fld_typevarchar(20),blankint)
declare@sqlttable(sql_statementvarchar(8000))
declare@tmpvarchar(1000),@num1int,@num2int,@sqlnvarchar(4000)
declare@anvarchar(3000),@iint,@jint,@kint,@mint,@xnvarchar(1000)

SETNOCOUNTON
ifobject_id(@table_name)isnotnull
begin
set@a=TABLE+@table_name+exists,chooseanewone!
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)
--checkdatatypelikedecimal(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>1and@j<@i)or(@i=0and@j=len(@datatype))set@m=-1
if@i>1
begin
insertinto@dt(fld_type,blank)
values(left(@datatype,@i-1+@m),casewhen@m=-1then1else0end)
select@datatype=right(@datatype,len(@datatype)-@i)
end
if@i=0andlen(@datatype)>0
insertinto@dt(fld_type,blank)values(left(@datatype,len(@datatype)+@m),
casewhen@m=-1then1else0end)
if@i=1orlen(@datatype)=0
begin
RAISERROR(errordatatype,commasigncannotbeaprefixorsurfix,16,1)
return
end

set@num1=@num1+1
end

--反省范例
ifexists(selectfld_typefrom@dt
where(casewhencharindex((,fld_type)>0then
left(fld_type,charindex((,fld_type)-1)
elsefld_typeend)notin(selectnamefromsystypes)or
charindex((,fld_type)*charindex(),fld_type)=0and
charindex((,fld_type)+charindex(),fld_type)>0)
begin
RAISERROR(errordatatype.,16,1)
return
end

--提取字段和数据
set@a=replace(@str,char(9),)---TABchar
set@a=rtrim(ltrim(@a))
ifcharindex(char(13)+char(10),right(@a,len(@a)-1))=0orlen(@a)=0
begin
RAISERROR(inputdataerror,checkyourdata.,16,1)
return
end

ifobject_id(tempdb.dbo.#xx)isnotnulldroptable#xx
selectidentity(int,1,1)ID,space(50)valinto#xxwhere1=2
set@k=0
set@num2=0
set@m=0
whilelen(@a)>0
begin
set@i=1
set@x=left(@a,1)

if@x=char(10)begin
if@m>@num2and@num2>0andcharindex(k,@datatype)=0begin
RAISERROR(numberofdataisgreaterthanthecolumns,youshouldaddkindatatypedifinition.,16,1)
return
end
set@m=0
end

if@xnotin(,char(13),char(10))
begin
set@i=charindex(,@a)
set@j=charindex(char(13)+char(10),@a)
set@m=@m+1
if@k-1set@k=@k+1
if@j>0and(@j<@ior@j>@iandsubstring(@a,@i,@j-@i)=space(@j-@i))begin
set@i=@j
if@k>@num2and@k-1set@num2=@k
set@k=-1
end
if@i=0set@i=(casewhen@j>0then@jelselen(@a)+1end)

select@j=max(ID)from#xx
if@m=1or@j<=@num1or(selectblankfrom@dtwhereID=@m-1)1
begin
if@j<@num1set@x=[+replace(rtrim(left(@a,@i-1)),],]])+]
elseset@x=rtrim(left(replace(@a,,),@i-1))
insertinto#xx(val)values(@x)
end
else
begin
update#xxsetval=val++rtrim(left(@a,@i-1))whereID=@j
set@m=@m-1
end
end
if@i<len(@a)set@a=ltrim(right(@a,len(@a)-@i))
elseset@a=
end

update#xxsetval=whereval=NULL
update#xxsetval=+val+whereID>@num2

if@num1@num2
begin
RAISERROR(datatypedismatchthecolumns,16,1)
return
end

--ifusetheexiststemplatetable,dropit
ifobject_id(tempdb.dbo.+@table_name)isnotnull
exec(droptable+@table_name)

--建表
updatea
seta.fld_name=b.val
from@dta,#xxb
wherea.ID=b.IDanda.ID<=@num1

set@a=
select@a=@a+fld_name++fld_type+,from@dtwhereID<=@num1
set@a=left(@a,len(@a)-1)
set@sql=createtable+@table_name+(+@a+)
exec(@sql)
insertinto@sqltselect@sql

--拔出数据
set@i=@num1+1
while@i<=(selectmax(ID)from#xx)
begin
set@a=
set@sql=select@s=@s+val+,+from(selecttop+convert(varchar(10),@num1)
+valfrom#xxwhereID>=+convert(varchar(10),(@i))+)a
execsp_executesql@sql,N@snvarchar(3000)output,@aoutput

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

set@sql=insertinto+@table_name+select+@a
iflen(@a)>0exec(@sql)
insertinto@sqltselect@sql

set@i=@i+@num1
end

select*from@sqlt
--select*from@dt
exec(select*from+@table_name)
SETNOCOUNTOFF
END

测试
execdbo.create_table##t2,varchar(20),datetimek,
IDAnDate
991012002-11-2400:00:00.000
991012003-11-1500:00:00.000
991012003-11-2900:00:00.000
991012003-12-2000:00:00.000


了局
sql_statement
--------------------------------------------------------
createtable##t2(IDvarchar(20),AnDatedatetime)
insertinto##t2select99101,2002-11-2400:00:00.000
insertinto##t2select99101,2003-11-1500:00:00.000
insertinto##t2select99101,2003-11-2900:00:00.000
insertinto##t2select99101,2003-12-2000:00:00.000

IDAnDate
-----------------------------------------------
991012002-11-2400:00:00.000
991012003-11-1500:00:00.000
991012003-11-2900:00:00.000
991012003-12-2000:00:00.000




ORACLE的写法在测试中。

使为了数据安全,我们搭建了主从。但实时主从备份只能防止硬件问题,比如主库的硬盘损坏。但对于误操作,则无能为力。比如在主库误删一张表,或者一个update语句没有指定where条件,导致全表被更新。

小女巫 发表于 2015-1-19 13:51:24

每天坚持做不一样的是,认真做笔录,定时复习。一个月你就可以有一定的收获。当然如果你想在sql方面有一定的造诣,你少不了需要看很多很多的书籍了。

若相依 发表于 2015-1-24 23:21:10

你觉得我的非分区索引无法对起子分区,你可以提醒我一下呀!没有任何的提醒,直接就变成了非分区表。不知道这算不算一个bug。大家也可以试试。

柔情似水 发表于 2015-2-2 14:24:49

再开发调试阶段和OLAP环境中,外键是可以建立的。新版本中加入了SETNULL和SETDEFAULT属性,能够提供能好的级联设置。

老尸 发表于 2015-2-7 22:35:58

sqlserver的痛苦之处在于有用文档的匮乏,很多只是表明的东西

精灵巫婆 发表于 2015-2-23 13:59:02

一直以来个人感觉SQLServer的优化器要比Oracle的聪明。SQL2005的更是比2k聪明了不少。(有次作试验发现有的语句在200万级时还比50万级的相同语句要快show_text的一些提示没有找到解释。一直在奇怪。)

admin 发表于 2015-3-7 09:19:58

对一张百万级别的表建游标,同时又没有什么过滤条件,取得游标效率是如果直接SQL查询百万条数据;如果再对每条记录做处理,耗时将更长。

山那边是海 发表于 2015-3-14 18:42:39

大家注意一点。如下面的例子:

金色的骷髅 发表于 2015-3-21 13:49:48

而写到本地,我又考虑到效率问题.大家来讨论讨论吧,分数不打紧,就给10分,十全十美,没啥对错,各抒己见,但是要有说服力的哦~
页: [1]
查看完整版本: MSSQL编程:间接从SQL语句成绩贴子数据建表并天生建...