В моем случае, определение параметров и назначение строки запроса перед назначением соединения решило проблему.Запрос выполняется в обоих случаях успешно, но компонент TADOQuery
внутренне вызывает (и впоследствии глотает) значение EOleException
, указанное в OP, если соединение назначено до параметризованного запроса.
//LADOQuery.Connection := LADOConnection; // Exception @ LADOQuery.Text:=...
Param := LADOQuery.Parameters.AddParameter;
Param.Name := 'rid';
Param.DataType := ftFixedChar;
Param := LADOQuery.Parameters.AddParameter;
Param.Name := 'qd';
Param.DataType := ftLongWord;
LADOQuery.SQL.Clear;
LADOQuery.SQL.Text:='SELECT Val FROM table WHERE v1=:rid AND v2=:qd';
LADOQuery.Connection := LADOConnection; // OK!
Я открыт для объяснений, почему это так - ничто в документации, похоже, не указывает на необходимость такого порядка операций.
Исключение возникает в файле ADODB.pas в TADOCommand.AssignCommandText
здесь
try
// Retrieve additional parameter info from the server if supported
Parameters.InternalRefresh;
, где эта ветвь используется только в том случае, если TADOQuery
присоединено к действующему соединению.InternalRefresh
выполняет:
if OLEDBParameters.GetParameterInfo(ParamCount,
PDBPARAMINFO(ParamInfo),
@NamesBuffer) = S_OK then
for I := 0 to ParamCount - 1 do
with ParamInfo[I] do
begin
// When no default name, fabricate one like ADO does
if pwszName = nil then
Name := 'Param' + IntToStr(I+1) else // Do not localize
Name := pwszName;
// ADO maps DBTYPE_BYTES to adVarBinary
if wType = DBTYPE_BYTES then wType := adVarBinary;
// ADO maps DBTYPE_STR to adVarChar
if wType = DBTYPE_STR then wType := adVarChar;
// ADO maps DBTYPE_WSTR to adVarWChar
if wType = DBTYPE_WSTR then wType := adVarWChar;
Direction := dwFlags and $F;
// Verify that the Direction is initialized
if Direction = adParamUnknown then Direction := adParamInput;
Parameter := Command.CommandObject.CreateParameter(Name, wType, Direction, ulParamSize, EmptyParam);
Parameter.Precision := bPrecision;
Parameter.NumericScale := ParamInfo[I].bScale;
// EOleException raised here vvvvvvvvv
Parameter.Attributes := dwFlags and $FFFFFFF0; //Mask out Input/Output flags
AddParameter.FParameter := Parameter;
end;
Проблема определенно возникает на уровне OLE, возможно, из-за того, что драйвер MySQL ODBC не поддерживает возврат этой информации (или возвращает неверную информацию).Исключение возникает за интерфейсом _Parameter
при настройке
Parameter.Attributes := dwFlags and $FFFFFFF0;
с использованием, как представляется, недопустимых значений (dwFlags
= 320 -> биты, установленные выше DBPARAMFLAGSENUM
определенной длины), возвращаемых из GetParameterInfo
,Обработка исключений для управления потоком кажется единственной возможностью, учитывая, что интерфейс не предоставляет какого-либо механизма для проверки значений перед их установкой (и инициированием исключений).
Обновление:
Оказывается, есть открытый QC по этому поводу: http://qc.embarcadero.com/wc/qcmain.aspx?d=107267