我有一个接受经度和纬度参数的十进制(9,6)值的Firebird存储过程。它用于为用户创建联系人配置文件。在Firebird存储过程中使用十进制参数
当我尝试创建和使用这些小数参数,我得到一个转换错误:
Value was too large or too small for an Int32.
下面是如何创建的ADO.Net连接:
FbConnection dbConn = new FbConnection(ConnectionString);
进一步对,这里的在那里我设置了命令:
IDbCommand command = _Connection.CreateCommand();
command.Connection = _Connection;
command.CommandText = "CREATECONTACT";
command.CommandType = CommandType.StoredProcedure;
我用来创建ADO.Net参数的代码看就像这样:
IDataParameter param21 = command.CreateParameter();
param21.ParameterName = "GEOLAT";
param21.DbType = DbType.Decimal;
param21.Value = 3.14m;
后所有的参数都被添加我叫command.ExecuteScalar()
得到的只是创造了一个(希望)的使用ContactID的价值。
int contactId = Convert.ToInt32(command.ExecuteScalar(), CultureInfo.InvariantCulture);
这不是导致问题的Convert.ToInt32。从ExecuteScalar()
中抛出异常。我得到同样的错误,如果命令是这样的:
object result = command.ExecuteScalar();
程序工作正常,如果为GeoLat和GeoLong值是整数值(如72或0),但如果我试图通过一个十进制值, 它失败。例如:
IDataParameter param21 = command.CreateParameter();
param21.ParameterName = "GEOLAT";
param21.DbType = DbType.Int32;
param21.Value = 12;
我在这里做错了什么?
我对Firebird 2.1.3数据库使用Firebird .NET数据提供程序2.5.1。
UPDATE:在@ bluecoder的请求中,我试图从源代码构建.NET数据提供程序。但是我在GdsStatement.cs的第731行得到一个编译错误。
int processedItems = (rowDescs[part] != null ? rowDescs[part].Count : 0);
的错误是:
There exist both implicit conversions from "short" to "int" and from "int" to "short".
更改线路731本:
int processedItems = (rowDescs[part] != null ? (int) rowDescs[part].Count : 0);
允许代码编译我的机器上。
使这个代码更改后,我能够运行我的测试,并成功地在我的存储过程中使用小数。
看来,错误的触发器是我返回受更新语句影响的行数作为过程的一部分。
UPDATE2:下面是SQL存储过程的完整源代码。它用于在我的数据库中创建一个hCard记录。
SET TERM^;
RECREATE PROCEDURE CREATECONTACT (
TEMPLATECODE SMALLINT,
CREATEUSERID INTEGER,
CREATEDATE TIMESTAMP,
SECURITYCODE SMALLINT,
LINKTEXT VARCHAR(255),
GUID VARCHAR(200),
GIVENNAME VARCHAR(200),
FAMILYNAME VARCHAR(200),
ADDITIONALNAME VARCHAR(200),
HONORIFICPREFIX VARCHAR(200),
HONORIFICSUFFIX VARCHAR(200),
NICKNAME VARCHAR(200),
PHOTOLOCALFILEID INTEGER,
LOGOLOCALFILEID INTEGER,
BIRTHDAY TIMESTAMP,
JOBTITLE VARCHAR(200),
"ROLE" VARCHAR(200),
ORGANIZATION VARCHAR(255),
NOTE BLOB SUB_TYPE TEXT,
GEOLAT DECIMAL(9,6),
GEOLONG DECIMAL(9,6))
RETURNS (
ENTITYID INTEGER)
AS
BEGIN
EXECUTE PROCEDURE CreateEntity :TEMPLATECODE, :CREATEUSERID, :CREATEDATE, :SECURITYCODE, :LinkText
RETURNING_VALUES EntityId;
INSERT INTO CONTACT (EntityId, GUID, GIVENNAME, FAMILYNAME, ADDITIONALNAME,
HONORIFICPREFIX, HONORIFICSUFFIX, NICKNAME, PHOTOLOCALFILEID, LOGOLOCALFILEID,
BIRTHDAY, JOBTITLE, "ROLE", ORGANIZATION, NOTE, GEOLAT, GEOLONG)
VALUES (:EntityId, :GUID, :GIVENNAME, :FAMILYNAME, :ADDITIONALNAME,
:HONORIFICPREFIX, :HONORIFICSUFFIX, :NICKNAME, :PHOTOLOCALFILEID,
:LOGOLOCALFILEID, :BIRTHDAY, :JOBTITLE, :ROLE, :ORGANIZATION, :NOTE,
:GEOLAT, :GEOLONG);
SUSPEND;
END^
SET TERM ;^
UPDATE3:我刚与新客户火鸟2.5.2版本尝试这样做,它仍然有问题。我认为这是一个错误。我要在Firebird Tracker上报告。
UPDATE4:糟糕。我发现我在GAC中对Firebird Client 2.5.1有一个陈旧的参考。 Firebird Client 2.5.2确实解决了这个问题。
您的程序是否在IBExpert这样的IDE中工作? – 2010-02-05 16:47:33
我还没有在IDE中尝试过它,但是如果我为GEOLAT和GEOLONG传递整数值,存储过程将正常工作。如果它们被输入为小数,它将失败。 – dthrasher 2010-02-05 21:03:59
我刚刚在Firebird Maestro IDE中尝试了我的过程,并且它可以正常使用十进制值。 – dthrasher 2010-02-05 21:18:27