2010-02-05 81 views
1

我有一個接受經度和緯度參數的十進制(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確實解決了這個問題。

+0

您的程序是否在IBExpert這樣的IDE中工作? – 2010-02-05 16:47:33

+0

我還沒有在IDE中嘗試過它,但是如果我爲GEOLAT和GEOLONG傳遞整數值,存儲過程將正常工作。如果它們被輸入爲小數,它將失敗。 – dthrasher 2010-02-05 21:03:59

+0

我剛剛在Firebird Maestro IDE中嘗試了我的過程,並且它可以正常使用十進制值。 – dthrasher 2010-02-05 21:18:27

回答

0

我剛剛發現我在GAC中有一個對Firebird Client 2.5.1的陳舊引用。刪除這個引用後,我能夠成功運行我的測試用例。

火鳥版本2.5.2的.NET提供程序沒有我在我的問題中描述的問題。解決方案是升級到最新版本的Firebird .NET Provider。

+0

我很高興你終於搞定了:) – bluecoder 2010-02-23 17:14:33

2

檢查顯而易見的第一:

1)您在Parameter.DbType的確定沒有被設置爲DbType.Int32?

2)你能發佈你的調試器遇到錯誤的實際代碼嗎? (我假設上面是僞代碼)

3)您是否驗證了失敗是否在Parameter.Value賦值行? (而不是在命令執行,例如)


來源
下載.NET提供源 - Provider
7zip的提取源(如果你沒有的話) - 7Zip

構建
[備份您當前的源正在修改任何東西]
1)右鍵單擊您的C#解決方案並選擇添加 - >現有的解決方案
2)選中*從您提取提供商源
目錄的.csproj [.. \ NETProvider \源\ FirebirdSql \數據\ FirebirdSql.Data.FirebirdClient.csproj]
3)右點擊FirebirdClient項目並構建它
4)將應用程序中的FirebirdSql.Data.FirebirdClient引用更改爲您剛剛編譯的版本
[.. \ Data \ bin \ Debug \ FirebirdSql.Data.FirebirdClient.dll]

現在您應該能夠進入(F11)您的ExecuteScalar語句並查看轉換異常正在引發的位置。

讓我知道是否有任何意義。我很有興趣看到你找到的東西

+0

我確定在所有情況下參數都設置爲DbType.Decimal。命令執行期間發生異常,而不是參數分配。我會將它發生的行粘貼到我的問題中。 – dthrasher 2010-02-05 20:48:31

+0

1)ExecuteScalar是否返回一個對於Int32來說太大的數字來處理? (> 2,147,483,647) 2)您正在執行的sql語句/過程/表是否具有正確的數據類型? (在數據庫中,數據類型是不兼容的) – bluecoder 2010-02-05 21:10:48

+0

1)不,我的聯繫人表的ID在數百個。我沒有接近Int32的返回值限制。 2)存儲過程和表都有正確的類型。該程序在Firebird Maestro IDE中執行得很好。 – dthrasher 2010-02-05 21:20:45