【问题标题】:How to insert blank data in tclientdataset?如何在 tclientdataset 中插入空白数据?
【发布时间】:2020-02-25 08:43:22
【问题描述】:

这是一个简单的数据库。

CREATE TABLE A(FIELD1 INT PRIMARY KEY, FIELD2 VARCHAR(10));  
INSERT INTO A (FIELD1, FIELD2) VALUES (1, 'A');

tbl1 已打开,它包含表 A 中的数据。我想插入空白数据,6 条带空白数据的记录,Tclientdataset 中的空数据用于制作标签。在此示例中,我收到“密钥违规”错误。

  procedure TForm1.btn1Click(Sender: TObject);

var
  i:Integer;
  cdsEti:TClientDataSet;
  dtstprvEti:TDataSetProvider;
  iNroEspaciosBlanco: Integer;
begin
  iNroEspaciosBlanco := 6;
  dtstprvEti := TDataSetProvider.Create(nil);
  cdsEti:= TClientDataSet.Create(nil);
  dtstprvEti.DataSet := tbl1;

  cdsEti.Data := dtstprvEti.Data;
  dtstprvEti.Constraints := False;
  cdsEti.ReadOnly := False;
  for i := 0 to (cdsEti.Fieldcount-1) do
  begin
    cdsEti.fields[i].ReadOnly := false;
    cdsEti.Fields[i].Required := false;
    cdsEti.FieldDefs[i].Attributes := [];
  end;
  cdsEti.Active := True;
  cdsEti.First;
  for i := 1 to iNroEspaciosBlanco do
  begin
    cdsEti.Insert;
    cdsEti.Post;
  end;
  FreeAndNil(cdsEti);
  FreeAndNil(dtstprvEti);
end;

dfm 包含这个。只需一个按钮、一个连接和一个表格。

object Form1: TForm1
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object btn1: TButton
    Caption = 'btn1'
    TabOrder = 0
    OnClick = btn1Click
  end
  object con1: TADOConnection
    Connected = True
    Provider = 'SQLOLEDB.1'
  end
  object tbl1: TADOTable
    Connection = con1
    TableName = 'A'
  end
end

【问题讨论】:

  • cdsEtiquetas 上是否定义了任何索引,如果有,它们是什么? cdsEtiquet 是“独立”CDS 还是有任何连接,例如到 DataSetProvider 还是处于主从关系?
  • 不,这个clientdataset的使用只针对这个porpouse。不是主细节或与任何表格的任何连接。我看过索引,有一个名为 DEFAULT_ORDER 的 CODIGO_ARTICULO 索引,它继承自数据集,但不是 ixprimary 或唯一的。在以前的测试中,我检查过使用这个 cdsEtiquetas.IndexDefs.Clear 但没有运行。
  • datasetprovider 中的约束设置为 false,
  • 我认为你的主键不能为空。
  • 你已经定义了一个主键,这意味着它不能为空。不需要为标签插入空白行。在您的演示文稿(用户界面或报告)中执行此操作,而不是在表格本身中。该表应仅包含符合其约束的实际数据。

标签: delphi tclientdataset


【解决方案1】:

我认为您的问题一定是由您没有的项目细节引起的 在您的 q 中提到,因为我无法在最小的测试项目中重现您的问题。

1 我使用此定义在 MS Sql Server 2014 上创建了一个测试表 ClientCodes

CREATE TABLE [dbo].[clientcodes](
  [ClientCode] [int] NOT NULL,
  [Name] [varchar](40) NULL,
PRIMARY KEY CLUSTERED
(
  [ClientCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

然后我插入了 3 个测试行

1  One
2  Two
3  Three

2 然后我创建了一个新的 Delphi 项目,其中包含 一个到 Sql Server 的 AdoConnection,一个执行“从 ClientCodes 中选择 *”的 AdoQuery,一个连接到 AdoQuery 的 DataSetProvider 和一个连接到该 AdoQuery 的 unqryCliPrint CDS,以及一个名为 cdsEtiquetas 的第二个 CDS。

注意:组件的所有属性都保留为默认值,除了 如上所述连接组件所必需的。

项目中唯一的代码是这样的:

procedure TForm1.Button1Click(Sender: TObject);
begin
  unqryCliPrint.Open;
  cdsEtiquetas.Data := unqryCliPrint.Data;

  cdsEtiquetas.InsertRecord([0, 'zero']);
  cdsEtiquetas.InsertRecord([0, 'zero']);
  cdsEtiquetas.InsertRecord([0, 'zero']);
end;

如您所见,这会插入同一行的 3 个副本。代码正确执行,无需 引发任何类型的异常或错误。

我建议您使用您的服务器创建一个类似的项目。如果你得到同样的结果, 您将需要尝试确定在您的实际项目中是什么导致了错误。

顺便说一句,您的代码中似乎有错误:

  cdsEtiquetas.DisableControls;
  cdsEtiquetas.DisableConstraints;

我看不到您撤消这些步骤的任何地方。

更新从您添加的 DFM 中,我看到您的 cdsEtiquetas 连接到其他东西,即 dtstprvEtiquetas,尽管您在评论中说了什么。并且这个 DSP 连接回 unqryCliPrint!所以我想这就是你的错误的来源。如果 cdsEtiquetas 不需要 DSP,并且您没有说明它需要的任何原因,只需清除其 ProviderName 属性即可。

【讨论】:

  • 问题是没有插入冗余数据。当我插入空白数据时。
  • 考虑到我花时间研究这个,我不得不说我没有找到“当我插入空白数据时”的评论。完全有帮助,尤其是当您的示例尝试插入 ClientCode 设置为零的行时,这正是我的代码所做的。无论如何,我只包括了对 InsertRecord 的第二次和第三次调用,以表明在插入重复行时不会发生错误 - 我对 InsertRecord 的第一次调用表明与您的示例相反,插入第一行时不会发生错误。
  • 顺便说一句,如果我将 Null 指定为 ClientCode 而不是零,我的代码仍然没有错误。就像我说的,清除你的cdsEtiquetasProviderName 属性,看看你是否仍然得到你报告的错误。
  • "我无法重现你的代码" 你是什么意思?您是否按照我所说的关于 ProviderName 的方式完成了?
  • 数据最少的代码,一个简单的表格(只有两个字段)和一个表单中的按钮。
【解决方案2】:

当我在 Firebird 中创建一个表时,我会自动为索引设置一个“非空”——它是该表的 DDL:

CREATE TABLE A (
    FIELD1  INTEGER NOT NULL,
    FIELD2  VARCHAR(10)
);
ALTER TABLE A ADD PRIMARY KEY (FIELD1);

所以 - 索引值不能为空,也必须是唯一的!

网上有一条信息:

“主键是表中唯一标识主键的字段 数据库表中的每一行/记录。主键必须包含 独特的价值观。主键列不能有 NULL 值。一张桌子 只能有一个主键,可以由一个或多个组成 字段”。

【讨论】:

  • 我正在尝试将表的数据导入 Tclientdataset 并停用约束(主键是约束)以对其进行操作并插入空白数据。
猜你喜欢
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多