国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

用C#通過DatabaseLink連接遠程Oracle數(shù)據(jù)表的錯誤,及其變通方法

2024-07-21 02:17:36
字體:
來源:轉載
供稿:網(wǎng)友
這次做的項目,其中牽扯到跨數(shù)據(jù)庫取數(shù)據(jù)的問題。
大概問題是這樣的:
在一臺服務器上有兩個oracle數(shù)據(jù)庫實例oraour和orahr。
oraour是我們自己建立的,里面有一些表,是和我們這個項目相關的。
orahr是另外一套人事系統(tǒng)所用的,其中有4張表是關于確定使用者身份的(包括用戶名、密碼、電話、部門等信息的)。

現(xiàn)在客戶要求我們自己開發(fā)的系統(tǒng)在登錄時采用人事系統(tǒng)中的用戶數(shù)據(jù),這樣方便管理。
客戶是上帝。

我們想到了一個最直接的方法,就是讓orahr提供一個視圖,里面包含了我們系統(tǒng)登錄所要用到的數(shù)據(jù)。視圖建立好之后,我們的程序在運行時分別向oraour和orahr建立連接,登陸時用orahr連接,判斷用戶名、密碼,并獲取登錄用戶的基本信息。然后就像以前一樣使用oraour連接就可以了。

本以為事情就這么完了,沒想到客戶的一個需求使我們不得不改變策略。
客戶要求:系統(tǒng)中的底層人員填寫的申請單需經(jīng)過3-4級審批,方可生效。
考慮到客戶的多變性,我們決定將客戶要求的3-4級審批改寫成一個n級審批。其實3級審批的寫法跟n級審批差不多,所以我們就決定這么做。

底層用戶5000多名、2層用戶1000多名、3層用戶200多名、4層用戶10名。這樣的數(shù)據(jù)量雖然不大,但是按照我們的想法(將用戶分組,然后根據(jù)組設定審批(因為人事系統(tǒng)給的視圖信息不是很完整,里面缺少人員級別信息)),何況底層用戶可以填寫6種不同的單據(jù),每種單據(jù)的審批流程還不一樣,這樣產(chǎn)生的數(shù)據(jù)量就不少了。要實現(xiàn)上述的功能,我們覺得應該能像訪問本地數(shù)據(jù)表一樣訪問遠程數(shù)據(jù)表(因為牽扯到聯(lián)合查詢),所以就建立了一個databaselink來實現(xiàn)這個功能。一個dblink很快就建立好了,在pl/sql dev中執(zhí)行“select * from [email protected]”能得到我們想要的結果集。但是在c#里就不行。系統(tǒng)返回的錯誤是:ora-02041: 客戶端數(shù)據(jù)庫未開始一個事務處理。

既然錯誤說沒有開始事務,那我們就把要執(zhí)行的sql語句當作一個事務來運行。我們在oracle網(wǎng)站上找到了篇文章http://www.oracle.com/technology/global/cn/pub/articles/price_dbtrans_dotnet.html,里面講如何用oracleconnection對象來創(chuàng)建一個事務。我們按照文章上寫的,創(chuàng)建了一個事務,結果程序還是報這個錯誤。這下該怎么辦呢?我們上網(wǎng)查了一下,也沒查出個所以然來。一般都是說:在一個事務內(nèi)不要連續(xù)進行commit,要在事務結束的時候進行一個commit就行了。但是我們的sql語句僅僅是一個查詢。

快下班了,我們開始想起他的解決辦法,最后想到了下面幾種:
1、在本地建立一個視圖,這個視圖是由查詢dblink中的視圖建立,然后在程序中訪問此視圖。實驗結果還是以出現(xiàn)上述錯誤告終。
2、在本地建立一個表,表結構與遠程視圖結構一致,然后每天將遠程視圖的內(nèi)容更新到本表中。這樣做是一個非常笨的方法,低效率與容易造成數(shù)據(jù)不同步。
3、在本地建立一個表,表結構與遠程視圖結構一致;在遠程視圖上建立觸發(fā)器,當遠程視圖內(nèi)容修改后,觸發(fā)器修改本地的表。還是不行,因為建立在視圖上的觸發(fā)器不會因為基本表的修改而觸發(fā),這個視圖觸發(fā)器只能在有語句向視圖本身作添加、刪除、修改操作時才會觸發(fā)。
4、遠程視圖是由4張基本表建立的,我們就想在本地也建立這4張基本表,然后在遠程數(shù)據(jù)庫上建立觸發(fā)器,每個表建立一個,當基本表數(shù)據(jù)修改時觸發(fā)器會通過dblink修改本地的基本表。為了保護原有的c#程序代碼,我們在本地建立一個視圖,視圖的建立語句與遠程視圖的建立語句一致,這樣就用不到遠程建立的視圖了。最后結果證明這種方法是可行的。

這么一個問題我們兩個人弄了兩天,才算搞定。呵呵。

下面是我今天學習建立觸發(fā)器的經(jīng)驗(oracle數(shù)據(jù)庫):
最基本的觸發(fā)器是針對表的insert、update、delete這三種操作來的。
觸發(fā)器可以建立在表上,也可以建立在視圖上。建立在表上的觸發(fā)器會在表內(nèi)容發(fā)生改變時觸發(fā)。建立在視圖上的觸發(fā)器會在視圖內(nèi)容改變時觸發(fā)。注意,視圖觸發(fā)器僅會在明確對視圖進行操作的sql語句執(zhí)行時才會觸發(fā),當基本表的內(nèi)容發(fā)生改變而引起視圖內(nèi)容變化時,不會觸發(fā)視圖觸發(fā)器。
觸發(fā)器不能建立在dblink的表上,只能在觸發(fā)器里通過dblink更新遠程數(shù)據(jù)庫的表

目前就這么點經(jīng)驗。

下面是建立dblink的代碼:

create public database link ora
  connect to system identified by manager
  using 's-server';

其中的ora,是你創(chuàng)建的鏈接的名稱
里面的system是登錄到遠程數(shù)據(jù)庫的用戶名
manager是登錄到遠程數(shù)據(jù)庫的密碼
s-server是你現(xiàn)在登錄的這臺oracle服務器上用net manager建立的到遠程數(shù)據(jù)庫的連接

使用的時候,只需這樣:“select * from [email protected]”即可訪問遠程數(shù)據(jù)庫的tablename表,tablename表是屬于你建立dblink時所輸入的用戶名。

如果你執(zhí)行這條sql語句的時候出現(xiàn)錯誤:ora通過gaac.world連接。類似這樣的錯誤,說明遠程數(shù)據(jù)庫的init文件里把global names屬性設為了true,只要將其改為false就可以了(要重啟oracle)。如果不能改這個參數(shù),那你建立dblink時的名字就要寫成gaac.world(就是上面提示的那個錯誤中的名字)

下面是建立表觸發(fā)器的代碼:

create or replace trigger tg_e_contact
  before update or insert or delete on e_contact
  for each row
begin
  if inserting then
    insert into [email protected]
    values
      (:new.telephone, :new.employeeid, :new.status);
  else
    if updating then
      update [email protected] s
         set s.telephone  = :new.telephone,
             s.employeeid = :new.employeeid,
             s.status     = :new.status
       where s.employeeid = :old.employeeid;
    else
      if deleting then
        delete from [email protected] s
         where s.employeeid = :old.employeeid;
      end if;
    end if;
  end if;
end;


下面是建立視圖觸發(fā)器的代碼:(注意里面的instead of)

create or replace trigger tg_e_contact
  before instead of update or instead of insert or instead of delete on e_contact
  for each row
begin
  if inserting then
    insert into [email protected]
    values
      (:new.telephone, :new.employeeid, :new.status);
  else
    if updating then
      update [email protected] s
         set s.telephone  = :new.telephone,
             s.employeeid = :new.employeeid,
             s.status     = :new.status
       where s.employeeid = :old.employeeid;
    else
      if deleting then
        delete from [email protected] s
         where s.employeeid = :old.employeeid;
      end if;
    end if;
  end if;
end;


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 凤城市| 淮滨县| 阿巴嘎旗| 襄城县| 通辽市| 桦川县| 亳州市| 新丰县| 大悟县| 湘乡市| 曲麻莱县| 孟连| 凤冈县| 布拖县| 十堰市| 响水县| 阜新市| 凤翔县| 菏泽市| 从化市| 额尔古纳市| 丹阳市| 钟祥市| 眉山市| 靖远县| 平舆县| 宁都县| 沈丘县| 玉山县| 长沙县| 辽源市| 陇西县| 绥江县| 芦山县| 广昌县| 互助| 峨眉山市| 化德县| 太原市| 巴林左旗| 自贡市|