Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.08.16;
Скачать: CL | DM;

Вниз

Incorrect values within SQLDA structure при выполнении запроса   Найти похожие ветки 

 
pushkin42 ©   (2008-11-04 19:53) [0]

Есть вот функция такая:  (D2007, FB2, dbExpress):

function TSQLDatabaseThread.SelectSQLA(const Q: String; const ParamNames,
 ParamValues: array of Variant): TSQLDataSet;

var Command: String;
   PNI, PNC: Integer;

 function ParamType(const Param: Variant): Byte;
 var basicType: TVarType;
 begin
   basicType := VarType(Param) and VarTypeMask;

   case basicType of
     varEmpty     : Result := VT_EMPTY;
     varNull      : Result := VT_NULL;
     varSmallInt  : Result := VT_SMALLINT;
     varInteger   : Result := VT_INTEGER;
     varSingle    : Result := VT_SINGLE;
     varDouble    : Result := VT_DOUBLE;
     varCurrency  : Result := VT_CURRENCY;
     varDate      : Result := VT_DATE;
     varBoolean   : Result := VT_BOOL;
     varVariant   : Result := VT_VARIANT;
     varUnknown   : Result := VT_UNKNOWN;
     varByte      : Result := VT_BYTE;
     varWord      : Result := VT_WORD;
     varLongWord  : Result := VT_WORD;
     varInt64     : Result := VT_INT64;
     varStrArg    : Result := VT_STRING;
     varString    : Result := VT_STRING;
     varAny       : Result := VT_ANY;
     varTypeMask  : Result := VT_TYPEMASK;
     else Result := VT_UNKNOWN;
   end;
 end;
begin
 // выполнение запроса (определение автоматическое)
 Result := TSQLDataSet.Create(nil);

 if Connection.Connected=False then begin
   Connection.Connected := True;
 end;

 Result.SQLConnection := Connection;

 Result.ParamCheck := (Length(ParamNames)<>0);

 //try
   Result.CommandText := Q;
   Command := Parse(Q, #32, 1);

//    Result.Params := TParams.Create(Result);
   Result.Params.Clear;
   Result.Close;

   if Length(ParamNames)<>0 then begin
   // перечисление параметров
     PNC := Length(ParamNames)-1;  // количество параметров
     for PNI := 0 to PNC do begin
       case ParamType(ParamValues[PNI]) of
         VT_UNKNOWN,
         VT_NULL        : Result.Params.CreateParam(ftUnknown, ParamNames[PNI], ptInputOutput);

         VT_SMALLINT    : Result.Params.CreateParam(ftSmallInt, ParamNames[PNI], ptInputOutput);
         VT_INTEGER,
         VT_SINGLE      : Result.Params.CreateParam(ftInteger, ParamNames[PNI], ptInputOutput);
         VT_DOUBLE      : Result.Params.CreateParam(ftFloat, ParamNames[PNI], ptInputOutput);
         VT_CURRENCY    : Result.Params.CreateParam(ftCurrency, ParamNames[PNI], ptInputOutput);
         VT_DATE        : Result.Params.CreateParam(ftDate, ParamNames[PNI], ptInputOutput);
         VT_BOOL        : Result.Params.CreateParam(ftBoolean, ParamNames[PNI], ptInputOutput);
         VT_VARIANT     : Result.Params.CreateParam(ftVariant, ParamNames[PNI], ptInputOutput);
         VT_BYTE        : Result.Params.CreateParam(ftFloat, ParamNames[PNI], ptInputOutput);
         VT_WORD,
         VT_LWORD       : Result.Params.CreateParam(ftWord, ParamNames[PNI], ptInputOutput);
         VT_INT64       : Result.Params.CreateParam(ftInteger, ParamNames[PNI], ptInputOutput);
         VT_STRARG,

         VT_STRING      : Result.Params.CreateParam(ftString, ParamNames[PNI], ptInputOutput);

         VT_ANY         : Result.Params.CreateParam(ftVarBytes, ParamNames[PNI], ptInputOutput);
         VT_TYPEMASK    : Result.Params.CreateParam(ftUnknown, ParamNames[PNI], ptInputOutput);

         else
                          Result.Params.CreateParam(ftVariant, ParamNames[PNI],
                          ptUnknown);
       end;
       Result.Params.ParamByName(ParamNames[PNI]).AsString :=
       String(ParamValues[PNI]);
     end;
   end;

   if (Command="SELECT") then begin
     Result.Open
   end else begin
     Result.ExecSQL();
     FinalizeSQL(Result);
   end;
 {
 except
   Result.Close;
   Result.Free;
   Exit(nil);
 end;
 }
end;


Почему-то если параметрами подсунуть скажем ["uid", 3] то выполняется нормально и возвращает датасет. А вот если подсунуть скажем ["uname", "какая_то_строка"], выдает "Incorrect values within SQLDA structure". ParamCheck := False не помогло.

Где могут быть грабли?


 
Johnmen ©   (2008-11-04 20:03) [1]

Можно поинтересоваться, зачем все эти танцы нужны?
И почему для ФБ используется дбЕкспресс?


 
pushkin42 ©   (2008-11-04 20:10) [2]

Танцы... для универсализации, наверное. Мне удобнее написать один раз функцию, выполняющую все виды запросов, и потом приспособить ее под отдельные цели вида ExecSQL(Query) и SelectSQL(Query).

Используется dbExpress потому, что по вынужденным причинам пересел на Tiburon, в котором IB компоненты нещадно глючат (видимо, сырые), а это оказались единственные компоненты, которые работают. FIB и иже с ними покупать не хочу - пишу для себя - дорого...


 
Johnmen ©   (2008-11-04 20:17) [3]


>  для универсализации, наверное. Мне удобнее написать один
> раз функцию, выполняющую все виды запросов,

Это бесперспективное заблуждение...

А по сути:
- приводи сам запрос,
- дбЕкспресс весьма специфичен, попытки на его основе что-то "универсализировать" за рамками работы с MySQL, обречены на провал,
- данное сообщение означает, что функция клиентской длл не смогла выделить и заполнить область параметров.


 
pushkin42 ©   (2008-11-04 20:20) [4]

А что вы можете предложить "в рамках" решения данного вопроса? Я не хочу использовать специфичный софт и компоненты, я часто пишу OpenSource, и часто пишу в команде (всем не поставишь). Возвращаться на Delphi 7 не хочу.


 
Johnmen ©   (2008-11-04 20:32) [5]

Лично я бы не гнался за "универсализацией". В данном случае мы же заранее знаем вид запроса, а значит и количество и качество параметров...
Для получения наборов данных - одни компоненты, для выполнения остальных запросов - другие. А вид запроса меняй наздоровье в рантайме.
И параметры будут создаваться "на лету" неявно. Останется только их определить в цикле по элементам открытого массива.


 
Правильный$Вася   (2008-11-04 20:52) [6]


> дбЕкспресс весьма специфичен, попытки на его основе что-
> то "универсализировать" за рамками работы с MySQL, обречены
> на провал,

весьма смелое утверждение, надо признать

> Мне удобнее написать один раз функцию, выполняющую все виды
> запросов, и потом приспособить ее под отдельные цели вида
> ExecSQL(Query) и SelectSQL(Query).

имхо, излишне


 
Johnmen ©   (2008-11-04 21:25) [7]


> весьма смелое утверждение, надо признать

Да, смелое, согласен.
Если у кого-то будут подтвержденные противоположные мнения - с удовольствием выслушаю.


 
PEAKTOP ©   (2008-11-05 12:45) [8]

> Johnmen ©   (04.11.08 21:25) [7]
> Если у кого-то будут подтвержденные противоположные мнения - с удовольствием выслушаю.


Не будет.
Сколько народ не учи, что быстрее чем через API и ручное управление транзакциями ничего нет. Все равно не понимают: то труп BDE где-то выкопают, то dbExpress, то ODBC. Нет, конечно, я понимаю кодеров на M$VC, Java - им деваться некуда от этих прослоек, да и самому из 1C коннектиться через ODBC приходилось. Но если ты пишешь на Delphi, нахрена лезть то в эти дебри ? Тот же IBX, хоть он и кривой на всю голову, но при определенном привыкании к глюкам позволяет нормально писать.


 
Правильный$Вася   (2008-11-05 14:19) [9]


> Тот же IBX, хоть он и кривой на всю голову, но при определенном
> привыкании к глюкам позволяет нормально писать.

а вот dbx для IB вовсе не кривой и ни к каким глюкам привыкать не нужно
или нужно стать любителем кошерных компонентов, чтоб хвастаться своим любимым, но страшным способом?


 
GRAND ©   (2008-11-05 14:30) [10]


> FIB и иже с ними покупать не хочу - пишу для себя - дорого.
> ..


Все же стоило бы поискать по нышпоркам, ИМХО - для IB/FB/YA человечество ничего лучшего не изобрело.


> кривой на всю голову


- это можно сказать обо всем, кроме фибов, что вы попытаетесь так или иначе приспособить под FB.


 
PEAKTOP ©   (2008-11-05 16:46) [11]

> - это можно сказать обо всем, кроме фибов, что вы попытаетесь так или иначе приспособить под FB.

Никто уже давно не пытается :)

У половины людей из FirebirdFoundation самописные библиотеки. В том числе и у Сергея Бузаджи. По последней скажу: не кошерно это использовать в потомке TDataSet (имеющем пять действий Select, Refresh, Insert, Update, Delete) две транзакции -  это годится только для студенческих курсовых, потому как практика в некоторых случаях заставляет использовать пять транзакций с разными параметрами. Поэтому у большинства людей пяти-транзакционные библиотеки.

Я свою писал на базе IBX от Delphi7. Конечно, пришлось обработать напильником, в некоторых местах - резал болгаркой и "приваривал". :) Зато не страдал фигней, и в процессе создания ни разу не пытался в отладчике выловить багу в говнокоде, к коему я причисляю FIBPlus, несмотря на его стабильность. IBX тоже не страдает чистотой кода, непонятно вообще, как Borland/CodeGear/Embarcadero выпустили это в продажу на фоне кода самой VCL. Наверное, чтобы потребители прочувствовали разницу ? :)


 
GRAND ©   (2008-11-05 17:20) [12]


> потому как практика в некоторых случаях заставляет использовать
> пять транзакций с разными параметрами. Поэтому у большинства
> людей пяти-транзакционные библиотеки.


Нет, я такого авангардизма не понимаю :))) Интересно было бы ознакомиться с каким-нибудь примером острой необходимости пятитранзакционного датасета, ибо даже моя извращенная фантазия вряд ли подобное сможет породить.

Обработанный напильником IBX - это агхиинтересно, конечно. Но до какой степени можно обрабатывать это "чудо" напильником, если там сама фундаментальная идеология уже на старте во многом проигрывает фибам? Может, просто лучше правильно юзать фибы? ;)


 
PEAKTOP ©   (2008-11-05 18:24) [13]

>GRAND ©   (05.11.08 17:20) [12]
> Но до какой степени можно обрабатывать это "чудо" напильником, если там сама фундаментальная идеология уже на старте во многом проигрывает фибам? Может, просто лучше правильно юзать фибы? ;)


Филосфия IBX = Философия TDataSet = Философия FIBPlus, также  = моя библиотека. Потому, как только так и не иначе, если Вы хотите увидеть Ваш набор данных в TDBGrid и проч. До какой степени ? - Наверное, пока камня на камне не останется :)

Фундаментально - философия IBX проигрывает:
1)  В подключениях. У меня может быть более чем одна клиентская библиотека доступа, в том числе и к устаревшему InterBase, и Embedded Firebird, с помощью которой я подгружаю данные из "БазыУдаленогоФилиала" в "ЦентральнуюБазу", которая где-то-там...
2) В транзакциях наборов данных. По минимуму - две (что уже есть в FIBPlus), по правильному - пять.

> Интересно было бы ознакомиться с каким-нибудь примером острой необходимости пятитранзакционного датасета, ибо даже моя извращенная фантазия вряд ли подобное сможет породить.

Видимо, у Вас не по настоящему извращенная фантазия :)
-----------------------
Кстати, камень в огород IBX и FIBPlus. Попробуете сделать INSERT в наборе данных, потом Post набора данных, а потом - Update этой же самой (только что вставленной) записи и ее же Post. А потом посмотрите, какая версия сохранится. :)

Вот и я говорю - пять транзакций....


 
GRAND ©   (2008-11-05 20:52) [14]


> Филосфия IBX = Философия TDataSet = Философия FIBPlus, также
>  = моя библиотека


А что тогда есть философия чуть более высокого уровня - TTable? ;) Вот тут-то мы и приходим к кардинальному различию: в FIBPlus этого уродство отсутствует.


> Кстати, камень в огород IBX и FIBPlus. Попробуете сделать
> INSERT в наборе данных, потом Post набора данных, а потом
> - Update этой же самой (только что вставленной) записи и
> ее же Post. А потом посмотрите, какая версия сохранится.
>  :)


Проверил: последняя (проапдейченная) версия. Как и должно быть. Собственно, я здесь проблем не вижу вот по какой причине: пять операций с датасетами (Select, Refresh, Insert, Update, Delete) прекрасно делятся на читающие и пишущие. Первые две работают в читающей транзакции, остальные три - в пишущей. Я не вижу чего-то непреодолимого, что может заставить Select и Refresh работать в разных транзакциях, а также Insert, Update и Delete. Более того, смысла я этом тоже не вижу ;)



Страницы: 1 вся ветка

Текущий архив: 2009.08.16;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.014 c
15-1244644377
Медвежонок Пятачок
2009-06-10 18:32
2009.08.16
сатанисты среди нас


1-1211958221
Still Swamp
2008-05-28 11:03
2009.08.16
Dsgjkyb


15-1244745720
DeadMeat
2009-06-11 22:42
2009.08.16
Чат для локалки


2-1245257837
Bred
2009-06-17 20:57
2009.08.16
Unable to invoke Code Completion due to errors in source code


2-1245399366
parasolka
2009-06-19 12:16
2009.08.16
Зафиксировать размаер панели.