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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
.net訪問PostgreSQL數(shù)據(jù)庫發(fā)生“找不到函數(shù)名”的問題追蹤

PostgreSQL是一個使用廣泛的免費開源的數(shù)據(jù)庫,與MySQL比較,它更適合復(fù)雜的企業(yè)計算任務(wù),而MySQL在互聯(lián)網(wǎng)領(lǐng)域應(yīng)用更為廣泛,究其原因,可能是PostgreSQL擁有支持最多的數(shù)據(jù)類型,甚至包括數(shù)組類型,IP地址類型等,可以使用C,SQL,PL/Pgsql,Phython等多種方式編寫強(qiáng)大的自定義函數(shù),因此特別適合處理復(fù)雜的計算問題。如果想要將SqlServer數(shù)據(jù)庫遷移到其它類型的數(shù)據(jù)庫,PostgreSQL是比較好的選擇。

專注于為中小企業(yè)提供網(wǎng)站設(shè)計、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)鐵嶺縣免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

盡管PostgreSQL使用比較廣泛,但在國內(nèi)相關(guān)資料太少,我們在數(shù)據(jù)庫遷移的過程中,遇到了不少問題,比如我的上一篇文章PostgreSQL的.NET驅(qū)動程序Npgsql中參數(shù)對象的一個Bug 中關(guān)于“找不到函數(shù)名”的問題,解決起來比較“辣手”,可以使用“追蹤”來形容了。本篇繼續(xù)對這個問題進(jìn)行深入探究。

1,問題回顧:

 在上一篇文章中說到,有一個PostgreSQL函數(shù) updateattention ,它有一個自定義的函數(shù)參數(shù),下面是函數(shù)頭:

 
 
 
  1. CREATE OR REPLACE FUNCTION updateattention(dm citext)  
  2.   RETURNS void AS 
  3. $BODY$  
  4. --函數(shù)體略  

參數(shù)dm 的類型是citex,一個自定義的數(shù)據(jù)類型,使用它來作為函數(shù)參數(shù)或者變量的類型,在進(jìn)行數(shù)據(jù)查詢的時候可以不區(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)用使用C#調(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來進(jìn)行相關(guān)的數(shù)據(jù)訪問操作,它采用反射工廠模式,根據(jù)系統(tǒng)的配置實例化具體的數(shù)據(jù)訪問類,這里使用的是PostgreSQL數(shù)據(jù)訪問類。

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

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

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

2,問題聚焦

一開始還以為是函數(shù)名大小寫的問題,仔細(xì)核對后發(fā)現(xiàn)沒有問題,然后嘗試對代碼進(jìn)行仔細(xì)排查。

將上面的程序中第6行代碼

 
 
 
  1. para.DbType = DbType.AnsiString; 

注釋掉,程序運(yùn)行通過,懷疑參數(shù)類型不能夠設(shè)置成AnsiString,設(shè)置成下面的方式:

 
 
 
  1. para.DbType = DbType.String;  

程序依然運(yùn)行不通過,拋出上面同樣的錯誤,只有將這行代碼注釋掉才可以允許通過,思索很久仍然沒有結(jié)果,于是昨天寫了本文開頭說的那篇文章(PostgreSQL的.NET驅(qū)動程序Npgsql中參數(shù)對象的一個Bug)。

今天再次將目光聚集在錯誤信息的函數(shù)參數(shù)上:

updatefundattention(text)

難道PostgreSQL的數(shù)據(jù)類型text 對應(yīng)的.NET程序類型既不是String,也不是AnsiString?

又搜索了下,在http://npgsql.projects.postgresql.org/docs/manual/UserManual.html 找到了一張數(shù)據(jù)類型對照表:

Supported data types

Npgsql supports the following data types:

Postgresql TypeNpgsqlDbTypeSystem.DbType Enum.Net System Type
int8BigintInt64Int64
boolBooleanBooleanBoolean
Box, Circle, Line, LSeg, Path, Point, PolygonBox, Circle, Line, LSeg, Path, Point, PolygonObjectObject
byteaByteaBinaryByte[]
dateDateDateDateTime, NpgsqlDate
float8DoubleDoubleDouble
int4IntegerInt32Int32
moneyMoneyDecimalDecimal
numericNumericDecimalDecimal
float4RealSingleSingle
int2SmallintInt16Int16
textTextStringString
timeTimeTimeDateTime, NpgsqlTime
timetzTimeTimeDateTime, NpgsqlTimeTZ
timestampTimestampDateTimeDateTime, NpgsqlTimestamp
timestamptzTimestampTZDateTimeDateTime, NpgsqlTimestampTZ
intervalIntervalObjectTimeSpan, NpgsqlInterval
varcharVarcharStringString
inetInetObjectNpgsqlInet, IPAddress
(there is an implicity cast operator to convert NpgsqlInet objects into IPAddress if you need to use IPAddress and have only NpgsqlInet)
bitBitBooleanBoolean, Int32
(If you use an Int32 value, odd values will be translated to bit 1 and even values to bit 0)
uuidUuidGuidGuid
arrayArrayObjectArray
In order to explicitly use array type, specify NpgsqlDbType as an 'OR'ed type: NpgsqlDbType.Array | NpgsqlDbType.Integer for an array of Int32 for example.

可以看到 數(shù)據(jù)庫的text 類型是可以對應(yīng).net程序的String類型的,看來問題的關(guān)鍵的確是函數(shù)參數(shù)類型問題。

為了驗證這個想法,將函數(shù)的參數(shù)類型改為Varchar類型:

  
 
 
  1. CREATE OR REPLACE FUNCTION updateattention(dm varchar)  
  2.   RETURNS void AS 
    • $BODY$  
    • --函數(shù)體略

再次運(yùn)行前面說的.net數(shù)據(jù)訪問程序,運(yùn)行通過!

故此得到結(jié)論:

PostgreSQL數(shù)據(jù)庫的函數(shù)中使用“自定義數(shù)據(jù)類型”,在.NET程序可能無法設(shè)置正確的DbType,從而出現(xiàn)找不到函數(shù)名的錯誤!

3,“靈異現(xiàn)象”分析

前面說,將

 para.DbType = DbType.AnsiString;
代碼注釋即可,也就是不對NpgsqlParameter.DbType 設(shè)置任何值,那么DbType的缺省值是什么呢?

在VS2010的“即時窗口”打印了一下未設(shè)置值的para.DbType,發(fā)現(xiàn)它的值是:

String

由于上一篇文章已經(jīng)驗證Npgsql的參數(shù)對象DbType無論怎么設(shè)置,獲取該屬性值的時候都是String,所以還是無法得知它的默認(rèn)屬性值是什么。

于是一個很偶然的念頭出現(xiàn):

NpgsqlParameter對象的默認(rèn)值是不是Object類型?

另外我們的函數(shù)使用了自定義的citext類型,所以很可能需要使用DbType.Object類型。

重新修改代碼成下面的方式:

 
 
 
  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.Object;  
  7. para.Value = "KF0355";  
  8. db.ExecuteNonQuery("updateattention",  
  9.                 System.Data.CommandType.StoredProcedure,  
  10.                 new System.Data.IDataParameter[] { para });  

運(yùn)行程序,正常通過,看來問題找到了,就是它,在PostgreSQL的自定義類型函數(shù)參數(shù)中,.net程序的存儲過程調(diào)用參數(shù)應(yīng)該設(shè)置成 DbType.Object!


網(wǎng)頁名稱:.net訪問PostgreSQL數(shù)據(jù)庫發(fā)生“找不到函數(shù)名”的問題追蹤
網(wǎng)頁地址:http://www.dlmjj.cn/article/dpejsod.html