经典SQL语句面试、开发必备
2013-12-03 13:44
375 查看
from
日程安排wheredatediff('minute',f开始时间,getdate())>5
13、说明:一条sql
语句搞定数据库分页
selecttop10b.*from(selecttop20
主键字段,排序字段from
表名orderby
排序字段desc)a,表名bwhereb.主键字段
=a.主键字段orderbya.排序字段
具体实现:
关于数据库分页:
declare@startint,@endint
@sqlnvarchar(600)
set@sql=’selecttop’+str(@end-@start+1)+’+fromTwhereridnotin(select
top’+str(@str-1)+’RidfromTwhereRid>-1)’
execsp_executesql@sql
注意:在top后不能直接跟一个变量,所以在实际应用中只有这样的进行特殊的处理。Rid为一个标识列,如果top后还有具体的字段,这样做是非常有好处的。因为这样可以避免
top的字段如果是逻辑索引的,查询的结果后实际表中的不一致(逻辑索引中的数据有可能和数据表中的不一致,而查询时如果处在索引则首先查询索引)
14、说明:前10条记录
selecttop10*formtable1where
范围
15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
selecta,b,cfrom
tablenametawherea=(selectmax(a)fromtablenametbwheretb.b=ta.b)
16、说明:包括所有在
TableA中但不在
TableB和TableC中的行并消除所有重复行而派生出一个结果表
(selectafromtableA)except(selectafromtableB)except(selectafromtableC)
17、说明:随机取出10条数据
selecttop10*from
tablenameorderby
newid()
18、说明:随机选择记录
selectnewid()
19、说明:删除重复记录
1),deletefromtablenamewhereidnotin(selectmax(id)fromtablenamegroupbycol1,col2,...)
2),selectdistinct*intotempfrom
tablename
deletefrom
tablename
insertinto
tablenameselect*fromtemp
评价:这种操作牵连大量的数据的移动,这种做法不适合大容量但数据操作
3),例如:在一个外部表中导入数据,由于某些原因第一次只导入了一部分,但很难判断具体位置,这样只有在下一次全部导入,这样也就产生好多重复的字段,怎样删除重复字段
altertable
tablename
--添加一个自增列
addcolumn_bintidentity(1,1)
deletefromtablenamewherecolumn_bnotin(
selectmax(column_b)
fromtablenamegroupbycolumn1,column2,...)
altertabletablenamedropcolumn
column_b
20、说明:列出数据库里所有的表名
selectnamefromsysobjectswheretype='U'//U代表用户
21、说明:列出表里的所有的列名
selectnamefromsyscolumnswhereid=object_id('TableName')
22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select
中的case。
selecttype,sum(casevenderwhen'A'thenpcselse0end),sum(casevenderwhen'C'thenpcselse0end),sum(casevenderwhen'B'thenpcselse0end)FROMtablenamegroupbytype
显示结果:
typevenderpcs
电脑A1
电脑A1
光盘B2
光盘A2
手机B3
手机C3
23、说明:初始化表table1
TRUNCATETABLEtable1
24、说明:选择从10到15的记录
selecttop5*from(selecttop15*fromtableorderbyidasc)table_别名orderbyiddesc
三、技巧
1、1=1,1=2的使用,在SQL语句组合时用的较多
“where1=1”
是表示选择全部“where1=2”全部不选,
如:
if@strWhere!=''
begin
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']where'+@strWhere
end
else
begin
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']'
end
我们可以直接写成
错误!未找到目录项。
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']where1=1
安定'+@strWhere
2、收缩数据库
--重建索引
DBCCREINDEX
DBCCINDEXDEFRAG
--收缩数据和日志
DBCCSHRINKDB
DBCCSHRINKFILE
3、压缩数据库
dbccshrinkdatabase(dbname)
4、转移数据库给新用户以已存在用户权限
execsp_change_users_login'update_one','newname','oldname'
go
5、检查备份集
RESTOREVERIFYONLYfromdisk='E:\dvbbs.bak'
6、修复数据库
ALTERDATABASE[dvbbs]SETSINGLE_USER
GO
DBCCCHECKDB('dvbbs',repair_allow_data_loss)WITHTABLOCK
GO
ALTERDATABASE[dvbbs]SETMULTI_USER
GO
7、日志清除
SETNOCOUNTON
DECLARE@LogicalFileNamesysname,
@MaxMinutesINT,
@NewSizeINT
USEtablename--要操作的数据库名
SELECT@LogicalFileName='tablename_log',--
日志文件名
@MaxMinutes=10,--Limitontimeallowedtowraplog.
@NewSize=1--你想设定的日志文件的大小(M)
Setup/initialize
DECLARE@OriginalSizeint
SELECT@OriginalSize=size
FROMsysfiles
WHEREname=@LogicalFileName
SELECT'OriginalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),@OriginalSize)+'8Kpagesor'+
CONVERT(VARCHAR(30),(@OriginalSize*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
CREATETABLEDummyTrans
(DummyColumnchar(8000)notnull)
DECLARE@CounterINT,
@StartTimeDATETIME,
@TruncLogVARCHAR(255)
SELECT@StartTime=GETDATE(),
@TruncLog='BACKUPLOG'+db_name()+'WITHTRUNCATE_ONLY'
DBCCSHRINKFILE(@LogicalFileName,@NewSize)
EXEC(@TruncLog)
--Wrapthelogifnecessary.
WHILE@MaxMinutes>DATEDIFF(mi,@StartTime,GETDATE())--timehasnotexpired
AND@OriginalSize=(SELECTsizeFROMsysfilesWHEREname=@LogicalFileName)
AND(@OriginalSize*8/1024)>@NewSize
BEGIN--Outerloop.
SELECT@Counter=0
WHILE((@Counter<@OriginalSize/16)AND(@Counter<50000))
BEGIN--update
INSERTDummyTransVALUES('FillLog')DELETEDummyTrans
SELECT@Counter=@Counter+1
END
EXEC(@TruncLog)
END
SELECT'FinalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),size)+'8Kpagesor'+
CONVERT(VARCHAR(30),(size*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
DROPTABLEDummyTrans
SETNOCOUNTOFF
8、说明:更改某个表
execsp_changeobjectowner'tablename','dbo'
9、存储更改全部表
CREATEPROCEDUREdbo.User_ChangeObjectOwnerBatch
@OldOwnerasNVARCHAR(128),
@NewOwnerasNVARCHAR(128)
AS
DECLARE@NameasNVARCHAR(128)
DECLARE@OwnerasNVARCHAR(128)
DECLARE@OwnerNameasNVARCHAR(128)
DECLAREcurObjectCURSORFOR
select'Name'=name,
'Owner'=user_name(uid)
fromsysobjects
whereuser_name(uid)=@OldOwner
orderbyname
OPENcurObject
FETCHNEXTFROMcurObjectINTO@Name,@Owner
WHILE(@@FETCH_STATUS=0)
BEGIN
if@Owner=@OldOwner
begin
set@OwnerName=@OldOwner+'.'+rtrim(@Name)
execsp_changeobjectowner@OwnerName,@NewOwner
end
--select@name,@NewOwner,@OldOwner
FETCHNEXTFROMcurObjectINTO@Name,@Owner
END
closecurObject
deallocatecurObject
GO
10、SQLSERVER中直接循环写入数据
declare@iint
set@i=1
while@i<30
begin
insertintotest(userid)values(@i)
set@i=@i+1
end
案例:
有如下表,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格:
Namescore
Zhangshan
80
Lishi59
Wangwu50
Songquan
69
while((select
min(score)fromtb_table)<60)
begin
updatetb_tablesetscore
=score*1.01
wherescore<60
if(select
min(score)fromtb_table)>60
break
else
continue
end
数据开发-经典
1.按姓氏笔画排序:
Select*FromTableNameOrderByCustomerNameCollateChinese_PRC_Stroke_ci_as//从少到多
2.数据库加密:selectencrypt('原始密码')
selectpwdencrypt('原始密码')
selectpwdcompare('原始密码','加密后密码')=1--相同;否则不相同encrypt('原始密码')
selectpwdencrypt('原始密码')
selectpwdcompare('原始密码','加密后密码')=1--相同;否则不相同
3.取回表中字段:
declare@listvarchar(1000),
@sqlnvarchar(1000)
select@list=@list+','+b.namefromsysobjectsa,syscolumnsbwherea.id=b.idanda.name='表A'
set@sql='select'+right(@list,len(@list)-1)+'from
表A'
exec(@sql)
4.查看硬盘分区:
EXECmaster..xp_fixeddrives
5.比较A,B表是否相等:
if(selectchecksum_agg(binary_checksum(*))fromA)
=
(selectchecksum_agg(binary_checksum(*))fromB)
print'相等'
else
print'不相等'
6.杀掉所有的事件探察器进程:
DECLAREhcforeachCURSORGLOBALFORSELECT'kill'+RTRIM(spid)FROMmaster.dbo.sysprocesses
WHEREprogram_nameIN('SQLprofiler',N'SQL事件探查器')
EXECsp_msforeach_worker'?'
7.记录搜索:
开头到N条记录
SelectTopN*From
表
-------------------------------
N到M条记录(要有主索引ID)
SelectTopM-N*From表WhereIDin(SelectTopMIDFrom
表)OrderbyIDDesc
----------------------------------
N到结尾记录
SelectTopN*From
表OrderbyIDDesc
案例
例如1:一张表有一万多条记录,表的第一个字段RecID是自增长字段,写一个SQL语句,找出表的第31到第40个记录。
selecttop10recidfromAwhererecidnotin(selecttop30recidfromA)
分析:如果这样写会产生某些问题,如果recid在表中存在逻辑索引。
selecttop10recidfromAwhere……是从索引中查找,而后面的selecttop30recidfromA则在数据表中查找,这样由于索引中的顺序有可能和数据表中的不一致,这样就导致查询到的不是本来的欲得到的数据。
解决方案
1,用orderby
selecttop30recidfromAorderbyricid
如果该字段不是自增长,就会出现问题
2,在那个子查询中也加条件:selecttop30recidfromAwhererecid>-1
例2:查询表中的最后以条记录,并不知道这个表共有多少数据,以及表结构。
set
@s='selecttop1*fromT
wherepidnotin(selecttop'+str(@count-1)+
'pidfromT)'
print
@sexec
sp_executesql
@s
9:获取当前数据库中的所有用户表
selectNamefromsysobjectswherextype='u'andstatus>=0
10:获取某一个表的所有字段
selectnamefrom
syscolumnswhereid=object_id('表名')
selectnamefrom
syscolumnswhereidin(selectidfrom
sysobjectswheretype='u'andname='表名')
两种方式的效果相同
11:查看与某一个表相关的视图、存储过程、函数selecta.*from
sysobjectsa,
syscommentsbwherea.id=b.idandb.textlike'%表名%'
12:查看当前数据库中所有存储过程
selectnameas
存储过程名称fromsysobjectswherextype='P'
13:查询用户创建的所有数据库
select*frommaster..sysdatabasesDwheresidnotin(selectsidfrommaster..syslogins
wherename='sa')
或者
selectdbid,nameASDB_NAMEfrommaster..sysdatabaseswheresid<>0x01
14:查询某一个表的字段和数据类型
selectcolumn_name,data_typefrominformation_schema.columns
wheretable_name='表名'
15:不同服务器数据库之间的数据操作
--创建链接服务器
execsp_addlinkedserver
'ITSV','','SQLOLEDB','远程服务器名或ip地址'
execsp_addlinkedsrvlogin
'ITSV','false',null,'用户名','密码'
--查询示例
select*fromITSV.数据库名.dbo.表名
--导入示例
select*into
表fromITSV.数据库名.dbo.表名
--以后不再使用时删除链接服务器
execsp_dropserver
'ITSV','droplogins'
--连接远程/局域网数据(openrowset/openquery/opendatasource)
--1、openrowset
--查询示例
select*fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
--生成本地表
select*into
表fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
--把本地表导入远程表
insertopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
select*from
本地表
--更新本地表
updateb
setb.列A=a.列A
fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)asainnerjoin本地表b
ona.column1=b.column1
--openquery用法需要创建一个连接
--首先创建一个连接创建链接服务器
execsp_addlinkedserver
'ITSV','','SQLOLEDB','远程服务器名或ip地址'
--查询
select*
FROMopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')
--把本地表导入远程表
insertopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')
select*from
本地表
--更新本地表
updateb
setb.列B=a.列B
FROMopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')asa
innerjoin
本地表bona.列A=b.列A
--3、opendatasource/openrowset
SELECT
*
FROM
opendatasource('SQLOLEDB','DataSource=ip/ServerName;UserID=登陆名;Password=密码').test.dbo.roy_ta
--把本地表导入远程表
insertopendatasource('SQLOLEDB',
'DataSource=ip/ServerName;UserID=登陆名;Password=密码').数据库.dbo.表名
select*from
本地表
SQLServer基本函数
SQLServer基本函数
1.字符串函数
长度与分析用
1,datalength(Char_expr)
返回字符串包含字符数,但不包含后面的空格
2,substring(expression,start,length)
取子串,字符串的下标是从“1”,start为起始位置,length为字符串长度,实际应用中以len(expression)取得其长度
3,right(char_expr,int_expr)
返回字符串右边第int_expr个字符,还用left于之相反
4,isnull(
check_expression,
replacement_value)如果check_expression為空,則返回replacement_value的值,不為空,就返回check_expression字符操作类
5,Sp_addtype
自定義數據類型
例如:
日程安排wheredatediff('minute',f开始时间,getdate())>5
13、说明:一条sql
语句搞定数据库分页
selecttop10b.*from(selecttop20
主键字段,排序字段from
表名orderby
排序字段desc)a,表名bwhereb.主键字段
=a.主键字段orderbya.排序字段
具体实现:
关于数据库分页:
declare@startint,@endint
@sqlnvarchar(600)
set@sql=’selecttop’+str(@end-@start+1)+’+fromTwhereridnotin(select
top’+str(@str-1)+’RidfromTwhereRid>-1)’
execsp_executesql@sql
注意:在top后不能直接跟一个变量,所以在实际应用中只有这样的进行特殊的处理。Rid为一个标识列,如果top后还有具体的字段,这样做是非常有好处的。因为这样可以避免
top的字段如果是逻辑索引的,查询的结果后实际表中的不一致(逻辑索引中的数据有可能和数据表中的不一致,而查询时如果处在索引则首先查询索引)
14、说明:前10条记录
selecttop10*formtable1where
范围
15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
selecta,b,cfrom
tablenametawherea=(selectmax(a)fromtablenametbwheretb.b=ta.b)
16、说明:包括所有在
TableA中但不在
TableB和TableC中的行并消除所有重复行而派生出一个结果表
(selectafromtableA)except(selectafromtableB)except(selectafromtableC)
17、说明:随机取出10条数据
selecttop10*from
tablenameorderby
newid()
18、说明:随机选择记录
selectnewid()
19、说明:删除重复记录
1),deletefromtablenamewhereidnotin(selectmax(id)fromtablenamegroupbycol1,col2,...)
2),selectdistinct*intotempfrom
tablename
deletefrom
tablename
insertinto
tablenameselect*fromtemp
评价:这种操作牵连大量的数据的移动,这种做法不适合大容量但数据操作
3),例如:在一个外部表中导入数据,由于某些原因第一次只导入了一部分,但很难判断具体位置,这样只有在下一次全部导入,这样也就产生好多重复的字段,怎样删除重复字段
altertable
tablename
--添加一个自增列
addcolumn_bintidentity(1,1)
deletefromtablenamewherecolumn_bnotin(
selectmax(column_b)
fromtablenamegroupbycolumn1,column2,...)
altertabletablenamedropcolumn
column_b
20、说明:列出数据库里所有的表名
selectnamefromsysobjectswheretype='U'//U代表用户
21、说明:列出表里的所有的列名
selectnamefromsyscolumnswhereid=object_id('TableName')
22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select
中的case。
selecttype,sum(casevenderwhen'A'thenpcselse0end),sum(casevenderwhen'C'thenpcselse0end),sum(casevenderwhen'B'thenpcselse0end)FROMtablenamegroupbytype
显示结果:
typevenderpcs
电脑A1
电脑A1
光盘B2
光盘A2
手机B3
手机C3
23、说明:初始化表table1
TRUNCATETABLEtable1
24、说明:选择从10到15的记录
selecttop5*from(selecttop15*fromtableorderbyidasc)table_别名orderbyiddesc
三、技巧
1、1=1,1=2的使用,在SQL语句组合时用的较多
“where1=1”
是表示选择全部“where1=2”全部不选,
如:
if@strWhere!=''
begin
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']where'+@strWhere
end
else
begin
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']'
end
我们可以直接写成
错误!未找到目录项。
set@strSQL='selectcount(*)asTotalfrom['+@tblName+']where1=1
安定'+@strWhere
2、收缩数据库
--重建索引
DBCCREINDEX
DBCCINDEXDEFRAG
--收缩数据和日志
DBCCSHRINKDB
DBCCSHRINKFILE
3、压缩数据库
dbccshrinkdatabase(dbname)
4、转移数据库给新用户以已存在用户权限
execsp_change_users_login'update_one','newname','oldname'
go
5、检查备份集
RESTOREVERIFYONLYfromdisk='E:\dvbbs.bak'
6、修复数据库
ALTERDATABASE[dvbbs]SETSINGLE_USER
GO
DBCCCHECKDB('dvbbs',repair_allow_data_loss)WITHTABLOCK
GO
ALTERDATABASE[dvbbs]SETMULTI_USER
GO
7、日志清除
SETNOCOUNTON
DECLARE@LogicalFileNamesysname,
@MaxMinutesINT,
@NewSizeINT
USEtablename--要操作的数据库名
SELECT@LogicalFileName='tablename_log',--
日志文件名
@MaxMinutes=10,--Limitontimeallowedtowraplog.
@NewSize=1--你想设定的日志文件的大小(M)
Setup/initialize
DECLARE@OriginalSizeint
SELECT@OriginalSize=size
FROMsysfiles
WHEREname=@LogicalFileName
SELECT'OriginalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),@OriginalSize)+'8Kpagesor'+
CONVERT(VARCHAR(30),(@OriginalSize*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
CREATETABLEDummyTrans
(DummyColumnchar(8000)notnull)
DECLARE@CounterINT,
@StartTimeDATETIME,
@TruncLogVARCHAR(255)
SELECT@StartTime=GETDATE(),
@TruncLog='BACKUPLOG'+db_name()+'WITHTRUNCATE_ONLY'
DBCCSHRINKFILE(@LogicalFileName,@NewSize)
EXEC(@TruncLog)
--Wrapthelogifnecessary.
WHILE@MaxMinutes>DATEDIFF(mi,@StartTime,GETDATE())--timehasnotexpired
AND@OriginalSize=(SELECTsizeFROMsysfilesWHEREname=@LogicalFileName)
AND(@OriginalSize*8/1024)>@NewSize
BEGIN--Outerloop.
SELECT@Counter=0
WHILE((@Counter<@OriginalSize/16)AND(@Counter<50000))
BEGIN--update
INSERTDummyTransVALUES('FillLog')DELETEDummyTrans
SELECT@Counter=@Counter+1
END
EXEC(@TruncLog)
END
SELECT'FinalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),size)+'8Kpagesor'+
CONVERT(VARCHAR(30),(size*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
DROPTABLEDummyTrans
SETNOCOUNTOFF
8、说明:更改某个表
execsp_changeobjectowner'tablename','dbo'
9、存储更改全部表
CREATEPROCEDUREdbo.User_ChangeObjectOwnerBatch
@OldOwnerasNVARCHAR(128),
@NewOwnerasNVARCHAR(128)
AS
DECLARE@NameasNVARCHAR(128)
DECLARE@OwnerasNVARCHAR(128)
DECLARE@OwnerNameasNVARCHAR(128)
DECLAREcurObjectCURSORFOR
select'Name'=name,
'Owner'=user_name(uid)
fromsysobjects
whereuser_name(uid)=@OldOwner
orderbyname
OPENcurObject
FETCHNEXTFROMcurObjectINTO@Name,@Owner
WHILE(@@FETCH_STATUS=0)
BEGIN
if@Owner=@OldOwner
begin
set@OwnerName=@OldOwner+'.'+rtrim(@Name)
execsp_changeobjectowner@OwnerName,@NewOwner
end
--select@name,@NewOwner,@OldOwner
FETCHNEXTFROMcurObjectINTO@Name,@Owner
END
closecurObject
deallocatecurObject
GO
10、SQLSERVER中直接循环写入数据
declare@iint
set@i=1
while@i<30
begin
insertintotest(userid)values(@i)
set@i=@i+1
end
案例:
有如下表,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格:
Namescore
Zhangshan
80
Lishi59
Wangwu50
Songquan
69
while((select
min(score)fromtb_table)<60)
begin
updatetb_tablesetscore
=score*1.01
wherescore<60
if(select
min(score)fromtb_table)>60
break
else
continue
end
数据开发-经典
1.按姓氏笔画排序:
Select*FromTableNameOrderByCustomerNameCollateChinese_PRC_Stroke_ci_as//从少到多
2.数据库加密:selectencrypt('原始密码')
selectpwdencrypt('原始密码')
selectpwdcompare('原始密码','加密后密码')=1--相同;否则不相同encrypt('原始密码')
selectpwdencrypt('原始密码')
selectpwdcompare('原始密码','加密后密码')=1--相同;否则不相同
3.取回表中字段:
declare@listvarchar(1000),
@sqlnvarchar(1000)
select@list=@list+','+b.namefromsysobjectsa,syscolumnsbwherea.id=b.idanda.name='表A'
set@sql='select'+right(@list,len(@list)-1)+'from
表A'
exec(@sql)
4.查看硬盘分区:
EXECmaster..xp_fixeddrives
5.比较A,B表是否相等:
if(selectchecksum_agg(binary_checksum(*))fromA)
=
(selectchecksum_agg(binary_checksum(*))fromB)
print'相等'
else
print'不相等'
6.杀掉所有的事件探察器进程:
DECLAREhcforeachCURSORGLOBALFORSELECT'kill'+RTRIM(spid)FROMmaster.dbo.sysprocesses
WHEREprogram_nameIN('SQLprofiler',N'SQL事件探查器')
EXECsp_msforeach_worker'?'
7.记录搜索:
开头到N条记录
SelectTopN*From
表
-------------------------------
N到M条记录(要有主索引ID)
SelectTopM-N*From表WhereIDin(SelectTopMIDFrom
表)OrderbyIDDesc
----------------------------------
N到结尾记录
SelectTopN*From
表OrderbyIDDesc
案例
例如1:一张表有一万多条记录,表的第一个字段RecID是自增长字段,写一个SQL语句,找出表的第31到第40个记录。
selecttop10recidfromAwhererecidnotin(selecttop30recidfromA)
分析:如果这样写会产生某些问题,如果recid在表中存在逻辑索引。
selecttop10recidfromAwhere……是从索引中查找,而后面的selecttop30recidfromA则在数据表中查找,这样由于索引中的顺序有可能和数据表中的不一致,这样就导致查询到的不是本来的欲得到的数据。
解决方案
1,用orderby
selecttop30recidfromAorderbyricid
如果该字段不是自增长,就会出现问题
2,在那个子查询中也加条件:selecttop30recidfromAwhererecid>-1
例2:查询表中的最后以条记录,并不知道这个表共有多少数据,以及表结构。
set
@s='selecttop1*fromT
wherepidnotin(selecttop'+str(@count-1)+
'pidfromT)'
@sexec
sp_executesql
@s
9:获取当前数据库中的所有用户表
selectNamefromsysobjectswherextype='u'andstatus>=0
10:获取某一个表的所有字段
selectnamefrom
syscolumnswhereid=object_id('表名')
selectnamefrom
syscolumnswhereidin(selectidfrom
sysobjectswheretype='u'andname='表名')
两种方式的效果相同
11:查看与某一个表相关的视图、存储过程、函数selecta.*from
sysobjectsa,
syscommentsbwherea.id=b.idandb.textlike'%表名%'
12:查看当前数据库中所有存储过程
selectnameas
存储过程名称fromsysobjectswherextype='P'
13:查询用户创建的所有数据库
select*frommaster..sysdatabasesDwheresidnotin(selectsidfrommaster..syslogins
wherename='sa')
或者
selectdbid,nameASDB_NAMEfrommaster..sysdatabaseswheresid<>0x01
14:查询某一个表的字段和数据类型
selectcolumn_name,data_typefrominformation_schema.columns
wheretable_name='表名'
15:不同服务器数据库之间的数据操作
--创建链接服务器
execsp_addlinkedserver
'ITSV','','SQLOLEDB','远程服务器名或ip地址'
execsp_addlinkedsrvlogin
'ITSV','false',null,'用户名','密码'
--查询示例
select*fromITSV.数据库名.dbo.表名
--导入示例
select*into
表fromITSV.数据库名.dbo.表名
--以后不再使用时删除链接服务器
execsp_dropserver
'ITSV','droplogins'
--连接远程/局域网数据(openrowset/openquery/opendatasource)
--1、openrowset
--查询示例
select*fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
--生成本地表
select*into
表fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
--把本地表导入远程表
insertopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)
select*from
本地表
--更新本地表
updateb
setb.列A=a.列A
fromopenrowset('SQLOLEDB','sql服务器名';'用户名';'密码',数据库名.dbo.表名)asainnerjoin本地表b
ona.column1=b.column1
--openquery用法需要创建一个连接
--首先创建一个连接创建链接服务器
execsp_addlinkedserver
'ITSV','','SQLOLEDB','远程服务器名或ip地址'
--查询
select*
FROMopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')
--把本地表导入远程表
insertopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')
select*from
本地表
--更新本地表
updateb
setb.列B=a.列B
FROMopenquery(ITSV,
'SELECT*FROM数据库.dbo.表名')asa
innerjoin
本地表bona.列A=b.列A
--3、opendatasource/openrowset
SELECT
*
FROM
opendatasource('SQLOLEDB','DataSource=ip/ServerName;UserID=登陆名;Password=密码').test.dbo.roy_ta
--把本地表导入远程表
insertopendatasource('SQLOLEDB',
'DataSource=ip/ServerName;UserID=登陆名;Password=密码').数据库.dbo.表名
select*from
本地表
SQLServer基本函数
SQLServer基本函数
1.字符串函数
长度与分析用
1,datalength(Char_expr)
返回字符串包含字符数,但不包含后面的空格
2,substring(expression,start,length)
取子串,字符串的下标是从“1”,start为起始位置,length为字符串长度,实际应用中以len(expression)取得其长度
3,right(char_expr,int_expr)
返回字符串右边第int_expr个字符,还用left于之相反
4,isnull(
check_expression,
replacement_value)如果check_expression為空,則返回replacement_value的值,不為空,就返回check_expression字符操作类
5,Sp_addtype
自定義數據類型
例如:
EXECsp_addtypebirthday,datetime,'NULL'
6,setnocount{on|off}
使返回的结果中不包含有关受Transact-SQL语句影响的行数的信息。如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。SETNOCOUNT设置是在执行或运行时设置,而不是在分析时设置。
SETNOCOUNT为ON时,不返回计数(表示受Transact-SQL语句影响的行数)。 SETNOCOUNT为OFF时,返回计数
常识
在SQL查询中:
from
后最多可以跟多少张表或视图:
256
在
SQL
语句中出现
Orderby
,
查询时,
先排序,后取
在
SQL
中,一个字段的最大容量是
8000
,而对于
nvarchar(4000)
,
由于
nvarchar
是Unicode码。
SQLServer2000
同步复制技术实现步骤
一、预备工作
1.
发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户
--
管理工具
--
计算机管理
--
用户和组
--
右键用户
--
新建用户
--
建立一个隶属于administrator组的登陆windows的用户(SynUser)
2.
在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作:
我的电脑--D:\新建一个目录,名为:PUB
--
右键这个新建的目录
--
属性--共享
--
选择"共享该文件夹"
--
通过"权限"按纽来设置具体的用户权限,保证第一步中创建的用户(SynUser)具有对该文件夹的所有权限
--
确定
3.
设置SQL代理(SQLSERVERAGENT)服务的启动用户(发布/订阅服务器均做此设置)
开始--程序--管理工具--服务
--
右键SQLSERVERAGENT
--
属性--登陆--选择"此账户"
--
输入或者选择第一步中创建的windows登录用户名(SynUser)
--"
密码"中输入该用户的密码
4.
设置SQLServer身份验证模式,解决连接时的权限问题(发布/订阅服务器均做此设置)
企业管理器
--
右键SQL实例--属性
--
安全性--身份验证
--
选择"SQLServer和Windows"
--
确定
5.
在发布服务器和订阅服务器上互相注册
企业管理器
--
右键SQLServer组
--
新建SQLServer注册...
--
下一步--可用的服务器中,输入你要注册的远程服务器名--添加
--
下一步--连接使用,选择第二个"SQLServer身份验证"
--
下一步--输入用户名和密码(SynUser)
--
下一步--选择SQLServer组,也可以创建一个新组
--
下一步--完成
6.
对于只能用IP,不能用计算机名的,为其注册服务器别名(此步在实施中没用到)
(
在连接端配置,比如,在订阅服务器上配置的话,服务器名称中输入的是发布服务器的IP)
开始--程序--MicrosoftSQLServer--客户端网络实用工具
--
别名--添加
--
网络库选择"tcp/ip"--服务器别名输入SQL服务器名
--
连接参数--服务器名称中输入SQL服务器ip地址
--
如果你修改了SQL的端口,取消选择"动态决定端口",并输入对应的端口号
二、正式配置
1
、配置发布服务器
打开企业管理器,在发布服务器(B、C、D)上执行以下步骤:
(1)
从[工具]下拉菜单的[复制]子菜单中选择[配置发布、订阅服务器和分发]出现配置发布和分发向导
(2)[
下一步]选择分发服务器可以选择把发布服务器自己作为分发服务器或者其他sql的服务器(选择自己)
(3)[
下一步]设置快照文件夹
采用默认\\servername\Pub
(4)[
下一步]自定义配置
可以选择:是,让我设置分发数据库属性启用发布服务器或设置发布设置
否,使用下列默认设置(推荐)
(5)[
下一步]设置分发数据库名称和位置采用默认值
(6)[
下一步]启用发布服务器选择作为发布的服务器
(7)[下一步]选择需要发布的数据库和发布类型
(8)[
下一步]选择注册订阅服务器
(9)[
下一步]完成配置
2
、创建出版物
发布服务器B、C、D上
(1)
从[工具]菜单的[复制]子菜单中选择[创建和管理发布]命令
(2)
选择要创建出版物的数据库,然后单击[创建发布]
(3)
在[创建发布向导]的提示对话框中单击[下一步]系统就会弹出一个对话框。对话框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个大家可以去看看帮助)
(4)
单击[下一步]系统要求指定可以订阅该发布的数据库服务器类型,
SQLSERVER
允许在不同的数据库如orACLE或ACCESS之间进行数据复制。
但是在这里我们选择运行"SQLSERVER2000"的数据库服务器
(5)
单击[下一步]系统就弹出一个定义文章的对话框也就是选择要出版的表
注意:如果前面选择了事务发布则再这一步中只能选择带有主键的表
(6)
选择发布名称和描述
(7)
自定义发布属性向导提供的选择:
是我将自定义数据筛选,启用匿名订阅和或其他自定义属性
否根据指定方式创建发布(建议采用自定义的方式)
(8)[
下一步]选择筛选发布的方式
(9)[
下一步]可以选择是否允许匿名订阅
1)
如果选择署名订阅,则需要在发布服务器上添加订阅服务器
方法:[工具]->[复制]->[配置发布、订阅服务器和分发的属性]->[订阅服务器]中添加
否则在订阅服务器上请求订阅时会出现的提示:改发布不允许匿名订阅
如果仍然需要匿名订阅则用以下解决办法
[
企业管理器]->[复制]->[发布内容]->[属性]->[订阅选项]选择允许匿名请求订阅
2)
如果选择匿名订阅,则配置订阅服务器时不会出现以上提示
(10)[
下一步]设置快照代理程序调度
(11)[
下一步]完成配置
当完成出版物的创建后创建出版物的数据库也就变成了一个共享数据库
有数据
srv1.
库名..author有字段:id,name,phone,
srv2.
库名..author有字段:id,name,telphone,adress
要求:
srv1.
库名..author增加记录则srv1.库名..author记录增加
srv1.
库名..author的phone字段更新,则srv1.库名..author对应字段telphone更新
--*/
--
大致的处理步骤
--1.
在srv1上创建连接服务器,以便在srv1中操作srv2,实现同步
execsp_addlinkedserver'srv2','','SQLOLEDB','srv2
的sql实例名或ip'
execsp_addlinkedsrvlogin'srv2','false',null,'
用户名','密码'
go
--2.
在srv1和srv2这两台电脑中,启动msdtc(分布式事务处理服务),并且设置为自动启动
。我的电脑--控制面板--管理工具--服务--右键DistributedTransactionCoordinator--属性--启动--并将启动类型设置为自动启动
go
--
然后创建一个作业定时调用上面的同步处理存储过程就行了
企业管理器
--
管理
--SQLServer
代理
--
右键作业
--
新建作业
--"
常规"项中输入作业名称
--"
步骤"项
--
新建
--"
步骤名"中输入步骤名
--"
类型"中选择"Transact-SQL脚本(TSQL)"
--"
数据库"选择执行命令的数据库
--"
命令"中输入要执行的语句:execp_process
--
确定
--"
调度"项
--
新建调度
--"
名称"中输入调度名称
--"
调度类型"中选择你的作业执行安排
--
如果选择"反复出现"
--
点"更改"来设置你的时间安排
然后将SQLAgent服务启动,并设置为自动启动,否则你的作业不会被执行
设置方法:
我的电脑--控制面板--管理工具--服务--右键SQLSERVERAGENT--属性--启动类型--选择"自动启动"--确定.
--3.
实现同步处理的方法2,定时同步
--
在srv1中创建如下的同步处理存储过程
createprocp_process
as
--
更新修改过的数据
updatebsetname=i.name,telphone=i.telphone
fromsrv2.
库名.dbo.authorb,authori
whereb.id=i.idand
(b.name<>i.nameorb.telphone<>i.telphone)
--
插入新增的数据
insertsrv2.
库名.dbo.author(id,name,telphone)
selectid,name,telphonefromauthori
wherenotexists(
select*fromsrv2.
库名.dbo.authorwhereid=i.id)
--
删除已经删除的数据(如果需要的话)
deleteb
fromsrv2.
库名.dbo.authorb
wherenotexists(
select*fromauthorwhereid=b.id)
go
相关文章推荐
- 经典SQL语句资料大全之开发案例
- 经典SQL语句大全——(三)经典-数据开发
- sql语句经典,凡是做开发的,用不到这里面绝对不可能!强大
- 面试-一道经典的sql语句题
- SQL语句大全[数据开发-经典]
- 移动设备(Android、Mobile)Sqlite开发必备SQL语句
- 经典SQL语句大全(数据开发-经典)
- 经典SQL语句大全之(数据开发,管理常识)
- 面试-一道经典的sql语句题
- 经典SQL语句大全之数据开发
- SQL网站入侵必备经典语句
- 50个常用的sql语句 (经典的sql面试题目)
- 入侵网站必备Sql语句:(经典语句)
- 入侵网站必备Sql语句:(经典语句)
- 数据开发-经典sql语句
- 【笔试学习工作必备!】六道经典SQL语句题完全掌握SQL语句
- 经典SQL语句资料大全高手必备
- 经典SQL语句大全(绝对的经典)
- 面试必须要知道的SQL语法,语句
- 50个常用SQL语句,太经典了,就转发了