Oracle系列——開發中奇葩問題你遇到幾個(一)


      前言:在使用oracle數據進行開發的時候有沒有經常出現一些很奇怪、很納悶、很無厘頭的問題呢。下面是本人使用oracle一段時間遇到的問題小節,在此做個記錄,方便以后再遇到類似的問題能快速解決。如果你是數據庫大蝦或者連續使用oracle數據庫1年以上,這篇文章可以不用看了,此文請直接略過;如果你是數據庫小菜或者剛從sql server轉到使用oracle開發,這些問題可能你曾經遇到或者即將遇到,不信?走着瞧!

 

1、oracle插入數據中文亂碼的問題:

問題描述:在plsql中不管是編輯數據,還是使用insert語句插入,所有的中文都會變成亂碼。

解決方法:

我的電腦---右擊---屬性---高級---環境變量---系統變量---新建

變量名:NLS_LANG

變量值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK,確定后再試試,OK。

 

2 、在plsql中增刪改數據后,查詢看到結果變了,但是程序訪問還是原來的數據。

問題描述:測試需要,在plsql中更新一條數據,然后程序查詢該數據。很奇怪的是程序查詢到的結果總是更新之前的。怎么回事?

解決方法:plsql里面有一個提交的操作,在增刪改數據后,需要提交一下數據,其他進程才能訪問到修改的數據。如果你之前一直用的ms sql server,剛使用oracle的過程中,是否也遇到類似的問題呢。

 

3、在plsql中修改數據后,沒有提交,程序修改這個表數據時就會卡死。因為表被plsql的進程鎖掉了。需要在plsql里面提交數據,這個時候鎖才會釋放。這也就是為什么經常看到下面代碼的原因:

lock (syncCommit)
{
    try
    {
          return context.SaveChanges();
    }
    catch (DbEntityValidationException dbEx)
    {

    }    
}

 

4、使用PowerDesigner設計表后生成DDL語句,執行DDL語句后表、字段、關聯鍵都可以正常生成,可是奇怪的問題就來了,你在plsql里面select * from table1表時,提示表或者視圖不存在,可是你仔細看了好多遍,表明明存在呀。還出鬼了呢。。。

問題描述:我們來看生成的DDL語句

/*==============================================================*/
/* DBMS name:      ORACLE Version 11g                           */
/* Created on:     2015/7/2 15:45:52                            */
/*==============================================================*/


drop table "TB_Department" cascade constraints;

drop table "TB_Menu" cascade constraints;

drop table "TB_MenuRole" cascade constraints;

drop table "TB_Role" cascade constraints;

drop table "TB_UserRole" cascade constraints;

drop table "TB_Users" cascade constraints;

/*==============================================================*/
/* Table: "TB_Department"                                       */
/*==============================================================*/
create table "TB_Department" 
(
   "department_id"      CHAR(10),
   "department_name"    CHAR(10),
   "parent_id"          CHAR(10),
   "level"              CHAR(10),
   "status"             CHAR(10)
);

/*==============================================================*/
/* Table: "TB_Menu"                                             */
/*==============================================================*/
create table "TB_Menu" 
(
   "menu_id"            CHAR(10),
   "menu_name"          CHAR(10),
   "menu_url"           CHAR(10),
   "parent_id"          CHAR(10),
   "level"              CHAR(10),
   "sort_order"         CHAR(10),
   "status"             CHAR(10),
   "remark"             CHAR(10)
);

/*==============================================================*/
/* Table: "TB_MenuRole"                                         */
/*==============================================================*/
create table "TB_MenuRole" 
(
   "id"                 CHAR(10),
   "role_id"            CHAR(10),
   "menu_id"            CHAR(10),
   "role_type"          CHAR(10),
   "button_id"          CHAR(10)
);

/*==============================================================*/
/* Table: "TB_Role"                                             */
/*==============================================================*/
create table "TB_Role" 
(
   "role_id"            CHAR(10),
   "role_name"          CHAR(10),
   "description"        CHAR(10),
   "createtime"         CHAR(10),
   "modifytime"         CHAR(10)
);

/*==============================================================*/
/* Table: "TB_UserRole"                                         */
/*==============================================================*/
create table "TB_UserRole" 
(
   "id"                 CHAR(10),
   "role_id"            CHAR(10),
   "user_id"            CHAR(10)
);

/*==============================================================*/
/* Table: "TB_Users"                                            */
/*==============================================================*/
create table "TB_Users" 
(
   "user_id"            INT,
   "user_name"          CHAR VARYING(0),
   "user_password"      CHAR VARYING(0),
   "fullname"           CHAR(10),
   "department_id"      CHAR(10),
   "status"             CHAR(10),
   "createtime"         DATE,
   "modifytime"         DATE,
   "remark"             CHAR(10)
);

comment on table "TB_Users" is
'用戶信息表';
View Code

解決方案:原來是"號在作怪,由於生成的表里面帶了引號,所以當你用tb_users去查時,提示找不到該表。當你講所有的引號去掉,再重新執行DDL,再去查詢,就這樣正常了。郁悶了好久吧!!如果你也是用過PowerDesigner生成過DDL語句,可能也遇到過問題。

 

5、用EF去連接oracle數據庫時,最開始開發一直用的test用戶,最近項目要上線了,在服務器上面安裝好oracle,建好正式用戶admin,可是奇怪的事情發生了。程序里面該改的配置文件,連接字符串都改了,數據表都創建正常,表空間什么的也都沒問題,可是用admin連接的時候總是提示找不到對應的表或視圖。這又是為什么呢?其實問題就在admin這個用戶那里。

原因分析:因為之前開發一直用的test用戶,拖EF表結構的時候也是test,這樣在edmx文件中就生成了對應的Schema="Test"。而在連接數據庫是,EF自動生成的Sql語句會帶Test用戶,所以導致找不到表。

<EntityContainer Name="ModelStoreContainer">
          <EntitySet Name="TB_DEPARTMENT" EntityType="Self.TB_DEPARTMENT" Schema="Test" store:Type="Tables" />
          <EntitySet Name="TB_MENU" EntityType="Self.TB_MENU" Schema="Test" store:Type="Tables" />
          <EntitySet Name="TB_MENUROLE" EntityType="Self.TB_MENUROLE" Schema="Test" store:Type="Tables" />
          <EntitySet Name="TB_ROLE" EntityType="Self.TB_ROLE" Schema="Test" store:Type="Tables" />
          <EntitySet Name="TB_USERROLE" EntityType="Self.TB_USERROLE" Schema="Test" store:Type="Tables" />
          <EntitySet Name="TB_USERS" EntityType="Self.TB_USERS" Schema="Test" store:Type="Tables" />

 

解決方案:重新生成表結構,或者手動改掉Schma的值。

 

6、查詢時,有時在PL/SQL里面可以用中文模糊搜索,但是在程序調試中使用中文模糊搜索時總查詢不到記錄。

原因分析:由於PL/Sql里面進行過自動編碼,所以支持中文檢索,當程序用sql語句查詢時如果沒有設置編碼的話可能查不到中文。

解決方案:需要在web.config配置文件加上 Unicode=true;
<property name="connection.connection_string">User ID=mall;Password=super123;Unicode=true;Data Source=EIPUAT</property>

 

7、oracle里面新建用戶的時候,用戶會有一個默認表空間,而此用戶是無法訪問到其他表空間下面的數據表的。這個時候需要修改用戶的默認表空間或者表的所屬表空間。

(1)修改表的表空間語句:

alter table TABLE_NAME move tablespace TABLESPACENAME 

 

(2)修改默認用戶的表空間:

  alter user user_name default tablespace tablespace_name;

 

8、oracle創建自增序列。如果在sql server里面,只需要給主鍵設置自增長就行了。oracle可沒有這玩意兒,怎么辦?

解決方案:

(1) 創建自增序列,在PLSql里面的SQL 窗口中執行如下語句,創建自增序列TB_TRIAL_PROCESS_SQE

create sequence TB_TRIAL_PROCESS_SQE
minvalue 1 
maxvalue 99999999
increment by 1
start with 1; /*步長為1*/
/*創建觸發器*/
DROP TRIGGER TB_TRIAL_PROCESS_TRI;
create or replace trigger TB_TRIAL_PROCESS_TRI
before insert on TB_TRIAL_PROCESS /*觸發條件:當向表TB_TRIAL_PROCESS 執行插入操作時觸發此觸發器*/
for each row/*對每一行都檢測是否觸發*/
begin/*觸發器開始*/ 
select TB_TRIAL_PROCESS_SQE.NEXTVAL into :new.trial_id from dual;  /*觸發器主題內容,即觸發后執行的動作,在此是取得序列dectuser_tb_seq的下一個值插入到表dectuser中的userid字段中*/
end; /*退出sqlplus行編輯*/

 

(2) nhibernate的xml里面配置這個序列
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="E2E.Model.TB_TRIAL_PROCESS, E2E.Model" table="TB_TRIAL_PROCESS">
    <id name="TRIAL_ID" type="Decimal" unsaved-value="0">
      <column name="TRIAL_ID" sql-type="NUMBER" not-null="true" unique="true"/>
      <generator class="sequence">
        <param name="sequence">TB_TRIAL_PROCESS_SQE</param>
      </generator>
    </id>

 

9、oracle里面經常會遇到表被鎖定的情況,有時需要手動解鎖。

查看系統的鎖語句:

select sess.sid, 
sess.serial#, 
lo.oracle_username, 
lo.os_user_name, 
ao.object_name, 
lo.locked_mode 
from v$locked_object lo, 
dba_objects ao, 
v$session sess 
where ao.object_id = lo.object_id and lo.session_id = sess.sid;

殺掉鎖表進程語句:(上面的語句會得到兩個字段SID和serial#)

alter system kill session 'SID,serial#';/*將上面語句查詢到的SID和serial#復制到本語句的相應位置執行即可*/

 

10、C#程序里面同時執行多條SQL語句,於此同時又不方便使用存儲過程或數據庫事務。一般是增刪改語句。

解決方案:如果你將多條SQL語句用分號隔開放在plsql中執行是可以得到結果的。但是在程序里面直接傳多條SQL語句時則會提示錯誤。這個時候需要在這多條SQL語句的前后分別加上begin和end。這樣就能解決問題。記得原來在SQL Server里面直接這樣傳多條sql語句是可以的。但在oracle里面需要這么處理下。

 

11、未完待續......

 

以上是本人在使用oracle開發過程中經常遇到的問題的一些小結。目前為止先整理這么多,后續會將這個序列繼續下去。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM