SQL Server连接占线

使用ADO及ODBC连接SQL Server时,如果连接没有处理好,很容易出现下面的错误:

[Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt.
连接占线导致另一个hstmt。

[Microsoft][ODBC SQL Server Driver]Connection is busy with results for another command.
连接占线导致另一个命令。

产生这个错误的原因是,在同一个connection中,同时操作了多个数据集。

解决这个问题有两个方法
1、不要在一个connection中,同时打开多个数据集
2、在SQL SERVER2005以上版本,可以使用MARS (Multiple Active ResultSet)。在连接字符串中加上”Mars_Connection=yes;”就可以支持多数据集了。

关于MARS,可以参考这个:
http://msdn2.microsoft.com/en-us/library/ms345109.aspx

Oracle数据泵导入导出

首先要说明一下,数据泵只可以在服务端运行,而且数据泵要用到DIRECTORY对象。

一、新建DIRECTORY并授权

#创建DIRECTORY
CREATE DIRECTORY dump_dir AS 'DIRECTORY_FULL_PATH';

#授权
GRANT READ, WRITE ON DIRECTORY dump_dir TO user_id;

二、数据泵导出数据

#导出表
expdp user_id/user_pwd directory=dump_dir dumpfile=table01.dmp tables=table01 logfile=table01.log

#导出方案
expdp user_id/user_pwd directory=dump_dir dumpfile=schema01.dmp schemas=schema01 logfile=schema01.log

#导出表空间
expdp user_id/user_pwd directory=dump_dir dumpfile=tbs01.dmp tablespaces=tbs01 logfile=tbs01.log

#导出数据库
expdp user_id/user_pwd directory=dump_dir dumpfile=db01.dmp full=y logfile=db01.log

三、数据泵导入数据

#导入表
impdp user_id/user_pwd directory=dump_dir dumpfile=table01.dmp tables=table01 

#导入方案
impdp user_id/user_pwd directory=dump_dir dumpfile=schema01.dmp schemas=schema01

#导入表空间
impdp user_id/user_pwd directory=dump_dir dumpfile=tbs01.dmp tablespaces=tbs01

#导入数据库
impdp user_id/user_pwd directory=dump_dir dumpfile=db01.dmp full=y

Oracle与SQL Server同步技术对比

方式 Oracle SQL Server 说明
备份还原 备份还原 备份还原 简单粗暴,无法实时,无法实现增量
日志备份 备库(Dataguard) 数据库镜像(Database Mirroring)
日志传输(Log Shipping)
读写操作受限
集群 RAC(Real Application Clusters) 集群(Database Cluster) RAC配置复杂,SQL Server集群只有单节点工作。实际存储只有一份。
视图 物化视图(Materialized View) 索引视图(Indexed Views) 不可改表结构,如增加字段等。
数据变更捕获 CDC(Change Data Capture) CDC(Change Data Capture) 不够灵活,无法配置只想获取部分事件,数据量很大。
订阅发布 ogg(Oracle Golden Gate)
流复制(Stream Replication)
高级复制(Oracle advanced Replication)
订阅发布(Publish and Subscribe)
数据库复制(Database Replication)
订阅发布(Publish and Subscribe)
最灵活的方式了,但也有限制。如果ogg在源加一列,或订阅发布的快照过期了,就惨了

Oracle并发查询

1. 第一张表加并发

select /*+ PARALLEL(t1, 5) */count(*) 
from table1 t1, table2 t2 
where t1.pk = t2.pk 

2. 两张表都加并发

select /*+ PARALLEL(t1, 5)  PARALLEL(t2, 5) */count(*) 
from table1 t1, table2 t2 
where t1.pk = t2.pk 

trunc函数示例

1、时间处理

select trunc(sysdate) from dual  
--2011-3-18 今天的日期为2011-3-18

select trunc(sysdate, 'mm')   from   dual  
--2011-3-1 返回当月第一天.

select trunc(sysdate,'yy') from dual  
--2011-1-1 返回当年第一天

select trunc(sysdate,'dd') from dual  
--2011-3-18 返回当前年月日

select trunc(sysdate,'yyyy') from dual  
--2011-1-1 返回当年第一天

select trunc(sysdate,'d') from dual  
--2011-3-13 (星期天)返回当前星期的第一天

select trunc(sysdate, 'hh') from dual   
--2011-3-18 14:00:00 当前时间为14:41   

select trunc(sysdate, 'mi') from dual  
--2011-3-18 14:41:00 TRUNC()函数没有秒的精确

2、数字处理

select trunc(123.458) from dual 
--123

select trunc(123.458,0) from dual 
--123

select trunc(123.458,1) from dual 
--123.4

select trunc(123.458,-1) from dual 
--120

select trunc(123.458,-4) from dual 
--0

select trunc(123.458,4) from dual  
--123.458

select trunc(123) from dual  
--123

select trunc(123,1) from dual 
--123

select trunc(123,-1) from dual 
--120

MySQL5.7 datetime无法设置默认值为0

在mysql5.7以上版本中,如果datetime默认值为0,则会出现下面的错误:

ERROR 1067 (42000) at line xxx: Invalid default value for 'xxx'

这是因为mysql5.7调整了校验规则,修改一下/etc/mysql/my.cnf配置文件就可以了

[mysqld]
#默认规则
#sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sql-mode="ONLY_FULL_GROUP_BY,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

然后重启mysql就可以啦。

修改Oracle最大连接数

--查询最大连接数
show parameter processes; 

--最大连接数调整为500
alter system set processes=500 scope=spfile; 

not in 优化为 not exists

最近迁移数据库的时候,发现not in比not exists效率差太多了

--not in 直接卡死
insert into table1(
select * from table2 t2@oraclegate where t2.pk not in (select pk from table3 t3));

--not exist则很快处理完成
insert into table1(
select * from table2 t2@oraclegate where not exists (select pk from table3 t3 where t3.pk=t2.pk));

其实数据量并不大,不知道是不是用gateway的问题。

SQL Server:提供的值不是数据类型datetime的有效实例

今天遇到了一个很郁闷的问题,在向SQL Server做Insert时,有几条数据总是提示:
提供的值不是数据类型 datetime 的有效实例

然后根据
参数 131 (“”)
还以为提供的数据为空,查了半天。

最后发现,是提交的日期范围,超出了SQL Server的Datetime的范围。
这提示能再坑一些吗。。。

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 131 (""): 提供的值不是数据类型 datetime 的有效实例。请检查源数据中的无效值。例如,小数位数大于精度的数值类型的数据即为无效值。
	at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(Unknown Source)
	at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source)
	... 45 more

Oracle常用命令

--重新分析表
analyze table table1 compute statistics for table for all indexes for all indexed columns;
--解析执行计划
explain plan for select xx1,xx2,xx3,xx4,xx5 from table1 t1 where t1.xx1 = 'yyy';