日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

.net访问PostgreSQL数据库发生“找不到函数名”的问题追踪

發布時間:2024/10/8 数据库 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net访问PostgreSQL数据库发生“找不到函数名”的问题追踪 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

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

1,問題回顧:
?在上一篇文章中說到,有一個PostgreSQL函數 updateattention ,它有一個自定義的函數參數,下面是函數頭:

?

CREATE?OR?REPLACE?FUNCTION?updateattention(dm?citext)
??
RETURNS?void?AS
$BODY$
--函數體略

?

參數dm 的類型是citex,一個自定義的數據類型,使用它來作為函數參數或者變量的類型,在進行數據查詢的時候可以不區分大小寫,它的定義是:

?

CREATE?OR?REPLACE?FUNCTION?citext(character)
??
RETURNS?citext?AS
'rtrim1'
??LANGUAGE?internal?IMMUTABLE?STRICT
??COST?
1;
ALTER?FUNCTION?citext(character)?OWNER?TO?postgres;

?

?下面是調用使用C#調用updateattention存儲過程的代碼:

?

//獲取PostgreSQL的數據訪問對象
PWMIS.DataProvider.Data.AdoHelper?db?=?MyDB.GetDBHelperByConnectionName("PostgreSQL");
//獲取PostgreSQL的參數對象
IDataParameter?para?=?db.GetParameter();?
para.ParameterName?
=?"@dm";
para.DbType?
=?DbType.AnsiString;
para.Value?
=?"KF0355";
db.ExecuteNonQuery(
"updateattention",
????????????????System.Data.CommandType.StoredProcedure,
????????????????
new?System.Data.IDataParameter[]?{?para?});

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

?

運行該程序,出現下面的錯誤:

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

PDF.NET框架內置了日志對象和異常對象,它能夠為你拋出詳細的錯誤信息,參看“PDF.NET的SQL日志 ”

?

2,問題聚焦

一開始還以為是函數名大小寫的問題,仔細核對后發現沒有問題,然后嘗試對代碼進行仔細排查。

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

para.DbType?=?DbType.AnsiString;


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

para.DbType?=?DbType.String;


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

?

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

updatefundattention(text)

難道PostgreSQL的數據類型text 對應的.NET程序類型既不是String,也不是AnsiString?

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

?

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.

?

可以看到 數據庫的text 類型是可以對應.net程序的String類型的,看來問題的關鍵的確是函數參數類型問題

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

?

?

CREATE?OR?REPLACE?FUNCTION?updateattention(dm?varchar)
??
RETURNS?void?AS
$BODY$
--函數體略

?

再次運行前面說的.net數據訪問程序,運行通過!

故此得到結論:

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

?

?3,“靈異現象”分析

前面說,將

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

在VS2010的“即時窗口”打印了一下未設置值的para.DbType,發現它的值是:

String

?

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

?

于是一個很偶然的念頭出現:

NpgsqlParameter對象的默認值是不是Object類型?

?

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

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

?

//獲取PostgreSQL的數據訪問對象
PWMIS.DataProvider.Data.AdoHelper?db?=?MyDB.GetDBHelperByConnectionName("PostgreSQL");
//獲取PostgreSQL的參數對象
IDataParameter?para?=?db.GetParameter();?
para.ParameterName?
=?"@dm";
para.DbType?
=?DbType.Object;
para.Value?
=?"KF0355";
db.ExecuteNonQuery(
"updateattention",
????????????????System.Data.CommandType.StoredProcedure,
????????????????
new?System.Data.IDataParameter[]?{?para?});

?

運行程序,正常通過,看來問題找到了,就是它,在PostgreSQL的自定義類型函數參數中,.net程序的存儲過程調用參數應該設置成 DbType.Object!

?

?

轉載于:https://www.cnblogs.com/bluedoctor/archive/2011/05/19/2051271.html

總結

以上是生活随笔為你收集整理的.net访问PostgreSQL数据库发生“找不到函数名”的问题追踪的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。