AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein PL/SQL: Kompilierungsfehler bei FORALL mit Insert
Thema durchsuchen
Ansicht
Themen-Optionen

PL/SQL: Kompilierungsfehler bei FORALL mit Insert

Ein Thema von sirius · begonnen am 29. Apr 2008 · letzter Beitrag vom 29. Apr 2008
Antwort Antwort
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#1

PL/SQL: Kompilierungsfehler bei FORALL mit Insert

  Alt 29. Apr 2008, 20:06
Ich bin nach wie vor dabei mich in PL/SQL einzuarbeiten. (Oracle 9i)

Ich habe derzeit ein Package mit folgender Procedure
SQL-Code:
procedure setData(aData in ValueList, count_errors out Integer) is
i Number;
begin
  -- count_errors:=0;
  if MeasurementPointID<>0 then
    for i in aData.First .. aData.Last loop
      Insert Into DBT_DATEN(ID, ID_MESSORT, ZEIT, MESSWERT)
             values (SEQ_DATEN.NEXTVAL, MeasurementPointID, aData(i).ODATETIME , aData(i).OVALUE);
    end loop;
  end if;
end;
SEQ_Daten ist eine Sequenz. MeasurementPointID ist ein Integer aus dem Package-Body. Und aData ist ein "Table of ValueElement" wobei ValueElement ein Objekt ist mit den beiden Feldern, die in der Procedure zu sehen sind.
Der oben gezeigt Code funktioniert auch.

Nun würde ich gerne aus der For-Schleife eine FORALL-Schleife basteln:
SQL-Code:
procedure setData(aData in ValueList, count_errors out Integer) is
i Number;
begin
  -- count_errors:=0;
  if MeasurementPointID<>0 then
    forall i in aData.First .. aData.Last loop
      Insert Into DBT_DATEN(ID, ID_MESSORT, ZEIT, MESSWERT)
             values (SEQ_DATEN.NEXTVAL, MeasurementPointID, aData(i).ODATETIME , aData(i).OVALUE);
  end if;
end;
Das will aber nicht. Egal wo ich Doppelpunkte hinsetze. Ich habe auch schon die Sequenz und die anderen Werte durch Konstanten ersetzt. In SQLPlus bekomme ich nur, dass es nicht kompilierbar ist und im Enterprise Manager sagt er gar nichts und kompiliert halt nicht (wie bei allen Fehlern).

Ich danke jedem für einen Tipp.


Edit:
Da denkt man den kompletten Nachmittag drüber nach und kurz nachdem man es in die DP eingetragen hat, fällt einem die Lösung auf die Tastatur.
Also ich darf (zumindest in Version 9i) nicht Objekte (Bsp.: aData(i).oDateTime) verwenden sondern muss direkt auf Listen verweisen:
SQL-Code:
procedure setData(aDates in DateList, aValues in ValueList, count_errors out Integer) is
i Number;
begin
  count_errors:=0;
  if (MeasurementPointID<>0)and(ADates.count=aValues.Count) then
     FORALL i in aValues.first .. aValues.last SAVE EXCEPTIONS
       Insert Into DBT_DATEN(ID, ID_MESSORT, ZEIT, MESSWERT)
           values
               (SEQ_DATEN.NEXTVAL,
                MeasurementPointID, aDates(i), aValues(i));
  end if;

EXCEPTION
     WHEN OTHERS THEN
       count_errors := SQL%BULK_EXCEPTIONS.COUNT;
end;
DateList und ValueList sind jetzt aufgesplittet (Table of Date und Table of Float) und kein "Table of Object" mehr.
Falls noch jemand Kommentare hat, dann immer her damit, ansonsten hat sich der Punkt erstmal für mich erledigt
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#2

Re: PL/SQL: Kompilierungsfehler bei FORALL mit Insert

  Alt 29. Apr 2008, 21:27
Warum fängst du die Exception ab?
So weißt du doch gar nicht was schief lief.
Außerdem, da du jetzt DOA nutzt, würde ich dir Packages empfehlen.
DOA kann die automatisch so verpacken, dass du sie direkt in Delphi nutzen kannst, als wären sie Delphiklassen.
Aus Performancegründen, würde ich empfehlen, die Sequencewerte vorher in einem Rutsch zu holen, damit sämtliche Werte statisch sind oder aus gebundenen Bulk-listen kommen.
Delphi-Quellcode:
type TIDList is table of DBT_DATEN.ID%type;
type TDateList is table of DBT_DATEN.Zeit%type;
type TMessWertList is table of DBT_DATEN.MessWert%type;

procedure SetData(aData in TValueList) is
  
  allIDs TIDList := TIDList();
  allDates TDateList := TDateList();
  allValues TMessWertList := TMessWertList();
begin
  allIDs.Extend(aData.Count);
  allDates.Extend(aData.Count);
  allValues.Extend(aData.Count);

  for i in aData.First .. aData.Last loop
    SELECT Seq_Daten.NextVal
    INTO allIDs(i)
    FROM dual;

    allDates(i) := aData(i).ODATETIME;
    allValues(i) := aData(i).OVALUE;
  end loop;

  forall i in allIDs.First .. allIDs.Last
    INSERT INTO dbt_Daten(ID, ID_MESSORT, ZEIT, MESSWERT)
    VALUES (allIDS(i), MeasurementPointID, allDates(i) , allValues(i));
end;
btw, Enterprise manager stinkt! Schaue dir PL/SQL Developer an, oder die Oracle IDEs von CoreLab.

btw2: Oracle erlaubt es einen Array als Datenquelle zu nutzen.
Deine originale SProc könnte also so aussehen:

SQL-Code:
INSERT INTO DBT_DATEN(ID, ID_MESSORT, ZEIT, MESSWERT)
  SELECT SEQ_DATEN.NEXTVAL, MeasurementPointID, ODATETIME , OVALUE
  FROM table(aData);
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: PL/SQL: Kompilierungsfehler bei FORALL mit Insert

  Alt 29. Apr 2008, 21:57
Danke Robert.

Das mit dem Package und dem Package Wizard in Delphi hatte ich bereits rausgefunden.
Ich glaube ich werde die Werte in zwei Listen belassen. Da schadet ja nicht. Es ist von Delphiseite zumindest nicht Bedingung alles in ein Objekt zu schmeißen.
Das mit der Sequenz werde ich dankend übernehmen.
Das Array als Datenquelle brauch ich vielleicht nochmal.

Das mit der Exception finde ich besser so. Das war ja hier nur ein Test und ich sollte schon noch mehr Infos rausholen als nur die Anzahl. Aber wenn ich die Exception nicht abfange, dann schmeißt er mich bei der ersten Wertedopplung (es darf ja nicht zwei Messwerte zum gleichen Zeitpunkt geben) raus. Bisher (Implementation ohne SP) habe ich das auch einfach ignoriert (abgesehen von Meldungen), da es nur passiert wenn jemand zweimal dieselbe Messdatei einliest oder eben einmal unterbrochen wurde und wieder neu anfängt.

Das es was besseres gibt als den Enterprise Manager habe ich ich schon gedacht. Das werde ich auch mal angehen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz