I have a Delphi project which uses the ADO-Components, currently SQL Server 2017.
I noticed that Microsoft has 3 possible providers , and Microsoft recommends using "Generation 3" for new projects.
SQLOLEDB (Generation 1) works
SQLNCLI11 (Generation 2) does NOT work
MSOLEDBSQL (Generation 3) does NOT work
To test the "Generation 3", I changed the provider in the connection string from SQLOLEDB to MSOLEDBSQL.
However, I noticed that this causes a problem if a column is added using a TAdoCommand inside a transaction, and afterwards, the Timeout is set. The error happens when the timeout is set after the execution.
Here is an example that reproduces the problem:
uses
ADODB;
procedure TForm2.Button1Click(Sender: TObject);
const
// SQLOLEDB (Generation 1) works
// SQLNCLI11 (Generation 2) does NOT work
// MSOLEDBSQL (Generation 3) does NOT work
SqlServerProvider= 'MSOLEDBSQL';
var
mConnection: TADoConnection;
command: TadoCommand;
begin
mConnection := TAdoConnection.Create(nil);
try
mConnection.ConnectionString := 'Provider='+SqlServerProvider+';Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=CORAMASTER_1;Data Source=SHS\HS2017,49010';
mConnection.KeepConnection := true;
mConnection.LoginPrompt := false;
mConnection.Connected := true;
mConnection.BeginTrans;
command := TADOCommand.Create(nil);
try
command.Connection := mConnection;
command.ParamCheck := false;
command.CommandText := 'alter table TESTTABLE add TESTCOLUMN int;';
command.CommandTimeout := 100;
command.Execute;
// If I set "CommandTimeout" here, I get the following error:
// Spaltennamen müssen in jeder Tabelle eindeutig sein. Der Spaltenname "..." wurde in der ...-Tabelle mehrmals angegeben.
// Translated: Column names must be unique in each table. The column name "..." appears multiple times.
// The error happens with provider MSOLEDBSQL (Generation 3) and SQLNCLI11 (Generation 2), but SQLOLEDB (Generation 1) works
command.CommandTimeout := 50; // ERROR!
finally
FreeAndNil(command); // Note: In the real project, I am keeping the command object. This is just for the example
end;
mConnection.RollbackTrans;
finally
FreeAndNil(mConnection);
end;
end;
What am I doing wrong? Is this an error in the ADO components?
Edit: Here is a trace log of the SQL server using the Microsoft SQL Server Profiler:
When I perform the second "SetTimeout" command, the SQL server performs the command exec [sys].sp_describe_first_result_set N'alter table TESTTABLE add TESTCOLUMN int;',NULL,1 which obviously causes the error. I have no idea why sp_describe_first_result_set is called and how to prevent it...



mConnection.Connected := true;actually opens the connection. And TRY without CATCH makes no sense. - SMortryconstructs,try ... exceptfor exception-handling andtry ...finallyfor resource protection. - MartynA