在Firebird存储过程中使用Decimal参数

时间:2010-02-05 16:17:21

标签: .net stored-procedures decimal firebird

我有一个Firebird存储过程,它接受纬度和经度参数的十进制(9,6)值。它用于为用户创建联系人配置文件。

当我尝试创建并使用这些十进制参数时,出现转换错误:

  

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 .NET数据提供程序2.5.1对Firebird 2.1.3数据库。

更新:在@ bluecoder的请求下,我尝试从源代码构建.NET数据提供程序。但是我在GdsStatement.cs的第731行遇到了编译错误。

int processedItems = (rowDescs[part] != null ? rowDescs[part].Count : 0);

错误是:

  

存在从“short”到“int”以及从“int”到“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 :我刚刚尝试使用新的Firebird Client 2.5.2版本,但仍然存在问题。我认为这是一个错误。我将在Firebird Tracker上报告。

UPDATE4 :哎呀。我发现我的GAC中有一个对Firebird Client 2.5.1的陈旧引用。 Firebird Client 2.5.2确实解决了这个问题。

2 个答案:

答案 0 :(得分:2)

首先检查明显:

1)您确定没有将Parameter.DbType设置为DbType.Int32吗?

2)您可以发布调试器遇到错误的实际代码吗? (我假设上面是伪代码)

3)您是否验证了失败是否在Parameter.Value分配线上? (例如,不在命令执行中)


<强>来源
下载.Net提供商来源 - Provider
7zip提取源(如果你没有) - 7Zip

<强>构建
[备份您当前的来源正在修改任何内容]
1)右键单击您的C#解决方案,然后选择添加 - >现有解决方案
2)从您将Provider源解压缩到的目录中选择* .csproj  [.. \ NETProvider \源\ FirebirdSql \数据\ FirebirdSql.Data.FirebirdClient.csproj]
3)右键单击FirebirdClient项目并构建它 4)将应用程序中的FirebirdSql.Data.FirebirdClient引用更改为刚刚编译的版本  [.. \ Data \ bin \ Debug \ FirebirdSql.Data.FirebirdClient.dll]

现在您应该可以进入(F11)您的ExecuteScalar语句并查看引发转换异常的位置。

如果其中任何一项没有意义,请告诉我。我很想知道你找到了什么

答案 1 :(得分:0)

我刚刚发现我的GAC中有对Firebird Client 2.5.1的陈旧引用。删除此引用后,我能够成功运行我的测试用例。

.NET Provider for Firebird版本2.5.2没有我在我的问题中描述的问题。解决方案是升级到最新版本的.NET Provider for Firebird。