Enquiring Mind
2008-04-28 14:11:06 UTC
Hi,
Can anyone help with the following questions about TSQLDataset?
1. When executing a SQL 'SELECT' command, is each row downloaded separately
when SQLDataset.Open or SQLDataset.Next is called, or are all the rows
downloaded into a temporary variable when SQLDataset.Open is called, and
SQLDataset.Next just moves the cursor to the next row in the temporary
variable? For example, the purpose of the following code is to download all
the rows from a table into a custom data structure:
SQLDataset.CommandText:= 'SELECT * FROM ' + FTableName;
SQLDataset.Open;
SQLDataset.First;
while not SQLDataset.Eof do
begin
RecordI:= FBaseRecordClass.Create(Self);
RecordI.ReadFromSQLDataset(SQLDataset);
AddNewRecord(RecordI, Done);
SQLDataset.Next;
end;
If the table contains say 100 records, will there be 100 downloads, or just
one download?
2.Can NULL values be uploaded in parameters in SQL INSERT or UPDATE
statements? I tried the following code:
{Assign SQL command:}
SQLDataset.CommandText:= 'UPDATE Projects SET DateTimeModified=
:DatetimeModified '
+ ', Name= :Name, ParentProjectIndex= :ParentProjectIndex'
+ ' WHERE ProjectIndex= :ProjectID';
{Set input parameters:}
with SQLDataset.Params do
begin
{.}ParamByName('ProjectID').AsInteger:= FID;
{.}ParamByName('DatetimeModified').AsSQLTimestamp:=
FDatetimeModified;
{.}ParamByName('Name').AsString:= FName;
with {.}ParamByName('ParentProjectIndex') do
begin
if FParent= nil then
begin
{.}Clear; {Set parameter to Null}
{.}Bound:= True;
end
else
{.}AsInteger:= FParent.ID;
end;
end;
{Prepare and execute SQL command:}
SQLDataset.ExecSQL(False);
SQLDataset.Close;
When the condition FParent=nil applies, I was expecting the above code to
cause a NULL value to be uploaded for parameter 'ParentProjectIndex' - but
an error seems to be generated when this condition occurs. Can anyone
suggest any reasons for this?
3. If a sub-query is used to assign an auto-incremented value to a primary
key field when a new record is inserted in the database, is there a way of
getting the insertion command to return the field generated on the server?
Consider the following example:
SQLDataset.CommandText:= 'INSERT INTO Projects (ProjectIndex,'
+ 'DateTimeModified, Name, ParentProjectIndex)'
+ ' values ((select max(ProjectIndex) from Projects)+1,'
+ ' current_timestamp, :Name, :ParentProjectIndex)';
The sub-query assigns the required auto-incremented value to field
ProjectIndex on the server, but how can the client get this value returned
to it?
4. If a SQL command contains an IN predicate, can the IN item list be
uploaded in a parameter?
5. If the answer to 4 is that it's not possible, then to achieve the same
effect using a query parameter one might envisage doing something along the
following lines:
SQLDataset.CommandText:= 'Select * from Projects where ProjectIndex=
:ProjectIndex;
for i:= 0 to High(RecordArray) do
begin
RecordI:= RecordArray[i];
SQLDataset.Close;
SQLDataset.Params.ParamByName('ProjectIndex').AsInteger:=
RecordI.FIndex;
SQLDataset.Open;
if not SQLDataset.EOF then
RecordI.ReadFromSQLDataset(SQLDataset);
end;
end;
Would this work? Is there a more efficient way of achieving the same effect?
Should the TSQLDataset.Prepared parameter be set to True before the loop
starts?
Thanks in advance for any tips.
EM
Can anyone help with the following questions about TSQLDataset?
1. When executing a SQL 'SELECT' command, is each row downloaded separately
when SQLDataset.Open or SQLDataset.Next is called, or are all the rows
downloaded into a temporary variable when SQLDataset.Open is called, and
SQLDataset.Next just moves the cursor to the next row in the temporary
variable? For example, the purpose of the following code is to download all
the rows from a table into a custom data structure:
SQLDataset.CommandText:= 'SELECT * FROM ' + FTableName;
SQLDataset.Open;
SQLDataset.First;
while not SQLDataset.Eof do
begin
RecordI:= FBaseRecordClass.Create(Self);
RecordI.ReadFromSQLDataset(SQLDataset);
AddNewRecord(RecordI, Done);
SQLDataset.Next;
end;
If the table contains say 100 records, will there be 100 downloads, or just
one download?
2.Can NULL values be uploaded in parameters in SQL INSERT or UPDATE
statements? I tried the following code:
{Assign SQL command:}
SQLDataset.CommandText:= 'UPDATE Projects SET DateTimeModified=
:DatetimeModified '
+ ', Name= :Name, ParentProjectIndex= :ParentProjectIndex'
+ ' WHERE ProjectIndex= :ProjectID';
{Set input parameters:}
with SQLDataset.Params do
begin
{.}ParamByName('ProjectID').AsInteger:= FID;
{.}ParamByName('DatetimeModified').AsSQLTimestamp:=
FDatetimeModified;
{.}ParamByName('Name').AsString:= FName;
with {.}ParamByName('ParentProjectIndex') do
begin
if FParent= nil then
begin
{.}Clear; {Set parameter to Null}
{.}Bound:= True;
end
else
{.}AsInteger:= FParent.ID;
end;
end;
{Prepare and execute SQL command:}
SQLDataset.ExecSQL(False);
SQLDataset.Close;
When the condition FParent=nil applies, I was expecting the above code to
cause a NULL value to be uploaded for parameter 'ParentProjectIndex' - but
an error seems to be generated when this condition occurs. Can anyone
suggest any reasons for this?
3. If a sub-query is used to assign an auto-incremented value to a primary
key field when a new record is inserted in the database, is there a way of
getting the insertion command to return the field generated on the server?
Consider the following example:
SQLDataset.CommandText:= 'INSERT INTO Projects (ProjectIndex,'
+ 'DateTimeModified, Name, ParentProjectIndex)'
+ ' values ((select max(ProjectIndex) from Projects)+1,'
+ ' current_timestamp, :Name, :ParentProjectIndex)';
The sub-query assigns the required auto-incremented value to field
ProjectIndex on the server, but how can the client get this value returned
to it?
4. If a SQL command contains an IN predicate, can the IN item list be
uploaded in a parameter?
5. If the answer to 4 is that it's not possible, then to achieve the same
effect using a query parameter one might envisage doing something along the
following lines:
SQLDataset.CommandText:= 'Select * from Projects where ProjectIndex=
:ProjectIndex;
for i:= 0 to High(RecordArray) do
begin
RecordI:= RecordArray[i];
SQLDataset.Close;
SQLDataset.Params.ParamByName('ProjectIndex').AsInteger:=
RecordI.FIndex;
SQLDataset.Open;
if not SQLDataset.EOF then
RecordI.ReadFromSQLDataset(SQLDataset);
end;
end;
Would this work? Is there a more efficient way of achieving the same effect?
Should the TSQLDataset.Prepared parameter be set to True before the loop
starts?
Thanks in advance for any tips.
EM