Как вставить пустые данные в tclientdataset? - PullRequest
0 голосов
/ 25 февраля 2020

Это простая база данных.

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

tbl1 открыт и содержит данные в таблице A. Я хочу вставить пустые данные, 6 записей с пустыми данными, нулевые данные в Tclientdataset для меток make. В этом примере я получаю сообщение об ошибке «Нарушение ключа».

  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

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Когда я создаю таблицу в Firebird, у меня автоматически появляется «not null» для индекса - это DDL для этой таблицы:

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

Таким образом - значение индекса не может быть нулевым и также должно быть UNIQUE!

Из Интернета есть информация:

"Первичный ключ - это поле в таблице, которое уникальным образом идентифицирует все строки / записи в таблице базы данных. Первичные ключи должен содержать уникальные значения. Столбец первичного ключа не может иметь значения NULL. В таблице может быть только один первичный ключ, который может состоять из одного или нескольких полей ".

0 голосов
/ 25 февраля 2020

Я думаю, что ваша проблема должна быть вызвана деталями вашего проекта, которые вы не упомянули в q, потому что я не могу воспроизвести вашу проблему в минимальном тестовом проекте.

1 Я создал тестовую таблицу, ClientCodes на MS Sql Server 2014 с таким определением

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, содержащий AdoConnection к Sql серверу, AdoQuery, который выполняет 'select * from ClientCodes', DataSetProvider, подключенный к AdoQuery, и CDS unqryCliPrint, подключенный к этому, и второй CDS с именем cdsEtiquetas.

Примечание: все свойства компонентов остались по умолчанию, кроме тех, которые необходимы для подключения компонентов, как описано выше.

Единственный код в проекте:

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.

...