背景
2020年9月份,在将SQL server内容迁移到openGauss数据库的过程中,由于openGauss开源不久,我在迁移的过程中遇到了许多问题。通过对源码的阅读和实际调试,最后逐个解决。在这里,我对两个数据库之间的不同和相同分别做对比,提供一个实际参考。(之所以列出相同,是为了更放心地使用)
- openGauss版本:1.0.1
- SQL server版本:2008
对比
以下所有内容均基于具体使用,因此将涵盖使用中较基本方面。
整体结构
· 相同
SQL server和openGauss同为关系型数据库,创建数据库和使用基本相同,当然openGauss数据库相比其他开源数据库主要有复合应用场景、高性能和高可用等产品特点,在不同之处基本可以解决。
·相异
SQL server | openGauss | 解决 |
---|---|---|
跨数据库执行表操作和存储过程调用 | 无法跨数据库操作 | 基本可以用openGauss中的多模式实现多数据库,跨模式可以实现跨库 |
同一数据库可以直接用表名调用操作 | 若直接调用会报不相关错误 | 将包括系统表在内的所有表,一切采用显示调用:模式名+数据库名+表名 |
临时数据库TempDB自动存储临时表 | 无临时数据库 | openGauss在pg_temp开头的schema中有系统临时表,当然也有全局和本地两种临时表,创建时指定TEMP或TEMPORARY关键字,可创建为临时表 |
数据类型
·相同
- 数值类型:INT、INTEGER、SAMALLINT、BIGINT包括对应数组基本用法相同。
- 货币类型和布尔类型使用基本相同
- 字符类型:定长和变长的CHAER和VARCHAR用法基本相同;TEXT、name也可互通使用
·相异
SQL server | openGauss | 解决 |
---|---|---|
字符类型:nvarchar(n)用来存储大量中文 | 不存在对应nvarchar(n)的类型 | openGauss中选择nvarchar2(n)存储大量中文,效果一致 |
表操作
·相同
- 创建表和删除表基本相同
- 多表查询基本相同,如下:
3.集函数用法基本一致
·相异
主要是系统表的使用差别
SQL server | openGauss | 解决 |
---|---|---|
sysobjects可用表名查询 | 刚开始使用PG_OBJECT表,此表只能按id查询 | 代替:PG_TABLES中可用表名查询 |
可用系统表sys.columns.object_id查询某表所有列名 | openGauss中可用information_schema模式下的columns表得到某表所有列名 | sys.columns表结构information_schema.columns表结构 |
函数对比
·相同
- while函数、集函数、exist函数等简单函数基本一致
- left(str text, n int)、right(str text, n int)、
length(string bytea, encoding name )
replace(string text, from text, to text)
ltrim(string [, characters])、rtrim(string text [, characters text]
charindex函数
·相异
SQL server | openGauss解决 |
---|---|
if-else函数比较自由 | 完整的if-then-else-end if结构 |
替换子字符串函数stuff ( character_expression1 , start , length , character_expression2 ) | overlay(string placing string FROM int [for int])完美替换stuff()函数 |
自定义函数时比较自由 | 自定义函数格式注意加 |
存储过程
·相同
SQL server和openGauss在存储过程中的相同点较少,基本上的逻辑基本相同
- 存储过程均支持输入(in)、输出(out)参数
- 存储过程答题逻辑相似
·相异
SQL server | openGauss解决 |
---|---|
declare声明在begin-end体内 | declare声明必须在存储过程begin-end体外统一声明 |
由于SQL server的begin-end相当于‘{}’,所以根据使用的函数,或者事务相应添加结构begin-end | 由于begin-end是执行结构,因此,存储过程body中所有添加begin-end结构的都不需要再添加,即整个存储过程一套begin-end结构 |
存储过程中用表创建新表:SELECT * INTO tablename FROM tablename1 | 因为SELECT INTO不能在存储过程中使用,会报错tablename不存在。 解决:使用CREATE TABLE AS语法替代SELECT INTO |
catch错误处理:在有事务时,仍可针对具体语句多次处理 | openGauss中,存储过程begin-end就是一个整体事务,可以方便地在body体最后用others整体处理: |
可用return返回参数 | 存储过程的入参和出参,默认IN,出参时(OUT name nametype) |
exec执行;@是变量必要格式 | execute执行;并不需要@格式 |
动态执行:exec sp_executesql | 动态执行: execute immediate |
- 以上均为问题解决方法,具体语句可以看开源社区的格式openGauss社区
总结
SQL server和openGauss由于都是关系型数据库,大体结构、基本数据类型、表操作和函数重合点很高,但是存储过程方面基本上需要全部仔细修改,逐渐调试并找到解决办法。以上所有都来自于实操,并成功迁移。
最后修改时间:2020-12-29 21:53:00
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。