:= 是PL/SQL语言里面的赋值
我们提供的服务有:网站制作、网站设计、微信公众号开发、网站优化、网站认证、将乐ssl等。为数千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的将乐网站制作公司
这段代码是
INSTEAD OF 触发器的一个例子。这类触发器主要用于更新有两张或两张基本表所得到的视图。
new.row_name 这个是讲你的内存中存在着两张表,一张为new, 另一张为old,这两张表的表结构跟你的视图时一样的。这两张表用的时候前面加上:访问
服务器内存不足了。
你的数据库查询消耗过多内存,或者是有其他的应用程序装在服务器上,占用了过多内存,还有你不要开启AWE,这个在03的系统上有很大的限制。让数据库自动分配内存吧。
用SQLPROFILER监视你的查询,时间超过2秒的查询,然后尝试优化它们。
楼主的语句本来就运行不了,上边那个瞎复制,都不运行一遍发什么发。oracle和sqlserver下运行语句如下:
select a.ticket_id,a.txn_station,b.txn_station from
(select row_number() over (partition by ticket_id order by txn_time) rn,subway.* from subway) a,
(select row_number() over (partition by ticket_id order by txn_time) rn,subway.* from subway) b
where a.ticket_id=b.ticket_id and a.trans_code=0 and b.trans_code=1 and a.txn_stationb.txn_station and a.rn=b.rn-1
order by a.ticket_id
结果:
其他数据库另外说明
简介
我最近参与了将一个Sybase数据库移植到MicrosoftSQLServer
2000上的项目,我在这一项目上获得的经验,将对Sybase数据库管理员把Sybase数据库移植到SQLServer2000平台上有一定的帮助。
尽管二者之间的一些差别是相当大的,例如Sybase数据库管理系统中的存储过程在SQL
Server就不能被编译,而其它差别则不太大。在完成这一转换前,对脚本文件和存储过程中编程逻辑的行为和结果进行测试是很有必要的。
在下面的部分中,我们将讨论这二种数据库系统之间的一些主要的不同点,在移植的规划阶段,我们必须仔细研究这些区别。
数据兼容模式
对SQLServer2000和Sybase之间的一些兼容性差别的一个临时性解决方案是改变SQL
Server中的数据库兼容性级别,使之与Sybase相符。为此,我们可以使用sp_dbcmptlevel存储过程。
下面表中的语句和结果显示出不同版本数据库之间的差别:
(Untitled-1)
注意:
1、当兼容性模式被设置为70时,下面的词汇不能被用作对象名和标识符:BACKUP、DENY、PRECENT、RESTORE和TOP。
2、当兼容性模式被设置为65时,下面的词汇不能被用作对象名和标识符:AUTHORIZATION、CASCASE、CROSS、 DISTRIBUTED、ESCAPE、FULL、INNER、JOIN、LEFT、OUTER、PRIVILEGES、RESTRICT、RIGHT、 SCHEMA和WORK。
下面是sp_dbcmptlevel的语法:
sp_dbcmptlevel[[@dbname=]name][,[@new_cmptlevel=]version]
@dbname是用于检查和改变兼容性水平的数据库名字。
@new_cmptlevel决定数据库被设置的兼容性水平(将它设置为70、65、60,缺省值为NULL)。
例如:
sp_dbcmptlevelpubs
这一行代码返回下面的结果:
Thecurrentcompatibilitylevelis70.(当前的兼容性级别为70。)
现在我们来看一下另外一个例子:
sp_dbcmptlevelpubs,65
它返回如下的结果:
DBCCexecutioncompleted.(DBCC执行结束。)
果DBCC打印出错误信息,则需要与系统管理员联系。我们可以使用rerunsp_dbcmptlevel验证pubs数据库是否修改得正确:
sp_dbcmptlevelpubs
它返回下面的结果:
Thecurrentcompatibilitylevelis65(当前的兼容性级别为65。)
除了上面的例子外,兼容性级别的差别还扩展到了保留字。Sybase和SQL
Server都有许多不能被用作数据库中对象名字的的保留字,二种产品的保留字相似,但并不完全相同。
由于能够在Sybase中使用的对象可能不能在SQLServer中使用,这一问题使得由Sybase向SQL
Server的移植凭添了许多困难。下面是在SQL
Server中是保留字,而在Sybase中不是保留字的词汇清单。
注意:名字为下列清单中词汇的Sybase数据库中的对象在移植到SQL
Server数据库时必须换为其它名字。
BACKUPCOLUMNCOMMITTEDCONTAINSCONTAINSTABLE
CROSSCURRENT_DATE
CURRENT_TIMECURRENT_TIMESTAMPCURRENT_USER
DENYDISTRIBUTEDFILEFLOPPY
FREETEXT
FREETEXTTABLEFULLIDENTITYCOLINNERJOIN
事务管理模式
SybaseSQLServer
Setchained[on:off]Setimplicit_transactions
[on:off]
在Sybase中使用下面的代码判断事务模式:
SELECT@@tranchained
GO
下面是可能返回的结果:
0表明使用的是非链锁式事务模式
1表明连接运行在链锁模式下
在SQLServer中使用下面的代码判断事务模式:
IF(@@options2)0
on
ELSE
PRINToff
下面是可能的返回结果:
0off
0on
隔离水平
在一个关系数据库这样的多线程应用软件中,数据库引擎对运行的进程间的数据是如何被隔离的管理是非常重要的,在表示隔离水平时,Sybase和SQL
Server的语法是不同的。下面的表格表明了Sybase和SQLServer在表示隔离水平时的差别。
SybaseSQL
Server
0READUNCOMMITTED
1READCOMMITTED
2REPEATABLEREAD
3
SERIALIZABLE
游标语法
二种产品中存储过程的创建和执行基本相似,但在移植时,游标语句中的一些例外是我们应当注意的。下面是一个例子:
CREATEPROCEDUREsql_cursorAS
DECLARE@lnamechar(20),@fname
char(20)
DECLAREmycursorCURSORFOR
SELECTau_lname,au_fnameFROM
authors
OPENmycursor
FETCHFROMmycursorINTO@lname,@fname
WHILE@@
FETCH_STATUS=0
/*Sybase数据库使用@SQLSTATUS而不是@@FETCH_STATUS*/
BEGIN
FETCHFROMmycursorINTO@lname,@fname
/*
**
这里应当是一些业务逻辑
*/
END
CLOSEmycursor
DEALLOCATE/*
Sybase数据库在这里需要CURSOR这个词*/mycursor
SybaseSQLServer
Fetch命令执行成功00
Fetch命令执行失败1-2
没有可存取的记录了2
-1
退回触发器
SQLServer中不存在这个命令,因此在向SQL
Server移植时,使用了ROLLBACKTRIGGER命令的Sybase存储过程必须被进行修改。在修改带有触发器的数据库表中的数据时,使用ROLLBACK
TRIGGER命令容易引起误解,一个ROLLBACK
TRIGGER命令只退回触发器以及触发触发器的数据修改,如果已经被提交了,则事务的其它部分会继续,被写到数据库中。因此,事务中的所有语句可能没有被成功地完成,但数据已经被提交了。
下面是Sybase数据库中一个使用ROLLBACK
TRIGGER的样例触发器:
CREATETABLEtable1(aint,bint)
GO
CREATETRIGGERtrigger1ontable1
FORINSERT
AS
IFEXISTS(SELECT1FROMinsertedWHEREa=
100)
BEGIN
ROLLBACKTRIGGERwithRAISERROR50000Invalidvalueforcolumn
a
END
INSERTINTOtable2
SELECTa,GETDATE()from
inserted
RETURN
GO
在上面的代码中,除非a=100,则所有插入table1的数据也被作为审计行插入table2中,如果a=100,ROLLBACK
TRIGGER命令被触发,而INSERT命令没有被触发,批命令的其它部分继续执行,这时会出现错误信息,表明在一个INSERT命令中出现了错误。下面是所有的INSERT命令:
BEGINTRAN
INSERTINTOtable1VALUES(1,1)
INSERTINTOtable1VALUES
(100,2)
INSERTINTOtable1VALUES(3,3)
GO
SELECT*FROMtable1
在执行这些命令后,table1和table2二个数据库表将各有2个记录,Table1表中的值为1,1以及3,3,由于ROLLBACK
TRIGGER命令,第二个INSERT命令没有执行;Table2表中的值为1,(当前日期)以及3,(当前日期),由于当a=100时ROLLBACK
TRIGGER被触发,触发器中的所有处理被中止,100没有被插入到Table2表中。
在SQL
Server中模拟这一操作需要更多的代码,外部的事务必须与保存点同时使用,如下所示:
CREATEtrigger1ontable1FOR
INSERT
AS
SAVETRANtrigger1
IFEXISTS(SELECT*FROMinsertedWHEREa
=100)
BEGIN
ROLLBACKTRANtrigger1
RAISERROR50000
ROLLBACK
END
INSERTINTOtable2
SELECTa,GETDATE()FROM
inserted
GO
这一触发器以一个存储点开始,ROLLBACKTRANSACTION只退回触发逻辑,而不是整个事务(规模要小于Sybases数据库中的ROLLBACK
TRIGGER语句。对批命令的修改如下:
BEGINTRAN
SAVETRANsave1
INSERTINTOtable1
VALUES(1,1)
IF@@error=50000
ROLLBACKTRANsave1
SAVETRAN
save2
INSERTINTOtable1VALUES(100,1)
IF@@error=50000
ROLLBACK
TRANsave2
SAVETRANsave3
INSERTINTOtable1VALUES(3,3)
IF@@error
=50000
ROLLBACKTRANsave3
COMMITTRAN
我们可以发现,改变不可谓不大。由于ROLLBACKTRIGGER命令能够使任何批命令不能成功执行,因此在移植的SQL
Server存储过程代码中必须包括另外的逻辑,根据ROLLBACK
TRIGGER的使用,这可能是一个艰巨而必要的任务,没有什么捷径可走。如果在移植后所有的ROLLBACKTRIGGER命令被改变为ROLLBACK
TRANSACTION,触发器的执行也会发生变化,因此我们应当十分小心。
命令优化
SQL
Server能够对SELECT、INSERT、UPDATE和DELETE命令进行优化,Sybase数据库则只支持对SELECT命令进行优化。下面是SQL
Server和Sybase在GUI方面的对比:
SybaseSQL
Server
使用被称作SHOWPLAN的基于文本的查询分析工具使用Query
Analyzer。
在ISQL中启动SHOWPLAN的命令按钮多QueryAnalyzer中启动SHOWPLAN_ALL或
SHOWPLAN_TEXT的命令
SETSHOWPLANONSETSHOWPLAN_ALL
GOGO
临时数据库表的名字
表名字的类型 最大长度
SQLServer表名字 128
SQL
Server临时表名字 116
Sybase表名字 30
Sybase临时表名字 13
数据类型
数据类型SybaseSQLServer
char(n)2558000
varchar(n)255
8000
nchar(n)2554000
nvarchar(n)2554000
binary255
8000
varbinary2558000
注意:
1)SQL
Server中的bit类型数据的值可以被设置为0、1或NULL。
2)Sybase中的bit类型数据的值不可以被设置为NULL。
同一性列
SybaseSQLServer
Numeric(x,0)Tinyint,smallint,int,decimal(x,0)or
numeric(x,0)
打印语法
在进行移植时,所有使用替换语法的打印语句必须被改变为RAISERROR语句。
结论
将Sybase数据库转换为SQL
Server数据库并非是不可能的,但二种产品之间存在许多差异,在转换时需要加以解决。根据应用程序的规模,这种转换可能需要大量的时间。尽管无需重新编写所有的应用程序,但需要完成的工作并不少。
我目前还没有发现这二种数据库间转换的更简单的方法。由于二种产品在许多方面都非常相似,我们非常容易成功地将Sybase数据库转换为SQL
Server数据。
网上其实很多相关文章,你可以搜一下,并不一定需要在这里提问。
转帖一篇给你吧
drop table #Tmp --删除临时表#Tmp
create table #Tmp --创建临时表#Tmp
(
ID int IDENTITY (1,1) not null, --创建列ID,并且每次新增一条记录就会加1
WokNo varchar(50),
primary key (ID) --定义ID为临时表#Tmp的主键
);
Select * from #Tmp --查询临时表的数据
truncate table #Tmp --清空临时表的所有数据和约束
相关例子:
Declare @Wokno Varchar(500) --用来记录职工号
Declare @Str NVarchar(4000) --用来存放查询语句
Declare @Count int --求出总记录数
Declare @i int
Set @i = 0
Select @Count = Count(Distinct(Wokno)) from #Tmp
While @i @Count
Begin
Set @Str = 'Select top 1 @Wokno = WokNo from #Tmp Where id not in (Select top ' + Str(@i) + 'id from #Tmp)'
Exec Sp_ExecuteSql @Str,N'@WokNo Varchar(500) OutPut',@WokNo Output
Select @WokNo,@i --一行一行把职工号显示出来
Set @i = @i + 1
End
临时表
可以创建本地和全局临时表。本地临时表仅在当前会话中可见;全局临时表在所有会话中都可见。
本地临时表的名称前面有一个编号符 (#table_name),而全局临时表的名称前面有两个编号符 (##table_name)。
SQL 语句使用 CREATE TABLE 语句中为 table_name 指定的名称引用临时表:
CREATE TABLE #MyTempTable (cola INT PRIMARY KEY)
INSERT INTO #MyTempTable VALUES (1)
如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建,则 SQL Server 必须能够区分由不同用户创建的表。为此,SQL
Server 在内部为每个本地临时表的表名追加一个数字后缀。存储在 tempdb 数据库的 sysobjects 表中的临时表,其全名由
CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀,为本地临时表指定的表名 table_name 不能超过
116 个字符。
除非使用 DROP TABLE 语句显式除去临时表,否则临时表将在退出其作用域时由系统自动除去:
当存储过程完成时,将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。
所有其它本地临时表在当前会话结束时自动除去。
全局临时表在创建此表的会话结束且其它任务停止对其引用时自动除去。任务与表之间的关联只在单个 Transact-SQL 语句的生存周期内保持。换言之,当创建全局临时表的会话结束时,最后一条引用此表的 Transact-SQL 语句完成后,将自动除去此表。
在
存储过程或触发器中创建的本地临时表与在调用存储过程或触发器之前创建的同名临时表不同。如果查询引用临时表,而同时有两个同名的临时表,则不定义针对哪
个表解析该查询。嵌套存储过程同样可以创建与调用它的存储过程所创建的临时表同名的临时表。嵌套存储过程中对表名的所有引用都被解释为是针对该嵌套过程所
创建的表,例如:
CREATE PROCEDURE Test2
AS
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (2)
SELECT Test2Col = x FROM #t
GO
CREATE PROCEDURE Test1
AS
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (1)
SELECT Test1Col = x FROM #t
EXEC Test2
GO
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (99)
GO
EXEC Test1
GO
下面是结果集:
(1 row(s) affected)
Test1Col
-----------
1
(1 row(s) affected)
Test2Col
-----------
2
当创建本地或全局临时表时,CREATE TABLE 语法支持除 FOREIGN KEY 约束以外的其它所有约束定义。如果在临时表中指定
FOREIGN KEY 约束,该语句将返回警告信息,指出此约束已被忽略,表仍会创建,但不具有 FOREIGN KEY 约束。在 FOREIGN
KEY 约束中不能引用临时表。
考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时,或多个存储过程或函数需要使用表值时,临时表很有用。通常,表变量提供更有效的查询处理。