https://www.cnblogs.com/zhangdk/p/oracle_sqlserver.html

只记得 最开始的时候看过
没有具体的了解里面的特点 原作者总结的很好 留下来 以后说不定有用处.

目录

  • 1.符号使用

    • 1.1 :->@
    • 1.2 mod()->%
    • 1.3 ||->+
    • 1.4 off等表别名
    • 1.5 columnnum=1->top 1
    • 1.6 minus->except
    • 1.7 number->decimal
    • 1.8 date -> datetime
  • 2.函数转换
    • 2.1 nvl->isnull
    • 2.2 substr->substring
    • 2.3 decode->case when end
    • 2.4 数据类型转换
    • 2.5 sq_executesql第一个参数必须是nvarchar类型
    • 2.6 instr -> charindex
    • 2.7 分组并合并列
  • 3. 语法规则
    • 3.1 子查询别名
    • 3.2 sql server树形查询
    • 3.3 sql server 使用merge info
    • 3.4 inserted表与deleted表
    • 3.5 insert\update\delete中使用output
    • 3.6 sql语句或存储过程数据库执行很快,程序中执行很慢
      • 3.6.1 程序传递参数类型与数据库不一致
      • 3.6.2 存储过程执行计划过期

最近项目升级,需要把原来的oracle版本改为sql server版本。由于项目的分层设计,主要的修改内容也就是存储过程,sql语句。如今改的七七八八,整理一下踩过的坑,备忘!

1.符号使用

1.1 :->@

带参数的sql语句,oracle的参数标识使用前缀":",sql server前缀"@"。

  • oracle版
SELECT * FROM table1 WHERE column1=:column1
  • sql server版
SELECT * FROM table1 WHERE column1=@column1

带参数的sql语句,在代码中添加参数时,oracle同一个参数可以添加多次,sql server添加多次会报异常。

  • oracle版本
...
db.AddInParameter(cmd, "column1", DbType.String,column1);
db.AddInParameter(cmd, "column2", DbType.String,column2); ... db.AddInParameter(cmd, "column1", DbType.String,column1); ...

oracle可以像上面这样,再次添加同名的参数,但是连接sql server数据库时不允许。

1.2 mod()->%

求余运算

1.3 ||->+

字符串连接符

oracle的||专门用来做字符串拼接,因此类似下面这样的字符串和数字的拼接是可以成功的:

select 'abc'||123 from dual

但是在sql server中类似下面的字符串和数字拼接是无法直接进行的:

select 'abc'+123

sql server倾向于将字符串转为数字,因此报异常。如果要实现字符串拼接的效果,需要做数据类型转换

select 'abc'+convert(varchar(10),123)

这种情况在存储过程等复杂的操作中,做动态sql拼接时,最容易忽略。

1.4 off等表别名

oracle中的表别名off在sql server中是关键字,导致sql语句错误。因此,在使用表别名的时候我们还是尽量避免掉这种类似关键字的命名。

1.5 columnnum=1->top 1

oracle在排序时,可以使用columnnum=1获取第一条记录,sql server排序时可以使用top 1来获取。

1.6 minus->except

oracle的minus对应sql server的except,直接替换

1.7 number->decimal

oracle中的number类型,即使设置了小数位数,比如decimal(18,2),但是数据库不会对插入的数值补零,插入整数就是整数。但是sql server中会根据设置的数据类型,在数字末尾补零以补足小数位。这个差异会影响前端数字的格式化展示。

1.8 date -> datetime

oracle中date数据类型包括日期和时间两部分。

sql server中date只包括日期部分,datetime包括日期和时间两部分,timestamp递增数字,与时间无关。

oracle中timestamp也包括日期和时间两部分,与date的区别主要是相减时,timestamp相减结果单位是秒,date相减结果是天。两个类型可以相互转换。

C#中向sql server中插入日期类型时,C#默认日期是01/01/01 00:00:00,直接插入数据库会导致数据一出,因为C#向sql server中插入datetime数值类型时(DbType.SqlDateTime),有效日期范围为1/1/1753 12:00:00 ~ 12/31/9999 11:59:59 PM。数据库直接导入日期字段,或者直接修改数据库时,是可以设置为 1/1/1 00:00:00的。

2.函数转换

2.1 nvl->isnull

这两个函数完全等价,可以直接替换使用。

2.2 substr->substring

substr(str,startIndex,[length]) oracle中length参数可以省略,默认取到结尾;
substring(str,startIndex,length) sql server中length参数不能省略。
因此做替换时,要根据业务确定截取长度。

2.3 decode->case when end

oracle中的decode函数使用case when end语句替换,对于嵌套的decode函数我们可以通过组合when的逻辑表达式实现。

  • oracle版
select decode(column1,0,'状态1',1,'状态2','其他') from table1; select decode(column1,0,decode(column2,0,'状态1','状态2'),'其他') from table1;
  • sql server版
select case column1when 0 then '状态1' when 1 then '状态2' else '其他' end from table1; select case when column1 = 0 and column2 = 0 then '状态1' when column1 = 0 then '状态2' else '其他' end from table1;

2.4 数据类型转换

  • to_number(str)->convert(int,str)
  • to_char(str)->convert(nvarchar(n),str)
  • to_char(date,'yyyy-MM-dd')->convert(varchar(100),date,23)
  • to_char(date,'yyyy-MM-dd hh24@mi@ss')->convert(varchar(100),date,20)
  • to_char(date,'yyyyMMdd')->convert(varchar(100),date,112)

2.5 sq_executesql第一个参数必须是nvarchar类型

2.6 instr -> charindex

两个函数的实现功能一样,但是参数顺序却不同,一定要注意。

oracle版本

select instr('abcde','c') from dual

sql server版本

select charindex('c','abcde')

2.7 分组并合并列

原始数据结构
学号 | 名字 | 爱好
---|---|---
201012 | 张三 | 篮球
201012 | 张三 | 乒乓球
201013 | 李四 | 唱歌
201012 | 张三 | 羽毛球
201013 | 李四 | 羽毛球
201013 | 李四 | 绘画

目标视图
学号 | 名字 | 爱好
---|---|---
201012 | 张三 | 篮球,乒乓球,羽毛球
201013 | 李四 | 唱歌,羽毛球,绘画

oracle 11g

select 学号,名字,listagg(爱好,',') within group(order by 爱好) from table1 group by 学号,名字

oracle 其他版本

select 学号,名字,wm_concat(爱好) from table1 group by 学号,名字

sql server

select 学号,名字,
stuff((select ','+爱好 from table1 for xml path('')),1,1,'') 爱好 from table1 group by 学号,名字

3. 语法规则

3.1 子查询别名

oracle中子查询作为from中查询目标可以不使用别名,但是sql server中必须命名别名。

oracle版本

select column1,column2,column3,column4
from (select column1,column2,column3,column4 from table1);

sql server版本

select column1,column2,column3,column4
from (select column1,column2,column3,column4 from table1) a;

3.2 sql server树形查询

with定义的sql片段作为查询对象,实现树形查询。

with cte(id,parentId,column1,column2,column3) as
(select column1,column2,column3 from table1--这里可以接收查询参数--where column1 = ''union all select column1,column2,column3 from table1 inner join cte t1 on t1.id = t2.parentId --自下而上查询 --on t1.parentId = t2.id --自上而下查询 ) select * from cte;

3.3 sql server 使用merge info

项目中作为更新或插入场景使用。

merge into table1 t1
using (select @id id,@para1 column1,@para2 column2,@para3 column3) t2 on t1.id = t2.id when matched then update set t1.column1 = t2.column1,t1.column2 = t2.column2,t1.column3 = t2.column3 when not matched then insert(id,column1,column2,column3) values(t2.column1,t2.column2,t2.column3)

其中oracle在一些没有from目标的操作时,使用dual作为操作目标。sql server在这种情况下,直接不写from部分即可。

3.4 inserted表与deleted表

The deleted table stores copies of the affected rows during DELETE and UPDATE statements. During the execution of a DELETE or UPDATE statement, rows are deleted from the trigger table and transferred to the deleted table. The deleted table and the trigger table ordinarily have no rows in common.

deleted表存储受Delete和Update语句操作影响的行的副本。执行delete或update语句期间,受影响的行从触发器所在表转移到deleted表。deleted表和触发器所在表通常没有共同的行。

The inserted table stores copies of the affected rows during INSERT and UPDATE statements. During an insert or update transaction, new rows are added to both the inserted table and the trigger table. The rows in the inserted table are copies of the new rows in the trigger table.

inserted表存储受insert和update语句操作影响的行的副本。执行insert或update事务时,新行被添加到inserted表和触发器所在表。inserted表中的行是触发器所在表新行的副本。

An update transaction is similar to a delete operation followed by an insert operation; the old rows are copied to the deleted table first, and then the new rows are copied to the trigger table and to the inserted table.

一个update事务类似于一个delete操作后跟一个insert操作。旧行先拷贝到deleted表,然后新行拷贝到触发器所在表和inserted表。

Use the inserted and deleted Tables

3.5 insert\update\delete中使用output

利用inserted表和deleted表,输出插入后自动生成的id等字段,避免insert后,在执行select查询的繁琐。

insert into table1(column1,column2,column3)
output inserted.id,inserted.time into @para1,@para2 values(@column1,@column2,@column3)

3.6 sql语句或存储过程数据库执行很快,程序中执行很慢

3.6.1 程序传递参数类型与数据库不一致

...
db.AddInParameter(cmd, "column1", DbType.Decimal,column1);
db.AddInParameter(cmd, "column2", DbType.String,column2); db.AddInParameter(cmd, "column3", DbType.String,column3); ...

这里的DbType指定的类型一定要与数据库的数据类型保持一致,否则在执行大量数据查询时,会存在数据类型转换,严重影响sql语句执行效率。其中比较以忽略的类型

varchar -> DbType.AnsiString
nvarchar -> DbType.String

这一对是比较容易不一致的,我们一般给varchar字段和nvarchar字段都传递的DbType.String。这样在数据量小时没有问题,数据量大时会非常慢。

3.6.2 存储过程执行计划过期

由于存储过程是预编译的,在第一次执行的时候,会生成执行计划,以后执行的时候,会使用这个执行计划(除非显示指定重新编译),而不是每次执行时都生成执行计划。当存储过程涉及的对象结构调整,或者相关的数据产生了很大的变化,这可能导致原来的计划不适合当前的现状(执行计划过期),这种情况下应该重新编译存储过程。

exec sp_recompile @objname='存储过程名'

转载于:https://www.cnblogs.com/jinanxiaolaohu/p/10437262.html

[转帖]oracle改版sql server问题点汇总相关推荐

  1. [Oracle][ODBC SQL Server Driver][SQL Server]对象名 'RECOVER.HS_TRANSACTION_LOG' 无效(转)

    原帖由 qingyun 于 2010-6-21 15:44 发表  在写pl/sql的时候,有个很重要的注意点: 比如: begin   update  某个sqlserver的表@dblink名字 ...

  2. Oracle 与SQL Server 2000常用函数对照 [摘抄]

    此文章系摘抄,非原创,供参考. 文中提及函数并非Oracle及SQL Server 的全部功能,尤其分析挖掘函数,并未完全涵盖,请以实际解决问题优先,勿妄谈二者优劣. 1.绝对值 S:select a ...

  3. Oracle和sql server中复制表结构和表数据的sql语句

    在Oracle和sql server中,如何从一个已知的旧表,来复制新生成一个新的表,如果要复制旧表结构和表数据,对应的sql语句该如何写呢?刚好阿堂这两天用到了,就顺便把它收集汇总一下,供朋友们参考 ...

  4. SQL比oracle卡,对比Oracle与SQL Server

    尽管Oracle和SQL Server的定位都是企业级的数据库产品,但是用过它们的DBA应该都知道,Oracle相比于微软数据库平台,在高级特性方面的优势还是挺明显的.特别是数据库高可用性以及安全性上 ...

  5. linux python连接oracle数据库_Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法...

    本文档主要描述了Linux下python数据库驱动的安装和配置,用来实现在Linux平台下通过python访问MySQL.Oracle.SQL Server数据库. 其中包括以下几个软件的安装及配置: ...

  6. sql数据迁移到oracle数据库,从Oracle到SQL Server数据库主键的迁移

    由于项目需要要将以前Oracle的数据库转化为SQL Server,今天利用SQL Server的DTD进行数据库的迁移,但导入以后发现只导入了表结构和数据,而表的一些主键约束都没导过来,感觉很郁闷, ...

  7. oracle的优化适用于mysql吗_性能优化之数据库优化,适用于Sqlite、Mysql、Oracle、Sql server,详细介绍了索引和事务及部分针对Sqlite的优化...

    本文为性能优化的第一篇--数据库性能优化,原理适用于大部分数据库包括Sqlite.Mysql.Oracle.Sql server,详细介绍了索引(优缺点.分类.场景.规则)和事务,最后介绍了部分单独针 ...

  8. Oracle与SQL Server在企业应用中的比较(转)

    Oracle与SQL Server在企业应用中的比较(转)[@more@] 在我供职的公司不仅仅拥有Oracle数据库,同时还拥有SQL Server数据库,所以我经常遇见人们向我提两种问题. 第一种 ...

  9. oracle sql常用的函数,界别Oracle和SQL Server常用函数

    区分Oracle和SQL Server常用函数 一.数学函数 1.绝对值 S:select abs(-1) value O:select abs(-1) value from dual 2.取整(大) ...

最新文章

  1. 棋盘分割(记忆化搜索)
  2. 幻想英雄2-战神再起折扣号新手入门攻略
  3. golang之正则校验(验证某字符串是否符合正则表达式)
  4. 月薪3W+,人才缺口高达19W,行业大牛5天带你零基础入门数据分析!
  5. MyApps接口引擎,打破跨系统间的壁垒
  6. JavaScript 常见安全漏洞和自动化检测技术
  7. 计算机英语videos啥意思,video是什么意思_video翻译_读音_用法_翻译
  8. 2021-2027中国高效空气过滤器市场现状及未来发展趋势
  9. centos各文件夹作用
  10. 最全搭建自己的SOCKS代理服务器
  11. 物联网:GPRS和NB-IOT
  12. Axure中继器的高级功能
  13. python人民币美元汇率双向兑换计算
  14. web实现地图画标识物
  15. [家里蹲大学数学杂志]第297期丘成桐大学生数学竞赛2014年分析与方程个人赛试题...
  16. Elrs 接收机 设置 Express LRS
  17. 大数据实战项目--中国移动运行分析
  18. C# Graphics类的用法
  19. spss 卡方检验,Logistic回归方法
  20. 组长让我用java定时爬取网页资源?简单啦(附实战源码)

热门文章

  1. ARM 嵌入式入门经验
  2. 还纠结选机器学习还是深度学习?看完你就有数了
  3. static 函数和普通函数
  4. php过滤手机特殊字符,php过滤特殊字符实用函数
  5. html实现照片添加功能,HTML5 Canvas调用手机拍照功能实现图片上传功能(图文详解上篇)...
  6. 047_Unicode对照表十三
  7. 007_Buzz事件
  8. 029_CSS水平对齐
  9. 7开启uasp协议_Dubbo-go 源码笔记(一)Server 端开启服务过程
  10. python3的socket_python2 与 python3 socket编程的一点小区别