- 浏览: 241982 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
huangtut:
popdyc 写道请问作者有没有遇到过Intellij 插件开 ...
IntelliJ 9 插件开发 -
popdyc:
请问作者有没有遇到过Intellij 插件开发中用Runtim ...
IntelliJ 9 插件开发 -
ggd543:
好文,收藏
IntelliJ 9 插件开发 -
fengwei199181:
不错哦。
Groovy 学习 (整理修改自精通Groovy) -- Groovy 介绍与插件的安装 -
zhengweisincere:
我的评论呢?
通过分析SQL语句的执行计划优化SQL(总结)
1、Oracel中的decode
DB2解决方案:用case条件表达式完成。
case两种语法模式:
(1)CASE
WHEN 条件 THEN 结果1
ELSE 结果2
END
(2)CASE 表达式1
WHEN 表达式2 THEN 结果1
ELSE 结果2
END
上面的WHEN可以重复多次,就像C中的SWITCH ..CASE的表达.
例如:
SELECT ORDNO,CUSNO,
CASE MONTH(SHIPDATE)
WHEN ''01'' THEN ''Jan''
WHEN ''02'' THEN ''Feb''
WHEN ''03'' THEN ''Mar''
WHEN ''04'' THEN ''Apr''
WHEN ''05'' THEN ''May''
WHEN ''06'' THEN ''Jun''
WHEN ''07'' THEN ''Jul''
WHEN ''08'' THEN ''Aug''
WHEN ''09'' THEN ''Sep''
WHEN ''10'' THEN ''Oct''
WHEN ''11'' THEN ''Nov''
WHEN ''12'' THEN ''Dec''
END
FROM FILE
应用实例:
Oracle SQL:
-------------------------
select decode(t.organtypecode, ''D'', t.parent, ''S'', t.parent, t.id)
from A_ORGAN t
where t.parent = 35
DB2 SQL:
-------------------------
select case x.organtypecode
when ''D'' then
x.parent
when ''S'' then
x.parent
else
x.id
end
from a_Organ x
where x.parent = 35;
2、Oracle中的Start with...Connect By递归查询
DB2解决方案:用with公共递归表达式来解决。
DB2解决方案:用case条件表达式完成。
Oracle SQL:
-------------------
select t.id
from a_organ t
start with t.id in (select decode(t.organtypecode,
''D'',
t.parent,
''S'',
t.parent,
t.id)
from A_ORGAN
where t.id = 35)
connect by t.parent = prior t.id
DB2 SQL:
-------------------------
WITH FKK(id) as
(select o.id from a_organ o
where o.id=35
UNION ALL
select case x.organtypecode
when ''D'' then x.parent
when ''S'' then x.parent
else x.id
end
from FKK fk, a_organ x
where fk.id=x.parent)
select distinct id from FKK;
3、Oracle中的dual表对应DB2中的SYSIBM.SYSDUMMY1表
DB2解决方案:对应于DB2中的 SYSIBM.SYSDUMMY1表
Oracle SQL:
-------------------------
select 15 as ttt from dual
结果:
ttt
-------
15
DB2 SQL:
-------------------------
select 15 as ttt from SYSIBM.SYSDUMMY1
结果:
ttt
-------
15
4、日期转换问题
DB2解决方案:有相应的函数
Oracle SQL:
-------------------------
select m.*
from dj_mcdj m
where m.mcqc || '' '' like ''%$P%''
and m.xzqhdm || '' '' like ''%$P%''
and m.hylbdm || '' '' like ''%$P%''
and m.blqsrq >= to_date(''$P'', ''yyyy-mm-dd'')
and m.blqsrq < to_date(''$P'', ''yyyy-mm-dd'')+1
DB2 SQL:
---------------------
--------------------
--名称:名称库查询
--作者:雷智民
--日期:2006-10-27
--FOR :DB2
--------------------
select m.*
from dj_mcdj m
where m.mcqc || '' '' like ''%%''
and m.xzqhdm || '' '' like ''%%%''
and m.hylbdm || '' '' like ''%%%''
and date(m.blqsrq) >= date(''1900-01-01'')
and date(m.blqsrq) < date(''2050-01-01'')+1 day
5、nvl 问题
DB2解决方案:利用coalesce(,) 或 value(,)方法。
oracle中的nvl对应db2中的value ,只是oracle中的语法更有宽松一些,在db2中,value要求两个参数必须是同一种类型的,nvl要求则不是很严格,nvl(A,‘’),如果A是数字类型或者日期类型的这个表达式也没有 问题,但是在db2中,若是也这么写的话, value(A,''),那肯定就有问题了,总的来说,基本上是一致的。
6、左右外连接问题
db2的左右外连接的语法和标准sql语法一样,只是没有oracle中的(+)这个简单符号来标记左右外连接,left (right) outer join on
1).内连接INNER JOIN的Oracle和DB2的写法
Oracle可以这样实现? Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no; DB2 可以这样实现? Select * from db2admin.bsempms inner join db2admin.bsdptms on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
2).外连接的Oracle和DB2的写法(右外连接,左外连接,完全外连接,组合外连接)
Oracle可以这样实现?
Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no(+);
Select a.* from bsempms a,bsdptms b wherea.dpt_no(+)=b.dpt_no;
DB2 可以这样实现?
Select * from db2admin.bsempms right outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
Select * from db2admin.bsempms left outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
Select * from db2admin.bsempms full outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
7、LIKE问题
db2中谓词LIKE后边的表达式不支持字段。只支持一下类型:
A constant
A special register
A host variable
A scalar function whose operands are any of the above
An expression concatenating any of the above
(附DB2文档:
使用格式: match-expression LIKE pattern-expression
match-expression
An expression that specifies the string that is to be examined to see if it conforms to a certain pattern of characters.
The expression can be specified by:
A constant
A special register
A host variable (including a locator variable or a file reference variable)
A scalar function
A large object locator
A column name
An expression concatenating any of the above
pattern-expression
An expression that specifies the string that is to be matched.
The expression can be specified by:
A constant
A special register
A host variable
A scalar function whose operands are any of the above
An expression concatenating any of the above
with the following restrictions:
No element in the expression can be of type LONG VARCHAR, CLOB, LONG VARGRAPHIC, or DBCLOB. In addition it cannot be a BLOB file reference variable.
The actual length of pattern-expression cannot be more than 32 672 bytes.
)
DB2中几个隔离级别select..for update with ** 的行锁
看了很多介绍DB2中隔离级别和锁的各种用法和机制,动手做了一个比较详尽的试验,
对于有些结果我还真没想明白。。
在 db2 9 中我做了以下的试验,
Create table RRTest (pkID VARCHAR(20) NOT NULL ,unID1 varchar(20) Not NULL,UnID2 varchar(20) ,"CUSTOMER_ID" VARCHAR(6) ,
"ORDER_TYPE" DECIMAL(2,0) ,
"EXECUTION_TYPE" DECIMAL(2,0) ,
"ORDER_DATE" VARCHAR(8) ,
"ORDER_TIME" VARCHAR(6) ,
"ORDER_DATETIME" TIMESTAMP ,
"SIDE" DECIMAL(1,0) ,
"TRADE_TYPE" DECIMAL(1,0) ,
"ORDER_AMOUNT" DECIMAL(15,2) ,
"ORDER_PRICE" DECIMAL(8,4),
TSID varchar(20) )
insert into RRTest
SELECT Order_ID, Order_ID, Order_ID, CUSTOMER_ID, ORDER_TYPE, EXECUTION_TYPE, ORDER_DATE, ORDER_TIME, ORDER_DATETIME, SIDE, TRADE_TYPE, ORDER_AMOUNT, ORDER_PRICE ,ORDER_ID
FROM DB2INST1.Fx_Order where ORDER_DATE >'20070401'
GO
select count(*) From RRTEST
72239
ALTER TABLE "DB2INST1".RRTest
ADD PRIMARY KEY
(pkID);
CREATE UNIQUE INDEX UNIQINDX ON RRTest(unID1)
CREATE INDEX INDX002 ON RRTest(unID2)
db2 "RUNSTATS ON TABLE DB2INST1.RRTest ON ALL COLUMNS AND INDEXES ALL ALLOW WRITE ACCESS"
db2 connect to db2TT
db2 +c
select * From RRTEST where TSID='20070223ORD01267732' for update with RR
select * From RRTEST where TSID='20070222ORD01266302' for update with RR
select * From RRTEST where TSID='20070223ORD01267732' for update with RS
select * From RRTEST where TSID='20070222ORD01266302' for update with RS
select * From RRTEST where unID1='20070223ORD01267732' for update with RR
select * From RRTEST where unID1='20070222ORD01266302' for update with RR
select * From RRTEST where unID1='20070223ORD01267732' for update with RS
select * From RRTEST where unID1='20070222ORD01266302' for update with RS
select * From RRTEST where unID2='20070223ORD01267732' for update with RR
select * From RRTEST where unID2='20070222ORD01266302' for update with RR
select * From RRTEST where unID2='20070223ORD01267732' for update with RS
select * From RRTEST where unID2='20070222ORD01266302' for update with RS
select * From RRTEST where pkID='20070223ORD01267732' for update with RR
select * From RRTEST where pkID='20070222ORD01266302' for update with RR
select * From RRTEST where pkID='20070223ORD01267732' for update with RS
select * From RRTEST where pkID='20070222ORD01266302' for update with RS
按照以上字段 pkID 是主键,unID1 是唯一健索引,unID2 是普通健索引,TSID 是普通字段,没有在上建立索引。
试验结论:
PK_INDEX UNIQ_INDEX NormalINDEX NO_INDEX
WITH RR 锁行,不锁表 锁行,不锁表 不锁行,不锁表(1) 锁行,锁表
WITH RS 锁行,不锁表 锁行,不锁表 锁行,不锁表 锁行,锁表(2)
锁行是指在一个事务中用某种方式读取并更改了改行数据并显示得指明要修改后,这个事务将锁住改行,直到它提交或者回滚了事务后,才释放该锁。
锁表是指在用以上各种SQL在读取并更改一行的同时锁住了整个表。
对以上红字部分(1)可能有不能理解的是:为什么对普通索引和主键或者唯一健索引的不同结论?
对 PK和UNIQ的解释是因为RR 是可重复的读的级别,对这次检索扫描到的有可能成为自己的潜在检索对象的内容都会锁住,而因为是主键或者唯一健,别的行不可能成为这次这个检索的潜在读的范围,就是对别的数据此事务根本就没有必要锁,任何情况的更改都不可能出现幻读的情况(此表上的约束限制),所以只锁这一行。这么理解对PK,UNIQ没有问题。
但是NormalINDEX 我认为应该是锁住这个表而不是不锁。这点一直没想明白。留待以后再加强理解。
对 RS隔离级别是“锁定检索到的数据行”,是通过SQL检索到的结果进行锁定, PK,UNIQ,INDEX的结论完全都可以理解。 对 tableScan的检索而出现的锁表有些象RR隔离级别的所为。
嗯,想了一圈没想明白,故把详细过程贴出来给自己留个纪念,以供以后遇到此类并发控制程序中注意一下,select * From TTT where ****= ? for update with RR(RS),这里的 *** 可不是随便定义的。
隔离级别分为RR/RS/CS/UR这四个级别。 下面让我们来逐一论述:
1. RR隔离级别: 在此隔离级别下, DB2会锁住所有相关的纪录。 在一个SQL语句执行期间, 所有执行此语句扫描过的纪录都会被加上相应的锁。 具体的锁的类型还是由操作的类型来决定, 如果是读取,则加共享锁; 如果是更新, 则加独占锁。 由于会锁定所有为获得SQL语句的结果而扫描的纪录, 所以锁的数量可能会很庞大, 这个时候, 索引的增加可能会对SQL语句的执行有很大的影响,因为索引会影响SQL语句扫描的纪录数量。
2. RS隔离级别: 此隔离级别的要求比RR隔离级别稍弱,此隔离级别下会锁定所有符合条件的纪录。 不论是读取, 还是更新, 如果SQL语句中包含查询条件, 则会对所有符合条件的纪录加相应的锁。 如果没有条件语句, 也就是对表中的所有记录进行处理,则会对所有的纪录加锁。
3. CS隔离级别: 此隔离级别仅锁住当前处理的纪录。
4. UR隔离级别:此隔离级别下,如果是读取操作,不会出现任何的行级锁。对于非只读的操作,它的锁处理和CS相同。
DB2默认的隔离级别是 CS。即 游标稳定性。
DB2分页查询
SELECT * FROM (Select 字段1,字段2,字段3,rownumber() over(ORDER BY 排序用的列名 ASC) AS rn from 表名) AS a1 WHERE a1.rn BETWEEN 10 AND 20
SELECT * FROM (Select T.*,rownumber() over(ORDER BY T.ID ASC) AS rn from ADMINISTRATOR.TEST_BY_HUFENG T) AS a1 WHERE a1.rn BETWEEN 1 AND 3
1.“||”的字符连接问题
在DB2中是用“||”连接字符串的,这点与别的语言和数据库是使用“+”有很大区别。在使用“||”时经常会出现“[IBM][CLI Driver][DB2/6000] SQL0440N 未找到类型为 "FUNCTION" 命名为 "||" 且具有兼容自变量的已授权例程。 SQLSTATE=42884”的错误,原因是有非字符类型参与了“||”运算,如有变量或字段出现在“||”的运算中,解决办法是把变量或字段传给char()函数再参与运算就OK了。下面举个例子:
select A.INF || '-' || A.IYF || '-01' from tableA A --会出错,INF年份,IYF月份
select char(A.INF) || '-' || char(A.IYF) || '-01' from tableA A --正确
2.时间比较问题
在DB2中不能使用DATEDIFF函数,或者说是我的不能用,那么怎么比较两个时间相差多少并返回以日、月或年等为时间单位的值呢?用timestampdiff()函数!例子:
select timestampdiff(64,char(timestamp(A.DCRAETETIME)- timestamp('2007-5-25-13.56.41'))) from tableA A
--其中64表示返回以月为单位的值
比如现在是oracle是::sql = sql + " and LoginTime > = to_date('"+ startTime + " 00:00:00" + "','yyyy-mm-dd hh24:mi:ss')";
那在DB2里应该怎么写才能实现这个查询啊?
DB2如下
TO_DATE('2000-01-01 10:00:01','yyyy-mm-dd hh24:mi:ss')
3.like后面不能跟字段
如这样写会出错:
select item1 from table1 where item2 like item3||'%'
如果仅仅是想写像上面那样的like,可以用left或substr函数:
select item1 from table1 where left(item2,length(item3))=item3
或
select item1 from table1 where substr(item2,1,length(item3))=item3
oracle
select item1 from table1 where item2 like '%'||item2
db2
select item1 from table1 where substr(item2,abs(length(item2)-length(item3))+1,length(item3)) =item3.
1,isnull convert coalesce function
2,string link SQL char+ convert || char
3,join-condition,It cannot contain any subqueries
4,SQLServer 的 top 或 Oracle rownum函数,在DB2中:
select * from (select ROW_NUMBER() over(ordey org.id desc) as a, org.* from org) as temp where a>=5 and a<=100
或者
select * from org order by org.id desc FETCH FIRST 3 ROWS ONLY
5,len convert length function\
6,to_date日期比较,DB2是TO_DATE('2000-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
7,比较两个时间相差多少并返回以日、月或年等为时间单位的值,用timestampdiff()函数.如select timestampdiff(64,char(timestamp(A.DCRAETETIME)- timestamp('2007-5-25-13.56.41'))) from tableA A
8,HQL语句里以冒号变量名后面是is null的,要转换变量名,如from project where :id is null 转换为DB2的 from project where cast(:id as string) is null
9,DB2 substring涵数是substr(str,strart,count),strart以1开始
DB2解决方案:用case条件表达式完成。
case两种语法模式:
(1)CASE
WHEN 条件 THEN 结果1
ELSE 结果2
END
(2)CASE 表达式1
WHEN 表达式2 THEN 结果1
ELSE 结果2
END
上面的WHEN可以重复多次,就像C中的SWITCH ..CASE的表达.
例如:
SELECT ORDNO,CUSNO,
CASE MONTH(SHIPDATE)
WHEN ''01'' THEN ''Jan''
WHEN ''02'' THEN ''Feb''
WHEN ''03'' THEN ''Mar''
WHEN ''04'' THEN ''Apr''
WHEN ''05'' THEN ''May''
WHEN ''06'' THEN ''Jun''
WHEN ''07'' THEN ''Jul''
WHEN ''08'' THEN ''Aug''
WHEN ''09'' THEN ''Sep''
WHEN ''10'' THEN ''Oct''
WHEN ''11'' THEN ''Nov''
WHEN ''12'' THEN ''Dec''
END
FROM FILE
应用实例:
Oracle SQL:
-------------------------
select decode(t.organtypecode, ''D'', t.parent, ''S'', t.parent, t.id)
from A_ORGAN t
where t.parent = 35
DB2 SQL:
-------------------------
select case x.organtypecode
when ''D'' then
x.parent
when ''S'' then
x.parent
else
x.id
end
from a_Organ x
where x.parent = 35;
2、Oracle中的Start with...Connect By递归查询
DB2解决方案:用with公共递归表达式来解决。
DB2解决方案:用case条件表达式完成。
Oracle SQL:
-------------------
select t.id
from a_organ t
start with t.id in (select decode(t.organtypecode,
''D'',
t.parent,
''S'',
t.parent,
t.id)
from A_ORGAN
where t.id = 35)
connect by t.parent = prior t.id
DB2 SQL:
-------------------------
WITH FKK(id) as
(select o.id from a_organ o
where o.id=35
UNION ALL
select case x.organtypecode
when ''D'' then x.parent
when ''S'' then x.parent
else x.id
end
from FKK fk, a_organ x
where fk.id=x.parent)
select distinct id from FKK;
3、Oracle中的dual表对应DB2中的SYSIBM.SYSDUMMY1表
DB2解决方案:对应于DB2中的 SYSIBM.SYSDUMMY1表
Oracle SQL:
-------------------------
select 15 as ttt from dual
结果:
ttt
-------
15
DB2 SQL:
-------------------------
select 15 as ttt from SYSIBM.SYSDUMMY1
结果:
ttt
-------
15
4、日期转换问题
DB2解决方案:有相应的函数
Oracle SQL:
-------------------------
select m.*
from dj_mcdj m
where m.mcqc || '' '' like ''%$P%''
and m.xzqhdm || '' '' like ''%$P%''
and m.hylbdm || '' '' like ''%$P%''
and m.blqsrq >= to_date(''$P'', ''yyyy-mm-dd'')
and m.blqsrq < to_date(''$P'', ''yyyy-mm-dd'')+1
DB2 SQL:
---------------------
--------------------
--名称:名称库查询
--作者:雷智民
--日期:2006-10-27
--FOR :DB2
--------------------
select m.*
from dj_mcdj m
where m.mcqc || '' '' like ''%%''
and m.xzqhdm || '' '' like ''%%%''
and m.hylbdm || '' '' like ''%%%''
and date(m.blqsrq) >= date(''1900-01-01'')
and date(m.blqsrq) < date(''2050-01-01'')+1 day
5、nvl 问题
DB2解决方案:利用coalesce(,) 或 value(,)方法。
oracle中的nvl对应db2中的value ,只是oracle中的语法更有宽松一些,在db2中,value要求两个参数必须是同一种类型的,nvl要求则不是很严格,nvl(A,‘’),如果A是数字类型或者日期类型的这个表达式也没有 问题,但是在db2中,若是也这么写的话, value(A,''),那肯定就有问题了,总的来说,基本上是一致的。
6、左右外连接问题
db2的左右外连接的语法和标准sql语法一样,只是没有oracle中的(+)这个简单符号来标记左右外连接,left (right) outer join on
1).内连接INNER JOIN的Oracle和DB2的写法
Oracle可以这样实现? Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no; DB2 可以这样实现? Select * from db2admin.bsempms inner join db2admin.bsdptms on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
2).外连接的Oracle和DB2的写法(右外连接,左外连接,完全外连接,组合外连接)
Oracle可以这样实现?
Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no(+);
Select a.* from bsempms a,bsdptms b wherea.dpt_no(+)=b.dpt_no;
DB2 可以这样实现?
Select * from db2admin.bsempms right outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
Select * from db2admin.bsempms left outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
Select * from db2admin.bsempms full outer join db2admin.bsdptms
on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;
7、LIKE问题
db2中谓词LIKE后边的表达式不支持字段。只支持一下类型:
A constant
A special register
A host variable
A scalar function whose operands are any of the above
An expression concatenating any of the above
(附DB2文档:
使用格式: match-expression LIKE pattern-expression
match-expression
An expression that specifies the string that is to be examined to see if it conforms to a certain pattern of characters.
The expression can be specified by:
A constant
A special register
A host variable (including a locator variable or a file reference variable)
A scalar function
A large object locator
A column name
An expression concatenating any of the above
pattern-expression
An expression that specifies the string that is to be matched.
The expression can be specified by:
A constant
A special register
A host variable
A scalar function whose operands are any of the above
An expression concatenating any of the above
with the following restrictions:
No element in the expression can be of type LONG VARCHAR, CLOB, LONG VARGRAPHIC, or DBCLOB. In addition it cannot be a BLOB file reference variable.
The actual length of pattern-expression cannot be more than 32 672 bytes.
)
DB2中几个隔离级别select..for update with ** 的行锁
看了很多介绍DB2中隔离级别和锁的各种用法和机制,动手做了一个比较详尽的试验,
对于有些结果我还真没想明白。。
在 db2 9 中我做了以下的试验,
Create table RRTest (pkID VARCHAR(20) NOT NULL ,unID1 varchar(20) Not NULL,UnID2 varchar(20) ,"CUSTOMER_ID" VARCHAR(6) ,
"ORDER_TYPE" DECIMAL(2,0) ,
"EXECUTION_TYPE" DECIMAL(2,0) ,
"ORDER_DATE" VARCHAR(8) ,
"ORDER_TIME" VARCHAR(6) ,
"ORDER_DATETIME" TIMESTAMP ,
"SIDE" DECIMAL(1,0) ,
"TRADE_TYPE" DECIMAL(1,0) ,
"ORDER_AMOUNT" DECIMAL(15,2) ,
"ORDER_PRICE" DECIMAL(8,4),
TSID varchar(20) )
insert into RRTest
SELECT Order_ID, Order_ID, Order_ID, CUSTOMER_ID, ORDER_TYPE, EXECUTION_TYPE, ORDER_DATE, ORDER_TIME, ORDER_DATETIME, SIDE, TRADE_TYPE, ORDER_AMOUNT, ORDER_PRICE ,ORDER_ID
FROM DB2INST1.Fx_Order where ORDER_DATE >'20070401'
GO
select count(*) From RRTEST
72239
ALTER TABLE "DB2INST1".RRTest
ADD PRIMARY KEY
(pkID);
CREATE UNIQUE INDEX UNIQINDX ON RRTest(unID1)
CREATE INDEX INDX002 ON RRTest(unID2)
db2 "RUNSTATS ON TABLE DB2INST1.RRTest ON ALL COLUMNS AND INDEXES ALL ALLOW WRITE ACCESS"
db2 connect to db2TT
db2 +c
select * From RRTEST where TSID='20070223ORD01267732' for update with RR
select * From RRTEST where TSID='20070222ORD01266302' for update with RR
select * From RRTEST where TSID='20070223ORD01267732' for update with RS
select * From RRTEST where TSID='20070222ORD01266302' for update with RS
select * From RRTEST where unID1='20070223ORD01267732' for update with RR
select * From RRTEST where unID1='20070222ORD01266302' for update with RR
select * From RRTEST where unID1='20070223ORD01267732' for update with RS
select * From RRTEST where unID1='20070222ORD01266302' for update with RS
select * From RRTEST where unID2='20070223ORD01267732' for update with RR
select * From RRTEST where unID2='20070222ORD01266302' for update with RR
select * From RRTEST where unID2='20070223ORD01267732' for update with RS
select * From RRTEST where unID2='20070222ORD01266302' for update with RS
select * From RRTEST where pkID='20070223ORD01267732' for update with RR
select * From RRTEST where pkID='20070222ORD01266302' for update with RR
select * From RRTEST where pkID='20070223ORD01267732' for update with RS
select * From RRTEST where pkID='20070222ORD01266302' for update with RS
按照以上字段 pkID 是主键,unID1 是唯一健索引,unID2 是普通健索引,TSID 是普通字段,没有在上建立索引。
试验结论:
PK_INDEX UNIQ_INDEX NormalINDEX NO_INDEX
WITH RR 锁行,不锁表 锁行,不锁表 不锁行,不锁表(1) 锁行,锁表
WITH RS 锁行,不锁表 锁行,不锁表 锁行,不锁表 锁行,锁表(2)
锁行是指在一个事务中用某种方式读取并更改了改行数据并显示得指明要修改后,这个事务将锁住改行,直到它提交或者回滚了事务后,才释放该锁。
锁表是指在用以上各种SQL在读取并更改一行的同时锁住了整个表。
对以上红字部分(1)可能有不能理解的是:为什么对普通索引和主键或者唯一健索引的不同结论?
对 PK和UNIQ的解释是因为RR 是可重复的读的级别,对这次检索扫描到的有可能成为自己的潜在检索对象的内容都会锁住,而因为是主键或者唯一健,别的行不可能成为这次这个检索的潜在读的范围,就是对别的数据此事务根本就没有必要锁,任何情况的更改都不可能出现幻读的情况(此表上的约束限制),所以只锁这一行。这么理解对PK,UNIQ没有问题。
但是NormalINDEX 我认为应该是锁住这个表而不是不锁。这点一直没想明白。留待以后再加强理解。
对 RS隔离级别是“锁定检索到的数据行”,是通过SQL检索到的结果进行锁定, PK,UNIQ,INDEX的结论完全都可以理解。 对 tableScan的检索而出现的锁表有些象RR隔离级别的所为。
嗯,想了一圈没想明白,故把详细过程贴出来给自己留个纪念,以供以后遇到此类并发控制程序中注意一下,select * From TTT where ****= ? for update with RR(RS),这里的 *** 可不是随便定义的。
隔离级别分为RR/RS/CS/UR这四个级别。 下面让我们来逐一论述:
1. RR隔离级别: 在此隔离级别下, DB2会锁住所有相关的纪录。 在一个SQL语句执行期间, 所有执行此语句扫描过的纪录都会被加上相应的锁。 具体的锁的类型还是由操作的类型来决定, 如果是读取,则加共享锁; 如果是更新, 则加独占锁。 由于会锁定所有为获得SQL语句的结果而扫描的纪录, 所以锁的数量可能会很庞大, 这个时候, 索引的增加可能会对SQL语句的执行有很大的影响,因为索引会影响SQL语句扫描的纪录数量。
2. RS隔离级别: 此隔离级别的要求比RR隔离级别稍弱,此隔离级别下会锁定所有符合条件的纪录。 不论是读取, 还是更新, 如果SQL语句中包含查询条件, 则会对所有符合条件的纪录加相应的锁。 如果没有条件语句, 也就是对表中的所有记录进行处理,则会对所有的纪录加锁。
3. CS隔离级别: 此隔离级别仅锁住当前处理的纪录。
4. UR隔离级别:此隔离级别下,如果是读取操作,不会出现任何的行级锁。对于非只读的操作,它的锁处理和CS相同。
DB2默认的隔离级别是 CS。即 游标稳定性。
DB2分页查询
SELECT * FROM (Select 字段1,字段2,字段3,rownumber() over(ORDER BY 排序用的列名 ASC) AS rn from 表名) AS a1 WHERE a1.rn BETWEEN 10 AND 20
SELECT * FROM (Select T.*,rownumber() over(ORDER BY T.ID ASC) AS rn from ADMINISTRATOR.TEST_BY_HUFENG T) AS a1 WHERE a1.rn BETWEEN 1 AND 3
1.“||”的字符连接问题
在DB2中是用“||”连接字符串的,这点与别的语言和数据库是使用“+”有很大区别。在使用“||”时经常会出现“[IBM][CLI Driver][DB2/6000] SQL0440N 未找到类型为 "FUNCTION" 命名为 "||" 且具有兼容自变量的已授权例程。 SQLSTATE=42884”的错误,原因是有非字符类型参与了“||”运算,如有变量或字段出现在“||”的运算中,解决办法是把变量或字段传给char()函数再参与运算就OK了。下面举个例子:
select A.INF || '-' || A.IYF || '-01' from tableA A --会出错,INF年份,IYF月份
select char(A.INF) || '-' || char(A.IYF) || '-01' from tableA A --正确
2.时间比较问题
在DB2中不能使用DATEDIFF函数,或者说是我的不能用,那么怎么比较两个时间相差多少并返回以日、月或年等为时间单位的值呢?用timestampdiff()函数!例子:
select timestampdiff(64,char(timestamp(A.DCRAETETIME)- timestamp('2007-5-25-13.56.41'))) from tableA A
--其中64表示返回以月为单位的值
比如现在是oracle是::sql = sql + " and LoginTime > = to_date('"+ startTime + " 00:00:00" + "','yyyy-mm-dd hh24:mi:ss')";
那在DB2里应该怎么写才能实现这个查询啊?
DB2如下
TO_DATE('2000-01-01 10:00:01','yyyy-mm-dd hh24:mi:ss')
3.like后面不能跟字段
如这样写会出错:
select item1 from table1 where item2 like item3||'%'
如果仅仅是想写像上面那样的like,可以用left或substr函数:
select item1 from table1 where left(item2,length(item3))=item3
或
select item1 from table1 where substr(item2,1,length(item3))=item3
oracle
select item1 from table1 where item2 like '%'||item2
db2
select item1 from table1 where substr(item2,abs(length(item2)-length(item3))+1,length(item3)) =item3.
1,isnull convert coalesce function
2,string link SQL char+ convert || char
3,join-condition,It cannot contain any subqueries
4,SQLServer 的 top 或 Oracle rownum函数,在DB2中:
select * from (select ROW_NUMBER() over(ordey org.id desc) as a, org.* from org) as temp where a>=5 and a<=100
或者
select * from org order by org.id desc FETCH FIRST 3 ROWS ONLY
5,len convert length function\
6,to_date日期比较,DB2是TO_DATE('2000-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
7,比较两个时间相差多少并返回以日、月或年等为时间单位的值,用timestampdiff()函数.如select timestampdiff(64,char(timestamp(A.DCRAETETIME)- timestamp('2007-5-25-13.56.41'))) from tableA A
8,HQL语句里以冒号变量名后面是is null的,要转换变量名,如from project where :id is null 转换为DB2的 from project where cast(:id as string) is null
9,DB2 substring涵数是substr(str,strart,count),strart以1开始
发表评论
-
MySQL 手册
2009-09-03 14:59 832来源于MySQL官方网站的5.0 ,中文手册。 因为是翻译于英 ... -
SQL Server,Oracle,DB2数据库SQL语句比较
2009-03-22 13:14 14791.1.1 取前n条记录 SQL Server ... -
异常是否会引起oracle事物回滚
2009-02-23 16:21 2179原理上说,异常是不会终止事务的。但是如果异常传递到了调用环境中 ... -
oracle 数据迁移 imp/exp 和 物化视图 的区别
2009-02-23 13:31 4182使用ON PREBUILT MATERIALIZED VIEW ... -
DB2 函数大全
2009-02-22 14:31 1063函数名 函数 ... -
通过分析SQL语句的执行计划优化SQL(总结)
2008-12-03 10:23 4089做DBA快7年了,中间感悟 ... -
Oracle中的Hash Join祥解
2008-12-02 13:41 1899、 hash join概念 ... -
oracle分区表总结(转)
2008-11-27 15:25 1307在ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应 ... -
oracle 索引
2008-11-27 14:04 1448概述 索引在各种关 ... -
常见Oracle HINT的用法
2008-11-27 12:42 13241. /*+ALL_ROWS*/ 表明对语句块选择基于开销的 ... -
start with ... connect by用法简介
2008-11-25 13:32 2250通过START WITH . . . CONNECT BY . ... -
oracle 常用 函数
2008-11-25 10:54 8821、add_months()用于从一个日期值增加或减少一些月份 ... -
oracle 常用 系统查询
2008-11-19 09:32 1042查索引 DBA_INDEXES 或 ALL_INDEXE ... -
使用智能优化器提高Oracle的性能极限
2008-11-04 22:34 842【IT168 技术文档】消耗在准备新的SQL语句的时间是Ora ... -
SQL语句性能调整原则
2008-11-04 22:33 859【IT168 技术文档】一、问题的提出 在应用系统开发初 ... -
Oracle性能调优原则
2008-11-04 22:25 834【IT168 技术文档】任何事情都有它的源头,要解决问题,也得 ... -
新增oracle监听器后 PL/SQL 显示 没有监听器
2008-11-02 23:10 2183oracle的监听器启动不了,于是删除重新建了一个监听器。数据 ... -
oracle Listener
2008-11-02 22:20 5085Oracle数据库监听配置 ... -
oracle sql 优化
2008-09-05 10:28 1067基本的Sql编写注意事项 ... -
转:sqlserver常用函数
2007-06-18 22:48 2517SQL常用字符串函数 一、字符转换函数1、ASCII()返回字 ...
相关推荐
在IT行业中,数据库管理系统(DBMS)是至关重要的工具,其中DB2和Oracle SQL Developer都是业界广泛使用的系统。本文将详细讲解如何使用Oracle SQL Developer连接到IBM的DB2数据库,并介绍涉及的jar包及其作用。 ...
在数据库管理领域,SQL Server、Oracle和DB2是三大主流的关系型数据库管理系统(RDBMS),它们各自拥有独特的特性和优势。以下是对这三个数据库系统的详细比较: 1. SQL Server(微软公司产品): - **易用性**:...
在IT行业中,数据库是数据存储和管理的核心工具,而Oracle、SQL Server和DB2是三种广泛应用的关系型数据库管理系统。为了与这些数据库进行交互,开发者通常需要相应的数据库驱动程序,也就是JDBC驱动。本文将详细...
Oracle SQL 判断值为空OrNull 判断 Oracle SQL 中判断值为空或 Null 的方法有多种,在本文中,我们将介绍 Oracle 和 SQL Server 中的空值判断方法。 Oracle 中的空值判断 在 Oracle 中,可以使用 `NVL` 函数来...
标题“Oracle、DB2、SQL Server”提示我们讨论的是三个主要的关系型数据库管理系统(RDBMS):Oracle、IBM DB2以及Microsoft SQL Server。这些数据库系统在IT领域中广泛用于数据存储、管理和处理,尤其在企业级应用...
### Oracle迁移到DB2 SQL语句差异 在IT项目的实施过程中,可能会遇到客户提出更换数据库的需求,例如从Oracle迁移到DB2。这种情况下,除了要考虑配置上的差异外,还需要关注SQL语句的不同之处。以下是对Oracle与DB2...
【标题】:“支持Oracle MySQL SQL Server DB2等数据库”意味着这款工具具备跨平台数据库管理的能力。这涵盖了市面上常见的四大关系型数据库管理系统(RDBMS),包括Oracle数据库、MySQL开源数据库、Microsoft SQL ...
标题与描述均聚焦于SQL Server, Oracle, 和DB2数据库中的SQL语句比较,这是一个对IT专业人士特别是数据库管理员(DBA)、开发人员以及对数据库技术感兴趣的人来说极为实用的主题。以下是对给定文件中提及的关键知识点...
SQL Monitor for Oracle,MySQL and DB2 是款免费的数据库跟踪工具,专门用来分析CPU使用率高的问题。 软件功能: 1. 监控SQL Server的进程和Job,查看当前执行的SQL/命令,并终止之。 2. 对象浏览器,跟 SQL Server...
mysql oracle sqlserver db2 sbase
ORACLE MYSQL SQLSERVER DB2等数据库转换工具百度云链接,永久有效,版本比较老,可能不支持新版本。
在众多的数据库系统中,SQL Server、Oracle、SYBASE、DB2和INFORMIX是业界广泛使用的主流产品。以下是对这些数据库进行分析比较的一些关键知识点: 1. SQL Server:由微软公司开发,它是一款全面的数据库平台,支持...
SQLMONITOR是一款强大的数据库监控工具,它专门设计用于实时监控Oracle、MySQL和DB2数据库中正在执行的SQL语句。这个工具对于数据库管理员和开发人员来说极其重要,因为它可以帮助他们诊断性能问题,优化查询,以及...
数据库转换工具,可实现oracle,mysql,sqlserver,sybase,db2相互转换
### 四大数据库的比较(SQL Server、Oracle、Sybase和DB2) #### 开放性 **SQL Server:** 仅限于Windows操作系统上运行,缺乏跨平台能力。这对于那些希望在不同操作系统之间灵活迁移的企业来说可能是一个限制因素...
`MODE DB2SQL`也是必须的。 ##### 1.3 创建UDF (用户定义函数) **DB2 标量函数的语法:** ```sql CREATE FUNCTION function_name(parameters) RETURNS return_type LANGUAGE SQL READS SQL DATA RETURN statement ...
DB2、ORACLE SQL写法的主要区别 1、数据类型转换函数 2、Where条件弱类型判断 3、replace关键字 4、子查询别名 5、DATE数据类型的区别 6、分页的处理 7、decode函数 8、NVL函数 9、substr的不同 10、获取操作系统...
迁移工具,用于mysql、oracle、sqlserver、db2等数据库数据表的相互转换
迁移工具版本为hgdb-migration-v4.1.4,瀚高数据库迁移工具支持源端为Oracle、MySQL、SQL Server、DB2、KingbaseV7、KingbaseV8、DM7、DM8、HIGHGO数据库,目标端为HIGHGO、PostgreSQL数据库的自动化迁移,为了能更...