Использование десятичных параметров в хранимых процедурах Firebird - PullRequest
1 голос
/ 05 февраля 2010

У меня есть хранимая процедура 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 из исходного кода. Но я получаю ошибку компиляции в строке 731 файла GdsStatement.cs.

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 ]

2 голосов
/ 05 февраля 2010

Сначала проверяем очевидное:

1) Вы уверены, что ни один из параметров Parameter.DbType не установлен в DbType.Int32?

2) Можете ли вы опубликовать фактический код, где ваш отладчик обнаруживает ошибку? (Я предполагаю, что это псевдокод выше)

3) Вы проверили, что ошибка находится в строке назначения Parameter.Value? (Например, не при выполнении команды)


Источник
Загрузить источник провайдера .Net - Провайдер
7zip для извлечения источника (если у вас его нет) - 7Zip

Строить
[Сделайте резервную копию вашего текущего источника, изменяя что-либо]
1) Щелкните правой кнопкой мыши на своем решении C # и выберите «Добавить» -> «Существующее решение»
. 2) выберите * .csproj из каталога, из которого вы извлекли источник провайдера в
[.. \ NETProvider \ источник \ FirebirdSql \ Data \ FirebirdSql.Data.FirebirdClient.csproj]
3) Щелкните правой кнопкой мыши по проекту FirebirdClient и постройте его
4) Измените ссылку FirebirdSql.Data.FirebirdClient в вашем приложении на версию, которую вы только что скомпилировали
[.. \ Data \ bin \ Debug \ FirebirdSql.Data.FirebirdClient.dll]

Теперь вы должны быть в состоянии (F11) выполнить оператор ExecuteScalar и посмотреть, где возникает исключение преобразования.

Дайте мне знать, если что-то из этого не имеет смысла. Мне интересно посмотреть, что вы найдете

0 голосов
/ 19 февраля 2010

Я только что обнаружил, что у меня есть устаревшая ссылка на Firebird Client 2.5.1 в моем GAC. После удаления этой ссылки я смог успешно выполнить свои тесты.

Поставщик .NET для Firebird версии 2.5.2 не имеет проблемы, описанной в моем вопросе. Решением является обновление до последней версии .NET Provider for Firebird.

...