马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
操作被同步到从库上后,则主从都“回天无力”。serveri.声明游标
在这一步中,必要指定游标的属性和依据请求发生的了局集。有两种办法能够指定一个游标。
情势1(ANSI92)
DECLAREcursor_name[INSENSITIVE][SCROLL]CURSOR
FORselect_statement
[FOR{READONLY|UPDATE][OFcolumn_list]}]
情势2
DECLAREcursor_nameCURSOR
[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
FORselect_statement
[FOR{READONLY|UPDATE][OFcolumn_list]}]
INSENSITIVE关头字指明要为检索到的了局集创建一个一时拷贝,今后的数据从这个一时拷贝中猎取。假如在厥后游标处置的过程当中,原有基表中数据产生了改动,那末它们关于该游标而言是不成见的。这类不敏感的游标不同意数据变动。
SCROLL关头字指明游标能够在恣意偏向上转动。一切的fetch选项(first、last、next、relative、absolute)都能够在游标中利用。假如疏忽该选项,则游标只能向前转动(next)。
Select_statement指明SQL语句创建的了局集。TransactSQL语句COMPUTE、COMPUTEBY、FORBROWSE和INTO在游标声明的选择语句中不同意利用。
READONLY指明在游标了局会合不同意举行数据修正。
UPDATE关头字指明游标的了局集能够修正。
OFcolumn_list指明了局会合能够举行修正的列。缺省情形下(利用UPDATE关头字),一切的列都可举行修正。
LOCAL关头字指明游标是部分的,它只能在它所声明的过程当中利用。
GLOBAL关头字使得游标关于全部毗连全局可见。全局的游标在毗连激活的任什么时候候都是可用的。只要当毗连停止时,游标才不再可用。
FORWARD_ONLY指明游标只能向前转动。
STATIC的游标与INSENSITIVE的游标是不异的。
KEYSET指明拔取的行的按次。SQLServer将从了局会合创立一个一时关头字集。假如对数据库的非关头字列举行了修正,则它们对游标是可见的。由于是流动的关头字汇合,以是对关头字列举行修正或新拔出列是不成见的。
DYNAMIC指明游标将反应一切对了局集的修正。
SCROLL_LOCK是为了包管游标操纵的乐成,而对修正或删除加锁。
OPTIMISTIC指明哪些经由过程游标举行的修正大概删除将不会乐成。
注重:
・假如在SELECT语句中利用了DISTINCT、UNION、GROUPBY语句,且在选择中包括了聚合表达式,则游标主动为INSENSITIVE的游标。
・假如基表没有独一的索引,则游标创立成INSENSITIVE的游标。
・假如SELECT语句包括了ORDERBY,而被ORDERBY的列并不是独一的行标识,则DYNAMIC游标将转换成KEYSET游标。假如KEYSET游标不克不及翻开,则将转换成INSENSITIVE游标。利用SQLANSI-92语法界说的游标一样云云,只是没有INSENSITIVE关头字罢了。
ii.翻开游标
翻开游标就是创立了局集。游标经由过程DECLARE语句界说,但实在际的实行是经由过程OPEN语句。语法以下:
OPEN{{[GLOBAL]cursor_name}|cursor_variable_name}
GLOBAL指明一个全局游标。
Cursor_name是被翻开的游标的称号。
Cursor_variable_name是所援用游标的变量名。该变量应当为游标范例。
在游标被翻开以后,体系变量@@cursor_rows能够用来检测了局集的行数。@@cursor_rows为正数时,暗示游标正在被异步迁徙,其相对值(假如@@cursor_rows为-5,则相对值为5)为以后了局集的行数。异步游标利用户在游标被完整迁徙时仍旧可以会见游标的了局。
iii.从游标中取值
在从游标中取值的过程当中,能够在了局会合的每行下去回挪动和处置。假如游标界说成了可转动的(在声明时利用SCROLL关头字),则任什么时候候都可掏出了局会合的恣意行。关于非转动的游标,只能对以后行的下一行实行取操纵。了局集能够取到部分变量中。Fetch命令的语法以下:
FETCH[NEXT|PRIOR|FIRST|LAST|ABSOLUTE{n|@nvar}|RELATIVE{n|@nvar}]
FROM[GLOBAL]cursor_name}|cursor_variable_name}
[INTO@variable_name][,……n]]
NEXT指明从以后行的下一行取值。
PRIOR指明从以后行的前一行取值。
FIRST是了局集的第一行。
LAST是了局集的最初一行。
ABSOLUTEn暗示了局会合的第n行,该行数一样能够经由过程一个部分变量传布。行号从0入手下手,以是n为0时不克不及失掉任何行。
RELATIVEn暗示要掏出的行在以后行的前n行或后n行的地位上。假如该值为负数,则要掏出的行在以后行前n行的地位上,假如该值为正数,则前往以后行的后n行。
INTO@cursor_variable_name暗示游标列值存储的中央的变量列表。该列表中的变量数应当与DECLARE语句当选择语句所利用的变量数不异。变量的数据范例也应当与被选择列的数据范例不异。直到下一次利用FETCH语句之前,变量中的值城市一向坚持。
每次FETCH的实行都存储在体系变量@@fetch_status中。假如FETCH乐成,则@@fetch_status被设置成0。@@fetch_status为-1暗示已抵达了却果集的一部分(比方,在游标被翻开以后,基表中的行被删除)。@@fetch_status能够用来机关游标处置的轮回。
比方:
DECLARE@inamechar(20),@fnamechar(20)
OPENauthor_cur
FETCHFIRSTFROMauthor_curINTO@iname,@fname
WHILE@@fetch_status=0
BEGIN
IF@fname=‘Albert’
PRINT“FoundAlbertRinger”
ELSE
Print“OtherRinger”
FETCHNEXTFROMauthor_curINTO@iname,@fname
END
iv.封闭游标
CLOSE语句用来封闭游标并开释了局集。游标封闭以后,不克不及再实行FETCH操纵。假如还必要利用FETCH语句,则要从头翻开游标。语法以下:
CLOSE[GLOBAL]cursor_name|cursor_variable_name
v.开释游标
游标利用不再必要以后,要开释游标。DEALLOCATE语句开释数据布局和游标所加的锁。语法以下:
DEALLOCATE[GLOBAL]cursor_name|cursor_variable_name
上面给出游标的一个完全的例子:
USEmaster
GO
CREATEPROCEDUREsp_BuildIndexes
AS
DECLARE@TableNamesysname,@msgvarchar(100),@cmdvarchar(100)
DECLAREtable_curCURSORFOR
SELECTnameFROMsysobjectsWHEREtype=’u’
OPENtable_cur
FETCHNEXTFROMtable_curINTO@TableName
WHILE@@fetch_status=0
BEGIN
IF@@fetch_status=-2
CONTINUE
SELECT@msg=“Buildingindexesfortable”+@TableName+”…”
PRINT@msg
SELECT@cmd=“DBCCDBREINDEX(‘”+@TableName+”)”
EXEC(@cmd)
PRINT““
FETCHNEXTFROMtable_curINTO@TableName
END
DEALLOCATEtable_cur
GO
上面的剧本将为PUBS数据库实行sp_BuildIndexes
USEpubs
GO
EXECap_BuildIndexes
注重:下面也是创立用户界说的体系存储历程的示例。
利用一时表
一时表是在TempDB中创立的表。一时表的称号都以“#”开首。一时表的局限为创立一时表的毗连。由于,一时表不克不及在两个毗连之间共享,一旦毗连封闭,一时表就会被抛弃。假如一时表被创立于存储历程当中,则一时表的局限在存储历程当中,大概被该存储历程挪用的任何存储历程当中。假如必要在毗连之间共享一时表,则必要利用全局的一时表。全局的一时表以“##”标记开首,它将一向存在于数据库中,直到SQLServer从头启动。一旦这类一时表创立以后,一切的用户都能够会见到。在一时表上不克不及明白地指明权限。一时表供应了存储两头了局的才能。偶然候,一时表还能经由过程将一个庞大的查询分化成两个查询而取得功能的改良。这能够经由过程起首将第一个查询的了局存在一时表中,然后在第二个查询中利用一时表来完成。当一个年夜表中的某个子集在一个在坐过程当中利用屡次时,倡议利用一时表。在这类情形下,在一时表中坚持数据的子集,以在随后的毗连中利用,如许能年夜年夜改良功能。还能够在一时表中创立索引。
上面我们说了DML的闪回方案。但对于DDL却无能为力,对于大多数的DDL,即使是rowbase格式,二进制日志binlog中仍只记录语句本身。对于删表操作,只记录一个语句droptablet。仅凭这句话,无法还原表的数据。 |