调用PostgreSQL存储过程,找不到函数名的问题
PostgreSQL的表,函数名称都是严格区分大小写的,所以在使用的时候没有注意大小写问题容易导致找不到函数名的错误,但最近两天我们发现,如果函数参数使用了自定义的数据类型,也会发生这个问题。
问题描述:
下面的示例测试代码:
PWMIS.DataProvider.Data.AdoHelper db = MyDB.GetDBHelperByConnectionName("PostgreSQL");
IDataParameter para = db.GetParameter();
para.ParameterName = "@jjdm";
para.DbType = DbType.AnsiString ;
para.Value = "KF0355";
int count= db.ExecuteNonQuery("updatefundattention",
System.Data.CommandType.StoredProcedure,
new System.Data.IDataParameter[] { para });
运行该存储过程,出现下面的错误:
DataBase ErrorMessage:ERROR: 42883: function updatefundattention(text) does not exist SQL:updatefundattention CommandType:StoredProcedure Parameters: Parameter["@jjdm"] = "KF0355" //DbType=String
实际上,PostgreSQL的函数updatefundattention 参数类型不是 text,而是自定义的类型 citex ,下面是函数定义:
CREATE OR REPLACE FUNCTION updatefundattention(jjdm citext)
RETURNS void AS
$BODY$
DECLARE
BEGIN
update JJZB set gzd=COALESCE(gzd,0)+1 where JJZB.Jjdm=$1 ;
--return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION updatefundattention(citext) OWNER TO postgres;
昨天分析可能PostgreSQL的字符型参数不能使用AnsiString参数类型,需要使用String类型,但今天测试发现
para.DbType = DbType.String ;
问题依然没有解决。
重新建立一个测试函数updatefundattention,只是参数类型为 varchar:
CREATE OR REPLACE FUNCTION updatefundattention2(jjdm character varying)
RETURNS void AS
$BODY$
DECLARE
BEGIN
update JJZB set gzd=COALESCE(gzd,0)+1 where JJZB.Jjdm=$1 ;
--return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION updatefundattention2(character varying) OWNER TO postgres;
运行测试程序,不论
para.DbType = DbType.AnsiString ;
还是
para.DbType = DbType.String ;
调用函数updatefundattention2 均能通过,故此得到结论:
目前自定义的 citext 类型.NET程序无法设置正确的DbType,从而会出现找不到函数的错误!
问题影响:
在WFT中,所有使用.NET程序调用PostgreSQL存储过程的代码,如果存储过程的参数使用了自定义的类型(例如citex),均会受影响。
解决方案:
a,建议不要在PostgreSQL函数的参数中使用自定义的类型,如果要想对参数进行大小写转换,建议在函数体中使用另外一个Pgsql变量,函数中执行查询的SQL语句使用这个新变量,而不是直接使用这个函数参数;
b,修改Sql-Map中的SQL语句,例如
<Select CommandName="AddGuanZhuDu" Method="" CommandType="StoredProcedure" Description="增加关注度" ResultClass="ValueType"><![CDATA[
UpdateFundAttention
#jjdm : String#
]]></Select>
修改成下面的方式:
<Select CommandName="AddGuanZhuDu" Method="" CommandType="Text" Description="增加关注度" ResultClass="ValueType"><![CDATA[
select * from UpdateFundAttention (#jjdm: String#)
]]></Select>
但这种修改方式会造成SqlServer与PostgreSQL的SQL-MAP语句不相同,增加程序的维护量,理想的方式是SQL-MAP语句尽量相同。
- IntelliJ idea配置Go开发环境
- 仰望PHPSHE1.5漏洞
- Golang负载均衡
- 构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式
- Golang单例模式
- 2018,我要Axublog。
- 厚土Go学习笔记 | 16. go语言有指针 没有指针运算
- 嗤!给你来点fiyocms漏洞喷雾
- 厚土Go学习笔记 | 15. defer语句延迟函数的执行
- Nodejs学习笔记(九)--- 与Redis的交互(mranney/node_redis)入门
- Nodejs学习笔记(十)--- 与MongoDB的交互(mongodb/node-mongodb-native)、MongoDB入门
- Golang泛型编程初体验
- 工具| 手把手教你制作信息收集器之端口扫描
- 厚土Go学习笔记 | 14. switch 的条件写的有点灵活,不过风格还是go的一贯风格
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- pandas to_excel 添加颜色操作
- Python自带的IDE在哪里
- php+Ajax无刷新验证用户名操作实例详解
- PHP经典设计模式之依赖注入定义与用法详解
- 浅谈python出错时traceback的解读
- PHP判断是否是微信打开还是浏览器打开的方法
- php面向对象程序设计中self与static的区别分析
- PHP如何根据文件头检测文件类型实例代码
- PHP去除空数组且数组键名重置的讲解
- Yii2框架配置文件(Application属性)与调试技巧实例分析
- java解析json方法总结
- PHP正则验证字符串是否为数字的两种方法并附常用正则
- 使用python编写一个语音朗读闹钟功能的示例代码
- PHP中常见的密码处理方式和建议总结
- php+Ajax处理xml与json格式数据的方法示例