Autor Téma: Editace ADODataset  (Přečteno 232 krát)

Offline Petr Shejbal

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: XE7 Profesional
Editace ADODataset
« kdy: 05-09-2017, 11:39:54 »
Dobrý den přeji,

Příběh.
  • Potřebuji nahradit hodnoty recordsetu (pod oběktem
Kód: [Vybrat]
TADODataset). Tzn. nahradit texty některých buňěk.
Na počátku je objekt
Kód: [Vybrat]
TADOSQLQuery, který po spuštění vrátí "kolekci" rekordsetů.
První dataset naplním pomocí
Kód: [Vybrat]
ADODataset1.Recordset := ADOSQLQuery.Recordset;
Zbylé datasety naplním metodou
Kód: [Vybrat]
ADODatasetN.Recordset := ADOSQLQuery.Nextrecordset;
    Dále mám proceduru pro nahrazení textu. (pouštím ji pro každý dataset.)[/li]

Kód: [Vybrat]
procedure transformFormTexts(dataset:TADODataSet;);
begin
   dataset.Open;
   dataset.Active;
   dataset.First;
   while not dataset.Eof do
    begin
    dataset.Connection := nil;
    dataset.Edit;
      for i := 0 to dataset.Fields.Count - 1 do
        begin         
              if podmínka  then
              begin               
                     dataset.Fields[i].ReadOnly :=false;
                     dataset.Fields[i].Value := string(data.ChildNodes[ii].Text);                           
              end;
           
        end;
        dataset.next;
    end;
end;

Poznámka.
Nepotřebuji držet živé spojení s databází, proto dataset.Connection := nil;
Druhý důvod je chyba "insufficient key column information for updating or refreshing" při metodě post.

Výsledek.
Data se nahradí pouze v prvním datasetu (přiřazen pomocí ADOSQLQuery.Recordset; [nevím jestli to má souvislost, ale jiný rozdíl nevidím])
Při pokusu o nahrazení ostatních datasetech dojde k chybě "Field 'Jméno fieldu' cannot be modified".

Předem děkuji za Váš čas.

Offline Delfin

  • Plnoletý
  • ***
  • Příspěvků: 231
  • Karma: 9
    • Verze Delphi: 2009, Tokyo
Re:Editace ADODataset
« Odpověď #1 kdy: 06-09-2017, 02:17:00 »
Nemuzu zreprodukovat. Dataset se po zruseni prirazeni Connection chova jako storage, coz ma pokud to spravne chapu byt ucelem.

Delphi 2009
ADOQuery1 - TADOQuery (neznam nic jako TADOSQLQuery)
ADOConnection1 - TADOConnection objekt pripojujici se pres nativniho klienta k LocalDb instanci Microsoft SQL Server Express 2014 v12.0.2000.8, connection string:

Citace
Provider=SQLNCLI11.1;Integrated Security=SSPI;Persist Security Info=False;User ID="";Initial Catalog=MyDatabase;Data Source=(LocalDb)\MyLocalDB;Initial File Name="";Server SPN=""

Skript pro vytvoreni tabulek (ani jedna z nich nema umyslne kvuli testu zminene chyby "insufficient key column information" primarni klic):

Kód: MySQL [Vybrat]
  1. CREATE TABLE [dbo].[MyTable1](
  2.         [ID] [int] NOT NULL,
  3.         [MyField] [nvarchar](50) NOT NULL
  4. );
  5.  
  6. CREATE TABLE [dbo].[MyTable2](
  7.         [MyField] [nvarchar](50) NOT NULL
  8. );
  9.  
  10. GO
  11.  
  12. INSERT INTO [dbo].[MyTable1] ([ID], [MyField]) VALUES (0, 'MyValue1');
  13. INSERT INTO [dbo].[MyTable2] ([MyField]) VALUES ('MyValue2');

A osklivy kod pro test:

Kód: Delphi [Vybrat]
  1. var
  2.   Affected: Integer;
  3.   DataSet1: TADODataSet;
  4.   DataSet2: TADODataSet;
  5. begin
  6.   ADOQuery1.SQL.Text := 'SELECT MyField FROM MyTable1; SELECT MyField FROM MyTable2;';
  7.   ADOQuery1.Open;
  8.  
  9.   DataSet1 := TADODataSet.Create(nil);
  10.   try
  11.     DataSet2 := TADODataSet.Create(nil);
  12.     try
  13.       DataSet1.Recordset := ADOQuery1.Recordset;
  14.       DataSet1.Open;
  15.       DataSet2.Recordset := ADOQuery1.NextRecordset(Affected);
  16.       DataSet2.Open;
  17.  
  18.       ADOQuery1.Connection := nil;
  19.       DataSet1.Connection := nil;
  20.       DataSet2.Connection := nil;
  21.  
  22.       Memo1.Lines.Add(DataSet1.Fields[0].AsString);
  23.       Memo1.Lines.Add(DataSet2.Fields[0].AsString);
  24.  
  25.       DataSet1.Edit;
  26.       DataSet1.Fields[0].AsString := 'New value 1';
  27.       DataSet1.Post;
  28.  
  29.       DataSet2.Edit;
  30.       DataSet2.Fields[0].AsString := 'New value 2';
  31.       DataSet2.Post;
  32.  
  33.       Memo1.Lines.Add(DataSet1.Fields[0].AsString);
  34.       Memo1.Lines.Add(DataSet2.Fields[0].AsString);
  35.     finally
  36.       DataSet2.Free;
  37.     end;
  38.   finally
  39.     DataSet1.Free;
  40.   end;
  41.  
  42.   ADOQuery1.Connection := ADOConnection1;
  43.   ADOQuery1.SQL.Text := 'SELECT A.MyField, B.MyField FROM MyTable1 A, MyTable2 B';
  44.   ADOQuery1.Open;
  45.  
  46.   Memo1.Lines.Add(ADOQuery1.Fields[0].AsString);
  47.   Memo1.Lines.Add(ADOQuery1.Fields[1].AsString);
  48. end;

Vystup memo (bez modifikace tabulky databaze):

Citace
MyValue1
MyValue2
New value 1
New value 2
MyValue1
MyValue2
« Poslední změna: 06-09-2017, 02:19:02 od Delfin »
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline Petr Shejbal

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: XE7 Profesional
Re:Editace ADODataset
« Odpověď #2 kdy: 06-09-2017, 14:44:37 »
Předem Vám chci poděkovat za pohotovou reakci spolu s příkladem.

1. Máte pravdu, že je účel aby dataset sloužil pouze jako storage.
2. TADOSQLQuery byl samozdřejmě překlep : ) Měl jsem, jak jste správně odhadl, na mysli TADOQuery.

Příklad se mi podařilo úspěšně zdeprodukovat a mé bádání to posunulo o něco dále.
Program kolabuje když chce modifikovat sloupce, které se byly ve stored procedure přidány jako alias.
'<%&LModifikoval%>' as LModifikoval
Ostatní sloupce se již přepisují podle potřeby.

Offline Delfin

  • Plnoletý
  • ***
  • Příspěvků: 231
  • Karma: 9
    • Verze Delphi: 2009, Tokyo
Re:Editace ADODataset
« Odpověď #3 kdy: 06-09-2017, 15:43:58 »
Příklad se mi podařilo úspěšně zdeprodukovat a mé bádání to posunulo o něco dále.
Program kolabuje když chce modifikovat sloupce, které se byly ve stored procedure přidány jako alias.
'<%&LModifikoval%>' as LModifikoval
Ostatní sloupce se již přepisují podle potřeby.

Porad nic. I pri vraceni multiple resulsetu pouzivajicich aliasy sloupcu z procedury se mi vse chova jak ma. Jeste dodam ze jsem na Windows 7 Professional.

Jde o tohle? Pokud ne, prosim o upresneni a podobnou, nejjednodussi spustitelnou ukazku k reprodukci.

Kód: MySQL [Vybrat]
  1. CREATE PROCEDURE [dbo].[MyProc]
  2.    -- SET NOCOUNT ON added to prevent extra result sets from
  3.    -- interfering with SELECT statements.
  4.    SET NOCOUNT ON;
  5.  
  6.    SELECT MyField AS MyFieldAlias FROM MyTable1;
  7.    SELECT MyField AS MyFieldAlias FROM MyTable2;

A kod ktery jsem postnul predtim, jen upraveny v SQL prikazu:

Kód: Delphi [Vybrat]
  1.   ...
  2.   ADOQuery1.SQL.Text := 'EXECUTE MyProc';
  3.   ADOQuery1.Open;
  4.   ...
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline Petr Shejbal

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: XE7 Profesional
Re:Editace ADODataset
« Odpověď #4 kdy: 07-09-2017, 09:37:15 »
V příloze přikládám zip funkčního příkladu spolu se scriptem.

Offline Delfin

  • Plnoletý
  • ***
  • Příspěvků: 231
  • Karma: 9
    • Verze Delphi: 2009, Tokyo
Re:Editace ADODataset
« Odpověď #5 kdy: 07-09-2017, 22:01:21 »
Aha, jde o pole s konstantni hodnotou. To jde nasimulovat i takto:

Kód: Delphi [Vybrat]
  1. var
  2.   DataSet: TADODataSet;
  3. begin
  4.   ADOQuery1.SQL.Text := 'SELECT ''ConstValue'' AS MyConstField FROM MyTable1';
  5.   ADOQuery1.Open;
  6.  
  7.   DataSet := TADODataSet.Create(nil);
  8.   try
  9.     DataSet.Recordset := ADOQuery1.Recordset;
  10.     DataSet.Open;
  11.  
  12.     ADOQuery1.Connection := nil;
  13.     DataSet.Connection := nil;
  14.  
  15.     DataSet.Edit;
  16.     DataSet.Fields[0].ReadOnly := False;
  17.     DataSet.Fields[0].AsString := 'New value';
  18.     DataSet.Post;
  19.  
  20.     Assert(DataSet.Fields[0].AsString = 'New value');
  21.   finally
  22.     DataSet.Free;
  23.   end;
  24. end;

Nedojde k zadne editaci, nehlede na to zda je dataset vnoreny. Je to proto, ze tomu sloupci ADO recordsetu chybi atributy adFldUpdatable a adFldUnknownUpdatable. Viz. implementaci metody TCustomADODataSet.InternalPost (nedojde k predani hodnoty prave kvuli absenci zminenych atributu).
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: