通过 OleDb 调用 AS400 程序会导致 InvalidCastException
我正在尝试使用 OleDb 在我们的 AS/400 机器上调用 RPG 程序。一旦出现更复杂的类型(例如日期和小数),我似乎就会收到以下错误:
由于符号不匹配或数据溢出以外的原因,无法转换数据值。例如,数据存储中的数据已损坏,但该行仍然可检索。
这是产生问题的代码:
// 'p_refno 9a ()
//'p_projdat *date (output parm)
//'p_amount 13p, 2 (output parm)
//'p_rtnsts 1a (output parm)
using (OleDbConnection cn = new OleDbConnection("Provider=IBMDA400;Data Source=MyAs400;User ID=MyUser;Password=MyPassword;"))
{
cn.Open();
OleDbCommand cmd = new OleDbCommand("{{call PGMLIB.MYPROGRAM(?,?,?,?,?,?,?)}}", cn);
cmd.CommandType = System.Data.CommandType.Text;
OleDbParameter p_refno = new OleDbParameter("p_refno","ED4565654");
OleDbParameter p_projdat = new OleDbParameter("p_projdat", new DateTime());
p_projdat.Direction = System.Data.ParameterDirection.Output;
p_projdat.Size = 8;
OleDbParameter p_amount = new OleDbParameter("p_amount", new Decimal());
p_amount.Direction = System.Data.ParameterDirection.Output;
OleDbParameter p_rtnsts = new OleDbParameter("p_rtnsts", " ");
p_rtnsts.Direction = System.Data.ParameterDirection.Output;
p_rtnsts.Size = 1;
p_amount.DbType = System.Data.DbType.Decimal;
cmd.Parameters.Add(p_refno);
cmd.Parameters.Add(p_mode);
cmd.Parameters.Add(p_source);
cmd.Parameters.Add(p_type);
cmd.Parameters.Add(p_projdat);
cmd.Parameters.Add(p_amount);
cmd.Parameters.Add(p_rtnsts);
cmd.ExecuteNonQuery();
Console.WriteLine(p_projdat.Value.ToString());
Console.WriteLine(p_amount.Value.ToString());
Console.WriteLine(p_rtnsts.Value.ToString());
}
Console.WriteLine("Press any key to quit...");
Console.ReadKey();
我做错了什么?
I am trying to call an RPG program on our AS/400 machine using OleDb. As soon as there are more complex types such as dates and decimals I seem to be getting the following error:
The data value could not be converted for reasons other than sign mismatch or data overflow. For example, the data was corrupted in the data store but the row was still retrievable.
Here is the code that produces the problem:
// 'p_refno 9a ()
//'p_projdat *date (output parm)
//'p_amount 13p, 2 (output parm)
//'p_rtnsts 1a (output parm)
using (OleDbConnection cn = new OleDbConnection("Provider=IBMDA400;Data Source=MyAs400;User ID=MyUser;Password=MyPassword;"))
{
cn.Open();
OleDbCommand cmd = new OleDbCommand("{{call PGMLIB.MYPROGRAM(?,?,?,?,?,?,?)}}", cn);
cmd.CommandType = System.Data.CommandType.Text;
OleDbParameter p_refno = new OleDbParameter("p_refno","ED4565654");
OleDbParameter p_projdat = new OleDbParameter("p_projdat", new DateTime());
p_projdat.Direction = System.Data.ParameterDirection.Output;
p_projdat.Size = 8;
OleDbParameter p_amount = new OleDbParameter("p_amount", new Decimal());
p_amount.Direction = System.Data.ParameterDirection.Output;
OleDbParameter p_rtnsts = new OleDbParameter("p_rtnsts", " ");
p_rtnsts.Direction = System.Data.ParameterDirection.Output;
p_rtnsts.Size = 1;
p_amount.DbType = System.Data.DbType.Decimal;
cmd.Parameters.Add(p_refno);
cmd.Parameters.Add(p_mode);
cmd.Parameters.Add(p_source);
cmd.Parameters.Add(p_type);
cmd.Parameters.Add(p_projdat);
cmd.Parameters.Add(p_amount);
cmd.Parameters.Add(p_rtnsts);
cmd.ExecuteNonQuery();
Console.WriteLine(p_projdat.Value.ToString());
Console.WriteLine(p_amount.Value.ToString());
Console.WriteLine(p_rtnsts.Value.ToString());
}
Console.WriteLine("Press any key to quit...");
Console.ReadKey();
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果可以,请使用 IBM i Access ADO.NET 驱动程序并将程序调用放在存储过程中。他们可以将数据从 i 转换到 PC。
If you can, use the IBM i Access ADO.NET drivers and place the program call in a stored procedure. They can convert the data from i to PC.
PC 和大型机平台之间的日期格式(以及二进制数字,例如 int/single 等)有所不同。您需要将它们转换为文本,然后再转换回来,除非通信平台为您处理了这一问题 - 显然这个平台没有这样做。
可能有一种方法可以弄清楚如何做到这一点,但如果您是唯一使用大型机部件并且有能力更改它的人,那么您将忘记它并自己在两端进行转换,从而提前几个小时。 (除非有人知道如何阅读此内容;-)
如果您无法更改 as400 部分,那么,请不要接受这个答案......
Date formats (and binary numeric e.g., int/single, etc) differ between PC and mainframe platforms. You will need to convert them to text and then back again, unless the communications platform takes care of this for you - which obviously this one isn't doing.
There is probably a way to figure out how to do this, but if you are the only one using the mainframe piece and have the ability to change it, you will be hours ahead by forgetting about it and doing the converts yourself on both ends. (unless somebody who knows how reads this ;-)
If you can't change the as400 piece, well, don't accept this answer...