Форум: "Базы";
Текущий архив: 2009.08.16;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.006 c