CREATE OR REPLACE FUNCTION updateattention(dm citext)
RETURNS void AS
$BODY$
DECLARE
BEGIN
update ZB set gzd=COALESCE(gzd,0)+1 where ZB.dm=$1 ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION updateattention(citext) OWNER TO postgres; 在PostgreSQL中,函数和存储过程没有区别,这里我们把没有返回值的函数叫做存储过程吧,也许表诉的不太准确,还望大虾指正。
上面定义一个存储过程updateattention,它有一个自定义类型 citext,用于将字符串中类型换成不区分大小写的类型,它的定义如下:
CREATE OR REPLACE FUNCTION citext(character)
RETURNS citext AS
'rtrim1'
LANGUAGE internal IMMUTABLE STRICT
COST 1;
ALTER FUNCTION citext(character) OWNER TO postgres; 下面是调用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框架内置了日志对象和异常对象,它能够为你抛出详细的错误信息。
如果采用下面的方式调用,又没有问题:
db.ExecuteNonQuery("select * from updateattention(@dm)",
System.Data.CommandType.Text,
new System.Data.IDataParameter[] { para });
------------------------------------------------------------------------------------
尽管该方式可以作为一种替代方案,但要用select * from 这种方式调用存储过程,总觉得很别扭,还得找到问题的真正原因。
这个 "function ... does not exist" 的问题很难搜索,最终在国外找到一篇文章讨论类似的问题:
http://pgfoundry.org/forum/forum.php?thread_id=637&forum_id=519
文中有人说,可能是参数的类型转换问题,但我这里只是将参数进行了大小写转换,应该不会有类似Int32到Int64这类问题。
无赖,只有将调用存储过程的.NET程序代码一个一个排查,当注释掉 para.DbType =DbType.AnsiString;