日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
PostgreSQL的.NET驅(qū)動程序Npgsql中參數(shù)對象的一個Bug

最近將公司的項目從SqlServer移植到PostgreSQL數(shù)據(jù)庫上來,在調(diào)用數(shù)據(jù)庫的存儲過程(自定義函數(shù))的時候,發(fā)現(xiàn)一個奇怪的問題,老是報函數(shù)無法找到。

為襄州等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及襄州網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、襄州網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

先看一個PgSQL存儲過程:

 
 
 
  1. CREATE OR REPLACE FUNCTION updateattention(dm citext)
  2. RETURNS void AS
  3. $BODY$
  4. DECLARE
  5. BEGIN
  6. update ZB set gzd=COALESCE(gzd,0)+1 where ZB.dm=$1 ;
  7. END;
  8. $BODY$
  9. LANGUAGE plpgsql VOLATILE
  10. COST 100;
  11. ALTER FUNCTION updateattention(citext) OWNER TO postgres;

在PostgreSQL中,函數(shù)和存儲過程沒有區(qū)別,這里我們把沒有返回值的函數(shù)叫做存儲過程吧,也許表訴的不太準確,還望大蝦指正。

上面定義一個存儲過程updateattention,它有一個自定義類型 citext,用于將字符串中類型換成不區(qū)分大小寫的類型,它的定義如下:

 
 
 
  1. CREATE OR REPLACE FUNCTION citext(character)
  2. RETURNS citext AS
  3. 'rtrim1'
  4. LANGUAGE internal IMMUTABLE STRICT
  5. COST 1;
  6. ALTER FUNCTION citext(character) OWNER TO postgres;

下面是調(diào)用updateattention存儲過程的代碼:

 
 
 
  1. //獲取PostgreSQL的數(shù)據(jù)訪問對象
  2. PWMIS.DataProvider.Data.AdoHelper db = MyDB.GetDBHelperByConnectionName("PostgreSQL");
  3. //獲取PostgreSQL的參數(shù)對象
  4. IDataParameter para = db.GetParameter();
  5. para.ParameterName = "@dm";
  6. para.DbType = DbType.AnsiString;
  7. para.Value = "KF0355";
  8. db.ExecuteNonQuery("updateattention",
  9. System.Data.CommandType.StoredProcedure,
  10. new System.Data.IDataParameter[] { para });

程序使用PDF.NET(PWMIS數(shù)據(jù)開發(fā)框架)的數(shù)據(jù)訪問對象AdoHelper來進行相關(guān)的數(shù)據(jù)訪問操作,它采用反射工廠模式,根據(jù)系統(tǒng)的配置實例化具體的數(shù)據(jù)訪問類,這里使用的是PostgreSQL數(shù)據(jù)訪問類。

運行該程序,出現(xiàn)下面的錯誤:

PDF.NET AdoHelper 查詢錯誤:

 
 
 
  1. DataBase ErrorMessage:ERROR: 42883: function updatefundattention(text) does not exist
  2. SQL:updatefundattention
  3. CommandType:StoredProcedure
  4. Parameters:
  5. Parameter["@jjdm"] = "KF0355" //DbType=String

PDF.NET框架內(nèi)置了日志對象和異常對象,它能夠為你拋出詳細的錯誤信息。

如果采用下面的方式調(diào)用,又沒有問題:

 
 
 
  1. db.ExecuteNonQuery("select * from updateattention(@dm)",
  2. System.Data.CommandType.Text,
  3. new System.Data.IDataParameter[] { para });

------------------------------------------------------------------------------------

盡管該方式可以作為一種替代方案,但要用select * from 這種方式調(diào)用存儲過程,總覺得很別扭,還得找到問題的真正原因。

這個 "function ... does not exist" 的問題很難搜索,最終在國外找到一篇文章討論類似的問題:

http://pgfoundry.org/forum/forum.php?thread_id=637&forum_id=519

文中有人說,可能是參數(shù)的類型轉(zhuǎn)換問題,但我這里只是將參數(shù)進行了大小寫轉(zhuǎn)換,應(yīng)該不會有類似Int32到Int64這類問題。

無賴,只有將調(diào)用存儲過程的.NET程序代碼一個一個排查,當注釋掉

para.DbType = DbType.AnsiString;

的時候,程序居然能夠正常運行通過了!

之前也曾經(jīng)懷疑過是不是DbType的問題,但是當把鼠標放到VS2010的編輯器中para 對象下面的時候,智能提示顯示 DbType="{String}".

默認情況下,參數(shù)對象的DbType屬性值是

DbType.String

難道

DbType.AnsiString==DbType.String ??

看了一下定義,它們是有區(qū)別的,DbType.AnsiString表示非Unicode的變長字符串,DbType.String 表示Unicode的變長字符串。

一般情況下,ANSI編碼表示當前系統(tǒng)編碼,所以我猜想AnsiString在我的機器上是Gb2312編碼的,查了一下數(shù)據(jù)庫的編碼,它是UTF-8格式的,難怪難怪,PostgreSQL給我提示找不到 updatefundattention(text) 函數(shù),注意下,實際上這個函數(shù)的參數(shù)不是text類型的,它實際上應(yīng)該是 character 類型,PostgreSQL可以定義同名的函數(shù),但函數(shù)可以有不同的參數(shù)類型,有點像C#的方法重載。

到此,問題似乎解決了,但還沒完:

VS2010的智能提示有Bug?

***次有這個念頭我都覺得不可思議,因為以前在VS2008的時候曾經(jīng)調(diào)試過類似的代碼,趕緊將上面的.net代碼中的參數(shù)對象換成其它數(shù)據(jù)庫類型的參數(shù)對象試試看:

 
 
 
  1. //獲取PostgreSQL的數(shù)據(jù)訪問對象
  2. PWMIS.DataProvider.Data.AdoHelper db = MyDB.GetDBHelperByConnectionName("PostgreSQL");
  3. //使用 SqlServer 的參數(shù)對象
  4. IDataParameter para = new SqlParameter();
  5. para.ParameterName = "@dm";
  6. para.DbType = DbType.AnsiString;
  7. para.Value = "KF0355";
  8. db.ExecuteNonQuery("updateattention",
  9. System.Data.CommandType.StoredProcedure,
  10. new System.Data.IDataParameter[] { para });

再此將光標放到para.DbType 上,這次提示正確了,是“{AnsiString}”;

將上面的代碼放到VS2008中再次驗證,智能提示正確,看來不是VS2010的Bug,呵呵。

故此,得到的結(jié)論:

PostgreSQL的.NET數(shù)據(jù)訪問驅(qū)動程序的參數(shù)對象DbType屬性存在一個設(shè)置成AnsiString之后查看該屬性的結(jié)果卻是String的Bug!

PS:雖然查看屬性的確有這樣一個Bug,但好像程序內(nèi)部做了正確的處理,要不我的程序最終是無法運行通過的。

后記

PostgreSQL的.NET數(shù)據(jù)驅(qū)動程序的這個問題引起的問題使得我困擾了2天左右的時間,不得不發(fā)帖說明一下這個過程,現(xiàn)在國內(nèi)有關(guān)PostgreSQL的資料太少,寫點東西供大家參考一下。


網(wǎng)站題目:PostgreSQL的.NET驅(qū)動程序Npgsql中參數(shù)對象的一個Bug
網(wǎng)頁路徑:http://www.dlmjj.cn/article/dhhiiic.html