【问题标题】:Howto fetch IDENTITY columns with ADO in Delphi如何在 Delphi 中使用 ADO 获取 IDENTITY 列
【发布时间】:2013-12-20 10:44:32
【问题描述】:

我无法在 Delphi XE2 中使用 ADO 获取 IDENTITY 列

问题 ADO 字段属性不返回/不包含任何 IDENTITY 列。 连接中是否有可以获取 IDENTITY 列的属性或其他东西,或者这是一个已知的错误?

场景 我有一个存储过程(在 SYBASE ASE 中),它获取 1 行和 4 列。 其中一列是 IDENTITY 列。

在此示例中:ADOQuery.Fields.Count 将返回 3 而不是 4。缺少 IDENTITY 列。

例如:

procedure TForm1.FormCreate(Sender: TObject);
var
test: string;
Password: String;
UserName: string;
ServerName : string;
NoRec: integer;
MyValue: integer;

begin

Password:='xxxx';
UserName:='yyyy';
ServerName := 'zzzzz';

ADOConnection := TADOConnection.Create(Application);

with ADOConnection do
begin
  CommandTimeout := 0;
  IsolationLevel := ilSerializable;
  Attributes := [xaAbortRetaining];
  KeepConnection := True;
  LoginPrompt := False;

   ConnectionString := 'Provider=ASEOLEDB.1;Password=' + Password +
        ';Persist Security Info=True' + ';User ID=' +
        UserName + ';Data Source=' + ServerName; 
end;

if not Assigned(ADOQuery) then
begin
  ADOQuery := TADOQuery.Create(Application);
  with ADOQuery do
  begin
    CommandTimeout := 0;
    DisableControls;

    CacheSize := 500;
    Connection := ADOConnection;
    CursorType := ctOpenForwardOnly;
  end;
end;

ADOConnection.Open();
ADOQuery.SQL.Text:= 'sp_echo';
ADOQuery.Open;

NoRec:=ADOQuery.Fields.Count;  //This will return: 3, the IDENTITY col is missing

//Trying to fetch the column this way, will fail (the field doesen´t exist):
//MyValue:=ADOQUery.FieldByName('col_1').AsInteger
end;

这里是这个例子的脚本、表格、存储过程

create table tbl_echo
(
  col_1  numeric(10,0) identity,
  col_2  varchar(255),  
  col_3  int,
  col_4  int
)

insert into tbl_echo (col_2, col_3, col_4) select 'testing', 100, 200

create proc sp_echo
as
select top 1 * from tbl_echo

【问题讨论】:

  • 我正在使用获取 1 单行的存储过程。
  • @Jens,这是一个 SYBASE ASE 数据库。
  • 你试过使用TADOStoredProc吗?
  • 您的代码无效,请将其编辑为SSCCE
  • 好吧,现在更有意义了,为什么还要创建一个额外的TADODataSet?尤其是分配给ADODataSet.RecordSet 对我来说似乎很不寻常。

标签: delphi delphi-xe2 ado sap-ase recordset


【解决方案1】:

你有两种不同的方式来获得你想要的东西:

  1. 您在 SP 中声明一个输出参数,并在插入后将 @@IDENTITY 分配给此参数。通过使用TADOStoredProc 组件而不是TADOQuery 组件来执行这样的SP。在 SP 完成后,当控件返回到您的 Delphi 代码时,您只需读取此类参数的值。

  2. 您只需选择@@IDENTITY,将为您提供一个包含生成值的单行和单列的结果集。在这种情况下,您可以使用 TADOQuery,但在您的 Delphi 代码中,您使用 Open(而不是 ExecSQL)来检索这样的结果集,然后从唯一的字段中读取值。

    李>

【讨论】:

  • @AlexSH,感谢您的回答。但我认为这不是我的情况的解决方案。我有一个庞大的代码库和几个 1000 个程序,所以审查和重写所有这些不是一个选择。我们当前的(和非常旧的 sybase 驱动程序)设法在所有查询中支持 IDENTITY 字段,我发现 ADO 不支持这一点很奇怪。我将与其他一些“提供者”进行一些实验,看看它们是否具有与此 ASEOLEDB.1 相同的行为
  • @carleson:我希望你能幸运,但我个人对此表示怀疑。我使用 OLE-DB 的经验告诉我,参数或列数据类型中没有 IDENTITY 类型。事实上,这似乎是不可能的,因为IDENTITY 不像数据集中的AutoInc,它是一个会话生成的值,它存在于数据服务器中,直到使用IDENTITY 插入下一行。如果没有存储过程代码的参与,就无法传递这样的值。
【解决方案2】:

好的,我尝试使用其他一些提供程序,结果相同。

解决此问题的一个简单方法是在我的过程/查询中将 IDENTITY 列转换为整数。通过这样做,它会像预期的那样工作。

create proc sp_echo
as
select top 1  cast(col_1 as int) as col_1, col_2, col_3, col_4 from tbl_echo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2022-06-26
    相关资源
    最近更新 更多