移植过程:采用的
oracle
的移植工具
Migration WorkBenth
。
移植注意事项:
1.
移植前要在
ODBC
中建立
DSN
,由于移植的是
sql server 2000
,驱动选
sql server
。
2.
在
oracle
实例中建立登陆用户,包括用户名和密码,并赋予权限(
connect
,
resource
和
dba
)。这在使用
WorkBenth
过程中是要填写的内容。
3.
移植过程分为获取
sql server Model
,建立
oracle Model
和导入数据三部分。
4.
移植后我们会发现在
oracle
实例中有两个方案生成:
omwb_emulation
和
sa
。其中
omwb_emulation
可以不予理会,它主要提供了弱游标,供
sa
方案中的存储过程调用。对于方案
sa
我们会注意到几点:原来
sql server
中的数据,包括表,视图,存储过程,索引等都在这个方案中存放;原来
sql server
表中的种子类型数据在方案
sa
中被统一管理,放在“序列”中;
原来的数据库名称
xihang_info
现在是方案
sa
中的表空间。
移植后注意事项:
1.
因为应用程序使用的是
ODBC,
涉及到几个连接字符
: dsn username
和
password
。由于应用程序中的连接字符串是
conn.Open("sczb","sczb","sczbpw")
,而现有的
schema
是
sa
,连接失败。现在有两种方案:改连接字符串或从新建立一个方案
sczb
。这里我们采用了第二种方案,新建方案
sczb
。
方法是:先新建用户
sczb,
密码是
sczbpw,
权限是
connect
,
resource
,
dba
;然后将方案
sa
导入到方案
sczb
中(若是导入到另外机器上,方案
omwb_emulation
一并导出再导入)。
2.
在
sczb
中修改视图和存储过程。修改视图只要把
sql
语句中的方案名
sa
删除或改为即可。存储过程需要修改的内容比较多,具体见下:
修改存储过程:
1.
修改临时表
SQL
的临时表用
#
或
##
开头,使用完后自动释放,
ORACLE
的临时表则存在数据库中,每个会话的数据都互不干涉。
语法分别为:
CREATE TABLE #TEMP
(
ID INT
,
NAME VARCHAR
(
20
))
CREATE GLOBAL TEMPORARY TABLE TEMP
(
ID INT
,
NAME VARCHAR
(
20
))
2. IDENTITY
字段
Oracle
不支持自增长类型,在向表中插入含有
IDENTITY
字段的记录时,要显示声明。例如:
Insert into tbl values
(序列名
.nextval,
字段
1
,字段
2
,。。。)。
3.
SQL
与
ORACLE
的游标
SQL
的游标用
@@FETCH_STATUS
判断是否还有数据,
ORACLE
的游标用
%FOUND
、
%NOTFOUND
来判断游标是否结束。
4.
连接字符串:
SQL
的字符串连接用
+
号,
ORACLE
字符串连接用
||
,单引号可以做转义符。因为在
sql server
中
number
类型的“
+
”运算也用到
”+”,
因此在移植后
oracle
对于
number
类型的“
+
”有时识别不出来,而作为字符连接来处理。
5.
游标的名称在移植后会有重复。不允许。
6.
日期类型数据要注意
其格式不同于
sql server
中的“
yyyy-mm-dd
”格式,而是“
dd-x
月
-yyyy
“格式。要用
to_char(?,’yyyy-mm-dd’)
处理成
sql server
一样的格式。
7.
oracle
获取
sql
语句所影响的行数时,不像
sql server
中
@@rowcount
直接获取那么简单,要分以下三种情况。
Oracle
中对于隐性游标,获取行数的方法是通过
SQL%rowcount
直接获得。
对于显性游标获取行数通过
cursor_name%rowcount
获得,但有有以下
sql
语句:
For index in cusor_name loop
变量名:
=cursor_name%rowcount;
End loop;
Fetch into
语句的话,
rowcount=1
8.
获得年,月,日在
oracle
中不支持
year
(),
month
()和
day
()函数。
解决的方法是通过
substr
()函数。例如获取‘2000-01-10’的‘年’,可以通过substr(‘2000-01-10’,1,4)得到。
9.
oracle
不支持
case
语句。
在
sql server
中语句:
CASE WHEN (GROUPING(BM_Name2) = 1)THEN '
合计
' ELSE ISNULL(BM_Name2,'
未知
') END AS BM_Name2,
在
oracle
改写为
decode
语句:
decode(GROUPING(BM_Name2),1,'
合计
',nvl(BM_Name2,'
未知
')) BM_Name2
10.
左右连接问题。
在
sql server
的连接语句如:
select a.id
,
b.yueshj from jh_wh_xiangmu as a left join jh_lr_zongliang as b on a.id=b.xiangmid
在
oracle
中应改为:
Select a.id, b.yueshj from jh_wh_xiangmu a, jh_lr_zongliang b where a.id=b.xiangmid(+);
在
sql server
的连接语句如:
select a.id
,
b.yueshj from jh_wh_xiangmu as a left join jh_lr_zongliang as b on trim(a.id)=trim(b.xiangmid)
在
oracle
中应改为:
Select a.id, b.yueshj from jh_wh_xiangmu a, jh_lr_zongliang b where trim(a.id)=trim(b.xiangmid(+))
11
.改好的存储过程,不能编译通过就认为
ok
了。编译通过只能说明在语法上没有问题了,要进一步执行看逻辑上是否还有问题。在编译时产生的错误是
pl/sql
错误,在执行时的错误是
ora
错误。
12.
在
sql/plus
或
worksheet
中执行存储过程的语句是:
execute
存储过程名(‘参数
1
‘,’参数
2
‘,。。)
但在执行返回多条记录集的存储过程,也就是参数中含有
RC1 IN OUT Omwb_emulation.globalPkg.RCT1
的存储过程时,执行起来略有不同。在
sql plus
中执行的语法如下:
Sql
〉
var rc1 refcursor;
Sql
〉
execute pro_name(‘
参数
1
‘,’参数
2
‘,:
rc1
,。。
)
;
Sql
〉
print rc1
;