经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库运维 » Oracle » 查看文章
net+Oracle开发过程中遇到的小问题
来源:cnblogs  作者:歌神的卖  时间:2018/9/25 20:04:13  对本文有异议

最新的项目开始使用Oracle后,5个月之间遇到一些在SqlServer中没有遇到的问题,这里记录并贴上一些常用的解决办法。

Oracle相关

一、数据库不同版本还原

刚开始我们一直使用Oracle12C进行开发,到上线服务器时说12C与可能不太稳定,有些问题不好定位就转用11g,这里牵扯到12C导出的DMP文件导入到11G上的问题,导出导入语句:

  1. exp 账号/密码@STO_DataBase file=D:\STO_DataBase.dmp full=y
  2. imp 账号/密码@STO_DataBase file=D:\DataBackUp\STO_DataBase.dmp full=y

导入报异常版本不一样,无法导入,这里用一款小工具可以解决问题下载地址

此处输入图片的描述

二、数据库创建

数据库文件大小受DB_BLOCK_SIZE决定,默认是8K对应的数据库文件是32G,所以创建数据库时数据库的大小不要设置最大值最好设置成无限大,可以多设置几个数据库文件,以免数据库大小不够用引起数据库异常。创建语句:

  1. //创建表空间
  2. CREATE TABLESPACE STO_Data
  3. LOGGING
  4. DATAFILE
  5. 'D:\DataBase\DbFile\STO_DATA.DBF',
  6. 'D:\DataBase\DbFile\STO_DATA1.DBF',
  7. 'D:\DataBase\DbFile\STO_DATA2.DBF'
  8. SIZE 512M
  9. AUTOEXTEND ON
  10. NEXT 512M MAXSIZE unlimited
  11. EXTENT MANAGEMENT LOCAL;
  12. //创建临时表空间
  13. CREATE TEMPORARY TABLESPACE STO_Temp
  14. TEMPFILE 'D:\DataBase\DbFile\STO_Temp.DBF'
  15. SIZE 512M
  16. AUTOEXTEND ON
  17. NEXT 512M MAXSIZE unlimite
  18. EXTENT MANAGEMENT LOCAL;
  19. //创建用户
  20. CREATE USER 用户名 IDENTIFIED BY 用户名密码
  21. DEFAULT TABLESPACE STO_Data
  22. TEMPORARY TABLESPACE STO_Temp
  23. //用户赋权限
  24. grant connect,resource,dba to 用户名

三、常见问题

(1)存储过程参数

存储过程的参数命名最好可以按照规则来否则会有问题,例如:

  1. create or replace procedure Proc_Test(IN_CompanyName in varchar2,
  2. OUT_Table out sys_refcursor) as
  3. begin open OUT_Table for select * from Waybill_Pickup t where t.companyname=IN_CompanyName;
  4. end Proc_Test;

如果参数使用的和数据库中的表字段一样会引起失效,例如:

  1. create or replace procedure Proc_Test(CompanyName in varchar2,
  2. OUT_Table out sys_refcursor) as
  3. begin open OUT_Table for select * from Waybill_Pickup t where t.companyname=CompanyName;
  4. end Proc_Test;

(2)定期释放Temp文件空间

长时间使用会使Temp文件越来越大,而引起某些操作异常。

  1. alter tablespace STO_TEMP shrink space;

(3)索引失效

Oracle批量插入如果是用Oracle.DataAccess.Client.OracleBulkCopy 类,数据在插入过程中会引起索引失效,如果是业务表就会引起业务查询非常缓慢。但是插入效率很高,如果数据库使用读写分离,或者接口采用读写分离的两个表可以通过此方法进行插入,如果遇到索引失效可用以下语句查看和修复。

  1. //查看失效索引
  2. select * from user_indexes where Status='UNUSABLE'
  3. //重建失效索引
  4. begin
  5. FOR cur in (select INDEX_NAME from user_indexes where Status='UNUSABLE') loop
  6. execute immediate 'alter index '|| cur.INDEX_NAME||' rebuild' ;
  7. END LOOP;
  8. end;

(4)遇到问题如何排查

当Oracle遇到内部问题出现异常和挂机后的排查步骤(Oracle服务器)

  1. 查找日志D:\app\Administrator\diag\rdbms\sto_database\stodatabase\alert
  2. 查询跟踪文件D:\app\Administrator\diag\rdbms\sto_database\stodatabase\trace
  3. 然后定位问题解决问题

参考文档

当时遇到的问题是:数据库直接Down掉了,连接时报没有监听程序。重启服务器后过一会数据库就挂掉了
检查Oracle日志:
D:\app\Administrator\diag\rdbms\sto_database\stodatabase\alert
查看Log文件,在日志文件中找到错误信息提示:
此处输入图片的描述

检查跟踪文件
D:\app\Administrator\diag\rdbms\sto_database\stodatabase\trace
在跟踪文件中查看错误信息引起的原因:
根据错误查找出引起错误的SQL语句,最后定位到是单条语句超过65535个参数引起,由于.net中使用了DbDataAdapter进行保存数据,他类似于拼接的Sql语句,更改批次提交数解决问题。

.net相关

一、处理传参和LONG RAW类型

DbCommand处理Oracle数据库默认参数绑定是按次序且不能查询LONG RAW类型,处理SqlServer数据库不用处理,
所以在初始化DbCommand时需要加入如下代码

  1. (cmd as Oracle.DataAccess.Client.OracleCommand).BindByName=true;
  2. (cmd as Oracle.DataAccess.Client.OracleCommand).InitialLONGFetchSize = -1;

二、批量插入

(1)OracleBulkCopy

OracleBulkCopy在Oracle.DataAccess.DLL中,速率很快,但不进行主键和唯一键检查,经常会将唯一索引弄坏,并且在插入过程中普通索引也会失效。

  1. /// <summary>
  2. /// 批量插入数据库
  3. /// </summary>
  4. /// <param name="datatable"></param>
  5. /// <returns></returns>
  6. public string OracleBulkInsert(DataTable datatable)
  7. {
  8. OracleBulkCopy bulkCopy = new OracleBulkCopy(_connStr, OracleBulkCopyOptions.UseInternalTransaction);
  9. try
  10. {
  11. bulkCopy.DestinationTableName = datatable.TableName;
  12. bulkCopy.BulkCopyTimeout = 600000;
  13. bulkCopy.BatchSize = 50000;
  14. if (datatable != null && datatable.Rows.Count != 0)
  15. bulkCopy.WriteToServer(datatable);
  16. return "";
  17. }
  18. catch (Exception ex)
  19. {
  20. throw ex;
  21. }
  22. finally
  23. {
  24. if (bulkCopy != null)
  25. bulkCopy.Close();
  26. }
  27. }

DataTable在插入时应注意字段类型和顺序,可以用以下代码获得表结构

  1. /// <summary>
  2. /// 根据表名获取Table结构
  3. /// </summary>
  4. /// <param name="tableName">表名</param>
  5. /// <returns></returns>
  6. public DataTable InitStructureByTable(string tableName)
  7. {
  8. DataTable dtColums = helper.GetDataSet("select column_name,data_type from user_tab_columns where table_name='" + tableName.ToUpper() + "' order by column_id", null).Tables[0];
  9. DataTable dtNew = new DataTable();
  10. dtNew.TableName = tableName;
  11. //匹配列数
  12. for (int j = 0; j < dtColums.Rows.Count; j++)
  13. {
  14. switch (dtColums.Rows[j][1].ToString().ToUpper())
  15. {
  16. case "DATE":
  17. dtNew.Columns.Add(new DataColumn(dtColums.Rows[j][0].ToString(), typeof(DateTime)));
  18. break;
  19. case "NUMBER":
  20. dtNew.Columns.Add(new DataColumn(dtColums.Rows[j][0].ToString(), typeof(double)));
  21. break;
  22. default:
  23. dtNew.Columns.Add(new DataColumn(dtColums.Rows[j][0].ToString(), typeof(string)));
  24. break;
  25. }
  26. }
  27. return dtNew;
  28. }

(2)DbDataAdapter批量插入

这种插入方式要比OracleBulkCopy要慢,相当于拼接了带参数的插入语句插入,注意UpdateBatchSize数值不要过大,否则可能由于单句Sql语句参数超过65535引起数据库崩溃。

  1. /// <summary>
  2. /// 批量插入数据库
  3. /// </summary>
  4. /// <param name="datatable"></param>
  5. /// <returns></returns>
  6. public string BulkInsertCopy(DataTable datatable)
  7. {
  8. DbDataAdapter adapter = _factory.CreateDataAdapter();
  9. DbCommand cmd = _factory.CreateCommand();
  10. DbCommandBuilder cb = _factory.CreateCommandBuilder();
  11. try
  12. {
  13. adapter.UpdateBatchSize = 200;
  14. using (DbConnection conn = _factory.CreateConnection())
  15. {
  16. conn.ConnectionString = ConnectionString;
  17. conn.Open();
  18. cmd.Connection = conn;
  19. //cmd.Transaction = conn.BeginTransaction();
  20. cb.DataAdapter = adapter;
  21. adapter.SelectCommand = cmd;
  22. adapter.SelectCommand.CommandText = "select * from " + datatable.TableName;
  23. adapter.FillSchema(datatable, SchemaType.Source);
  24. adapter.Update(datatable);
  25. //cmd.Transaction.Commit();
  26. }
  27. return "";
  28. }
  29. catch (Exception ex)
  30. {
  31. //cmd.Transaction.Rollback();
  32. return ex.Message;
  33. }
  34. finally
  35. {
  36. cmd.Dispose();
  37. cb.Dispose();
  38. adapter.Dispose();
  39. }
  40. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号