前言:在使用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 '用戶信息表';
解決方案:原來是"號在作怪,由於生成的表里面帶了引號,所以當你用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開發過程中經常遇到的問題的一些小結。目前為止先整理這么多,后續會將這個序列繼續下去。