DELPHI ERROR : Multiple-step operation generater error. Check each status value - delphi

I have a procedure when click a bitbutton, it open a dialog box to load some files, and add it into AdoQuery (AQSource1). When I add some files, this error appear :
"Multiple-step operation generater error. Check each status value."
Only when I add multiple files selected. But if I selected a file by a file there is no error at all... But sometimes if I select multiple files this error did not show up either.... Kind a confusing for me...
How to fix this ? in simple way...
PS:
I use Windows 7 Pro SP1 64bit, Embarcadero Delphi 2010
procedure TFMain1.btImgLoad1Click(Sender: TObject);
var i : integer;
strFilename : string;
begin
if OpenDialog1.Execute then
begin
// Add selected file to DBase and show it on DBGrid
for i := 0 to openDialog1.Files.Count-1 do
begin
// ShowMessage(openDialog1.Files[i]);
strfilename := openDialog1.Files[i];
AQSource1.Append;
AQSource1source_fileurl.Value := strFilename;
AQSource1source_filename.Value := ExtractFileName(strfilename);
AQSource1source_dateadd.Value := date();
AQSource1source_timeadd.Value := Time();
AQSource1.Post;
AQSource1.Close;
AQSource1.Open;
end;
end;
end;

Ah... Finally I found what the cause of it. It lies on the "Field size" in Access and AdoQuery in Delphi. The field size for both is 50. When I change them to 255, whola.... the error is gone....
So based on my conclusion, the error for "Multiple-step operation generater error. Check each status value." for my case was caused by the FIELD SIZE... Thanks ^^

this error usually occur when there is a values change on the server side and the changes are not being reflected on the client.for example when on/before insert trigger that change field value .
so all you need that is to change Adotable1.CursorLocation to the option clUseServer . no thing else.
good luck

I have similar experience, In one instance, when I have synthesized the required SQL text, and did not care about alias name & the ADO makes that alias automatically (which is a long name) this error occurs. the solution is to give an alias directly in the statement to by pass this short coming.

Related

Error when using parameter in ADOQuery

I have this simple code to check if a record exists in a table, but it always returns a runtime error :
Arguments are of the wrong type, are out of acceptable range, or are
in conflict with one another.
my code is this :
function TDataModuleMain.BarCodeExists(barCode: string): boolean;
begin
if ADOQuerySql.Active then
ADOQuerySql.Close;
ADOQuerySql.SQL.Clear;
ADOQuerySql.SQL.Text := 'select count(1) from Card where BarCode = (:TestBarcode)';
ADOQuerySql.Parameters.ParamByName('TestBarcode').Value := barCode;
ADOQuerySql.Open; // HERE THE RUNTIME ERROR APPEARS
Result := ADOQuerySql.Fields[0].AsInteger = 1;
ADOQuerySql.Close;
ADOQuerySql.Parameters.Clear;
end;
The field BarCode in table Card is of type nvarchar(100)
In debug I see that the parameter is created, and gets populated with the correct value.
Running the query in sql server management studio also works.
I also found this How to pass string parameters to an TADOQuery? and checked my code with the code in the answer but I don't see any problems here.
Also this AdoQuery Error using parameters did not help me.
It will no doubt be something very simple that I have missed but I just dont see it now.
EDIT : things I tried from suggestions in the comments:
.ParamCheck := True (default)
.Parameters.ParamByName('TestBarcode').DataType := ftString
.Parameters.ParamByName('TestBarcode').DataType := ftWideString
None of these worked however.
What did help was using a non-shared AdoQuery for this, and that one did the job without any errors. I am using that now as the solution but I am still looking at the shared AdoQuery out of curiousity what the exact problem is.
EDIT: the source of the problem is found.
I used the function provided by MartinA to examine both the dynamic created query and the shared AdoQuery and I found one difference.
The shared AdoQuery had the this property filled :
ExecuteOption := [eoExecuteNoRecords]
and the dynamic created query does not.
Since this property is not set in designtime I did not see it.
After clearing the property to [] the shared AdoQuery worked again.
I am going to switch to using non shared AdoQuery for this kind of work as been suggested.
Thanks everyone for your assistance.
The following isn't intended to be a complete answer to your q, but to follow up my comment that "all you have to do is to inspect your form's DFM and compare the properties of your original ADoQuery with the unshared one. The answer should lie in the difference(s)" and your reply that the unshared query is created dynamically.
There is no "voodoo" involved in the difference in behaviour between your two ADOQuerys. It's just a question of capturing what the differences actually are.
So, what you need, to debug the problem yourself, is some code to compare the properties of two components, even if one or both of them is created dynamically. Using the following routine on both components will enable you to do exactly that:
function TForm1.ComponentToString(AComponent : TComponent) : String;
var
SS : TStringStream;
MS : TMemoryStream;
Writer : TWriter;
begin
// Note: There may be a more direct way of doing the following, without
// needing the intermediary TMemoryStream, MS
SS := TStringStream.Create('');
MS := TMemoryStream.Create;
Writer := TWriter.Create(MS, 4096);
try
Writer.Root := Self;
Writer.WriteSignature;
Writer.WriteComponent(AComponent);
Writer.FlushBuffer;
MS.Position := 0;
ObjectBinaryToText(MS, SS);
Result := SS.DataString;
finally
Writer.Free;
MS.Free;
SS.Free;
end;
end;
Over to you ...

Max length TSQLConnection.Params values

Hello fellow StackOverflowers,
Currently I'm facing a situation where it seems that there is a maximum length for the Database property of a TSQLConnection object in Delphi.
When I open the connection to my database I get the following error when I use a rather long (154 chars) database name:
dbExpress Error: [0x0015]: Connection failed
SQL Server Error: unrecognized database parameter block
wrong version of database parameter block
When I relocate my database file to another location (and with that reduce the length of the path) it will connect to the database.
I am currently using the Object Inspector to set the connection properties of the TSQLConnection object.
Basically, my question comes down to this:
Does a TSQLConnection have a maximum length for the values set in the Params property? And if so, what is the maximum length of these values?
Update
I've found two ways to open a copy of Employee.Gdb in a folder with a 160-character name ('abcdefghij0123456789' x 8).
What I did firstly was to edit the DBXConnections.Ini file and changed the Database parameter in the [IBConnection] section to read
Database=localhost:D:\abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890\employee.gdb
Then, I can successfully connect to it, open the Employee.Gdb and make changes to the Customer table. I have verified the changes in IBConsole just in case the copy of Employee.Gdb wasn't the one I assumed it was.
Subsequently, I've found that I can create and open the db in code using Delphi Seattle and Interbase XE7, as follows:
function LongPath : String;
begin
Result := 'D:\' + DupeString('abcdefghij0123456789', 8);
end;
function LongDBName : String;
begin
Result := LongPath + '\Employee.Gdb';
end;
procedure TForm1.OpenDB;
var
Ini : TMemIniFile;
const
scDBXConIni = 'C:\Users\Public\Documents\Embarcadero\Studio\dbExpress\17.0\dbxconnections.ini';
scSourceDB = 'D:\Delphi\Databases\Interbase\Employee.Gdb';
begin
Ini := TMemIniFile.Create(scDBXConIni);
try
// First, blank out the Database value in the IBConnection section
// of DBXConnections.Ini
Ini.WriteString('IBConnection', 'Database', '');
Ini.UpdateFile;
// Next, create the long-named directory and copy Employee.Gdb to it
if not DirectoryExists(LongPath) then
MkDir(LongPath);
Assert(CopyFile(PChar(scSourceDB), PChar(LongDBName), False));
// Set LoadParamsOnConnect to False so that the SqlConnection uses
// the value of the Database we are about to give it
SqlConnection1.LoadParamsOnConnect := False;
SqlConnection1.Params.Values['Database'] := LongDBName;
SqlConnection1.Connected := True;
// Open the CDS to view the data
CDS1.Open;
finally
Ini.Free;
end;
end;
The critical step in doing it this way is setting LoadParamsOnConnect to False, which I confess I'd overlooked in earlier attempts to get this code to work.
I've got some earlier versions of Delphi on this machine, so if you're not using Seattle and the above code doesn't work for you, tell me which one you are using and I'll see if I can try that.
**[Original answer]
Actually, I think that this may be an error occurring in one of the DBX DLLs.
I created a folder with a 160-character name, then copied the demo Employee.Gdb database into it. Interbase XE7's IBConsole can open the db without error. So could a small test project contructed with IBX components in Delphi Seattle.
However, with an equivalent DBX project, when I use the code below
procedure TForm1.Button1Click(Sender: TObject);
begin
SqlConnection1.Params.Values['database'] := 'D:\abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890abcdefghij01234567890\employee.gdb';
SqlConnection1.Connected := True;
end;
I get an error in
procedure TDBXDynalinkConnection.DerivedOpen;
var
Count: TInt32;
Names: TWideStringArray;
Values: TWideStringArray;
IsolationLevel: Longint;
DBXError: TDBXErrorCode;
begin
Count := FConnectionProperties.Properties.Count;
FConnectionProperties.GetLists(Names, Values);
CheckResult(FMethodTable.FDBXConnection_Connect(FConnectionHandle, Count, Names, Values));
DBXError := FMethodTable.FDBXConnection_GetIsolation(FConnectionHandle, IsolationLevel);
'I/O error for file "database.gdb"
Error while trying to open file
The operation completed successfully'
and the Database param of the SqlConnection is left at the value 'Database.Gdb', which is not the value I specified, of course, nor was it the value specified in the params in the IDE, which was 'd:\delphi\databases\interbase\employee.gdb'.
I wondered if I could work around this problem by SUBSTing a drive to the 'abcdefg ...' path. I tried that and opening the database as "x:\employee.gdb" , but I get the same error in my DBX app, and also IBConsole cannot access the db either.
I think you need a shorter physical path!**
This is related to MSSql Server:
As a general guideline, long path names greater than 160 characters
might cause problems.
from Microsoft TechNet - https://technet.microsoft.com/en-us/library/ms165768(v=sql.105).aspx

EDataBase error with ClientDataset parameter not found

I have added new TClientDataset in my project, to client. Also I have an Oracle stored procedure that takes clientid as input & returns cursor.
The code below executes on button click
with dmMain.cdsGetV do //cdsGetV is name of Clientdataset
begin
if Active then Close;
Params.Clear;
FetchParams;
Params.ParamByName('PCLIENTID').AsString := '0022995544';
Open;
end;
On click I have error: `
cdsGetV: parameter 'pclientid' not found.
There are many other clientdatasets like this and they work good. I copied exactly the same code of those cds', but it's still not working. Any idea what's problem?
I recreated the clientdataset and datasetprovider on server ,and now it works.

Delphi F2084 Internal Error: AV07953449-R26D7474C-0

In my project, i'm trying to connect one more UNIT, named Lang_Unit.pas with some classes and procedures, but, while compiling the Project, Delphi gives unknown error called "[dcc32 Fatal Error] Lang_Unit.pas(5): F2084 Internal Error: AV07953449-R26D7474C-0".
And the point is that, what if i will close my project, or remove this connected UNIT, error is not getting away.
And if i will create clear default VCL Application, its still gives this error.
And only when i'm restarting my Delphi 2010, error is getting away.
But, if i will try to edit something in the code, this error is comes again...
What is problem ? Everything was works fine, im not touched nothing.
I've just turned off my PC, then after some time turned it ON and opened my Project and edited my code, then i see this error...
If Its will help, here is my Lang_Unit.pas code :
unit Languages_UNIT;
interface
Uses
System.Generics.Collections, IniFiles;
Type
TLanguages_List = Class
private
LangType:string;
LangDescription:string;
LangFile:TIniFile;
public
Constructor Create(LType,LDes:string; LFile:TiniFile);
Function GetLangType:string;
Function GetDescription:string;
Function GetStructure:TIniFile;
End;
TLanguages_Controller = Class
public
Function GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
Function TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
Procedure LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
End;
implementation
uses Unit1;
Constructor TLanguages_List.Create(LType,LDes:string; LFile:TiniFile);
Begin
LangType:=LType;
LangDescription:=LDes;
LangFile:=LFile;
End;
Function TLanguages_List.GetLangType:string;
Begin
Result:=LangType;
End;
Function TLanguages_List.GetDescription:string;
Begin
Result:=LangDescription;
End;
Function TLanguages_List.GetStructure:TIniFile;
Begin
Result:=LangFile;
End;
Function TLanguages_Controller.GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
var
i:integer;
Begin
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
Result:=LangList[i].GetStructure;
Break;
End;
End;
End;
Function TLanguages_Controller.TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
var
i:integer;
GOTYA:Boolean;
Begin
GOTYA:=False;
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
GOTYA:=True;
Break;
End;
End;
IF(GOTYA) Then
Result:=True
Else
Result:=False;
End;
Procedure TLanguages_Controller.LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
var
i:integer;
SLS:TIniFile;//SELECTED LANGUAGE STRUCTURE
CS:string;//CURRENT SECTION
Begin
//GET SELECTED LANGUAGE STRUCTURE
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
SLS:=LangList[i].GetStructure;
Break;
End;
End;
//START LOADING SELECTED LANGUAGE
//TABS SECTION LOAD
CS:='TABS';
SD_DEFNAME:=SLS.ReadString(CS,'Speed_Dials','Speed_Dials');
Form1.goleft.Hint:=SLS.ReadString(CS,'Back','Back');
Form1.goright.Hint:=SLS.ReadString(CS,'Forward','Forward');
REFLESHBTN_TEXT:=SLS.ReadString(CS,'Reflesh','Reflesh');
STOPBTN_TEXT:=SLS.ReadString(CS,'Stop','Stop');
//PAGE_POPUP SECTION LOAD
CS:='PAGE_POPUP';
Form1.ChromiumPopup.Items[0].Caption:=SLS.ReadString(CS,'Forward','Forward');
Form1.ChromiumPopup.Items[1].Caption:=SLS.ReadString(CS,'Back','Back');
Form1.ChromiumPopup.Items[2].Caption:=SLS.ReadString(CS,'Reflesh','Reflesh');
Form1.ChromiumPopup.Items[3].Caption:=SLS.ReadString(CS,'Copy_Link','Copy Link');
Form1.ChromiumPopup.Items[4].Caption:=SLS.ReadString(CS,'Save','Save');
Form1.ChromiumPopup.Items[5].Caption:=SLS.ReadString(CS,'Print','Print');
Form1.ChromiumPopup.Items[6].Caption:=SLS.ReadString(CS,'view_source','View Source');
Form1.ChromiumPopup.Items[7].Caption:=SLS.ReadString(CS,'code_debug','Code Debug');
End;
end.
Internal error means that the compiler itself is in a 'confused' state.
The way to get out of this is to:
Save your code in a safe location for later reference.
Restart Delphi
Revert the source code to the last known good state by undoing your last edits, or by loading a temp save file.
You can find the previous files in the _backup folder.
Make sure to set file type to any file.
In order to have Delphi generate a save file upon compilation you need to enable autosave
It's a good idea to have Delphi keep more than the default 10 saves. I like to set it to the max: 90.
Just keep restarting Delphi, and compile a previous version, until the internal error goes away.
Then you just recreate the code in a slightly different manner.
(You did save the original code right?)
I also had this problem (in Delphi 10 Berlin). It started shortly after I changed the name of a component in a frame. It also seemed very persistent. However I found the by right clicking the project and selecting 'Clean' followed by 'Build' solved the problem.
I had this issue with my system drive's memory less than 300mb left. It was especially choking in the cache folder. Prior to this error I had a sensible error (fatal error DBG) when I was attempting to recurse already async functions into a larger async function in a big multi threaded application. The compiler just gave up!(perhaps for circular references and too many subfunctions of a function) The two errors may not be related. But after freeing the system drive to about 2 Gigs upon restart and correcting the above mistake, I did a clean then it compiled just fine.
In my case, the solution for the F2084 error code was to change the encoding from ANSI to UTF8.
In my case, I made several packages that related one to another, and all were built as design and run time packages. But one day, I changed some of them to run-time only packages. After that I experienced this kind of error. It took me hours to realize that I should rebuilt all other related packages. After doing that, the error was away eventually.

How can I change the TEdit default error message (NumbersOnly mode)?

How can I change the TEdit's default error message when I use it in NumbersOnly mode. I mean this error:
Unacceptable character You can only type a number here
Is it possible to change this message ?
I don't know a direct way to change the value of that message (which is handled by Windows) but you can show your own message and then avoid to show the original windows hint ballon, using the Abort procedure in the OnKeyPress Event.
Check this sample
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (CharInSet(Key,['0'..'9',#8,#9])) then
begin
ShowHintMessage('Only numbers please');//you must write this function
Abort;//this will prevent which the original windows hint was shown
end;
end;
You must we aware which this code will be prevent the execution of the clipboard operations over the control.
Update
I Update the code to allow the Tab(#9) and Back space(#8) chars.
Looking at the VCL source, it looks like that message is generated by windows, rather than by Delphi. That is, the VCL is only wrapping the functionality that exists in windows. So it doesn't appear that it would be easy to modify the message.

Resources