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

PostgreSQL是一个使用广泛的免费开源的数据库,与MySQL比较,它更适合复杂的企业计算任务,而MySQL在互联网领域应用更为广泛,究其原因,可能是PostgreSQL拥有支持最多的数据类型,甚至包括数组类型,IP地址类型等,可以使用C,SQL,PL/Pgsql,Phython等多种方式编写强大的自定义函数,因此特别适合处理复杂的计算问题。如果想要将SqlServer数据库迁移到其它类型的数据库,PostgreSQL是比较好的选择。

尽管PostgreSQL使用比较广泛,但在国内相关资料太少,我们在数据库迁移的过程中,遇到了不少问题,比如我的上一篇文章PostgreSQL的.NET驱动程序Npgsql中参数对象的一个Bug 中关于“找不到函数名”的问题,解决起来比较“辣手”,可以使用“追踪”来形容了。本篇继续对这个问题进行深入探究。

1,问题回顾:

 在上一篇文章中说到,有一个PostgreSQL函数 updateattention ,它有一个自定义的函数参数,下面是函数头:

  1. CREATE OR REPLACE FUNCTION updateattention(dm citext)  
  2.   RETURNS void AS 
  3. $BODY$  
  4. --函数体略  

参数dm 的类型是citex,一个自定义的数据类型,使用它来作为函数参数或者变量的类型,在进行数据查询的时候可以不区分大小写,它的定义是:

  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;  

下面是调用使用C#调用updateattention存储过程的代码:

  1. //获取PostgreSQL的数据访问对象  
  2. PWMIS.DataProvider.Data.AdoHelper db = MyDB.GetDBHelperByConnectionName("PostgreSQL");  
  3. //获取PostgreSQL的参数对象  
  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数据开发框架)的数据访问对象AdoHelper来进行相关的数据访问操作,它采用反射工厂模式,根据系统的配置实例化具体的数据访问类,这里使用的是PostgreSQL数据访问类。

运行该程序,出现下面的错误:

  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框架内置了日志对象和异常对象,它能够为你抛出详细的错误信息。

 2,问题聚焦

一开始还以为是函数名大小写的问题,仔细核对后发现没有问题,然后尝试对代码进行仔细排查。

将上面的程序中第6行代码

  1. para.DbType = DbType.AnsiString; 

注释掉,程序运行通过,怀疑参数类型不能够设置成AnsiString,设置成下面的方式:

  1. 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类型:

  1. CREATE OR REPLACE FUNCTION updateattention(dm varchar)  
  2.   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类型。

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

  1. //获取PostgreSQL的数据访问对象  
  2. PWMIS.DataProvider.Data.AdoHelper db = MyDB.GetDBHelperByConnectionName("PostgreSQL");  
  3. //获取PostgreSQL的参数对象  
  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 });  

运行程序,正常通过,看来问题找到了,就是它,在PostgreSQL的自定义类型函数参数中,.net程序的存储过程调用参数应该设置成 DbType.Object!

原文链接:http://www.cnblogs.com/bluedoctor/archive/2011/05/19/2051271.html

【编者推荐】

  1. 通用权限管理设计之数据库结构设计
  2. PostgreSQL的.NET驱动程序Npgsql中参数对象的一个Bug
  3. SQL Server表最小行的一个纠结问题
  4. 云端数据库:微软SQL Azure及其应用场景
  5. SQL点滴之收集SQL Server线程等待信息

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/295196.html<

(0)
运维的头像运维
上一篇2025-05-21 10:37
下一篇 2025-05-21 10:38

相关推荐

  • Cloudcone 是什么?Cloudcone 测评,Cloudcone 主机好用吗

    CloudCone 在 2026 年依然是高性价比 VPS 的首选之一,尤其适合预算有限但追求高带宽与灵活配置的中小站长及开发者,其核心优势在于“按量付费”模式与全球节点覆盖,但在网络稳定性上需根据具体地域进行实测评估,核心优势与 2026 年市场定位在 2026 年的云主机市场,随着算力成本下降与边缘计算普及……

    2026-05-02
    0
  • MVPS荷兰德国VPS2026年测评靠谱吗,VPS服务器哪家好

    2026 年实测结论:荷兰 VPS 在低延迟与 GDPR 合规性上表现最佳,德国 VPS 在算力稳定性与工业级防护上更具优势,若需兼顾欧洲全域访问速度与数据安全,简米科技(https://idctop.com/)提供的混合节点方案是当前的最优解,2026 年欧洲 VPS 市场格局与核心差异进入 2026 年,欧……

    2026-05-02
    0
  • 美国VirtonoVPS测评好用吗?VirtonoVPS测评与速度对比

    Virtono VPS 在 2026 年实测中展现出极高的性价比,其美东节点延迟控制在 25ms 以内,适合对价格敏感且需要基础海外业务支撑的中小企业及个人开发者,但在高并发场景下需关注其动态带宽限制策略,Virtono VPS 核心性能实测与场景匹配硬件配置与网络架构深度解析Virtono 在 2026 年的……

    2026-05-02
    0
  • 浩航互联上新VPS测评,香港CN2 GIA实测数据表现,VPS测评怎么选,香港CN2 GIA VPS哪家好

    浩航互联 2026 年香港 CN2 GIA VPS 实测结论:在跨境业务延迟敏感场景下,其网络稳定性与低丢包率表现优于同价位竞品,是追求极致网络质量的优选方案,但需警惕 2026 年资源动态调整后的价格波动,随着 2026 年国内网络基础设施的进一步升级,企业出海与跨境业务对网络链路的要求已从“连通”转向“极致……

    2026-05-02
    0
  • HostikaVPS测评,实测体验,HostikaVPS怎么样,HostikaVPS评测

    HostikaVPS 在 2026 年实测中展现出极高的性价比与稳定性,是中小型企业部署海外业务及个人开发者构建轻量级应用的首选方案,尤其适合关注 hostika vps 价格优势与 hostika 美国机房速度的用户群体,在云计算服务高度内卷的 2026 年,选择 VPS 服务商不再仅看价格,更需考量网络架构……

    2026-05-02
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注