Die Fehlermeldung kommt, wenn man eine direkte Tabellenverlinkung FROM TABELLE A, TABELLE B mit einem LEFT OUTER JOIN kombiniert und in allen Tabellen nicht unbedingt Daten vorhanden sind. Generell sollte man so ein Konstrukt nie erstellen - aber die Version ist ja auch schon über drei Jahre alt. Aber das nur am Rande.
Ich habe mir das mal bei uns angesehen:
Code: Alles auswählen
CREATE OR ALTER PROCEDURE P_BARTPH_BSAL_INTERCOMP (
  BMAND_ID INTEGER,
  BARTPH_ID INTEGER)
AS
DECLARE VARIABLE BSA_ID TYPE OF COLUMN BSA.ID;
DECLARE VARIABLE BSA_ID_MAND INTEGER;
DECLARE VARIABLE BKUNDE_ID TYPE OF COLUMN BKUNDE.ID;
DECLARE VARIABLE BMAND_ID_KUNDE TYPE OF COLUMN BMAND.BKUNDE_ID;
DECLARE VARIABLE BLIEF_ID TYPE OF COLUMN BMAND.BLIEF_ID;
DECLARE VARIABLE BSAL_ID TYPE OF COLUMN BSAL.ID;
DECLARE VARIABLE BSALP_ID TYPE OF COLUMN BSALP.ID;
DECLARE VARIABLE HK1 TYPE OF COLUMN BSA.HK1;
DECLARE VARIABLE VK_WAEHRUNG TYPE OF COLUMN BARTPH.VK_WAEHRUNG;
DECLARE VARIABLE ZUSCHLAG TYPE OF COLUMN BARTPH.ZUSCHLAG;
DECLARE VARIABLE MENGE TYPE OF COLUMN BARTPH.MENGE;
DECLARE VARIABLE STAFFELNR TYPE OF COLUMN BARTPH.STAFFELNR;
DECLARE VARIABLE PRBASIS TYPE OF COLUMN BARTPH.PRBASIS;
BEGIN
  /* LETZTER STAND 15.11.2010 09:56:13 RW */
  /* ERSTER STAND 09.12.2007 19:09:47 HB */
  /* Protokollieren, dass Aktion hier durchgelaufen ist */
  IF (GEN_ID(GEN_ENTWICKLUNG,0) = 0) THEN
    INSERT INTO A_WASMACHTIB (PROGRAMMTEIL) VALUES ('P_BARTPH_BSAL_INTERCOMP');
  -- Lieferantennummer des Mandanten suchen
  BLIEF_ID = NULL;
  SELECT A.BLIEF_ID
  FROM BMAND A
  WHERE A.ID = :BMAND_ID
  INTO :BLIEF_ID;
  IF (BLIEF_ID IS NULL) THEN EXIT;
  -- Kundennummer suchen
  SELECT A.BSA_ID_LINKKEY, A.VK_WAEHRUNG, A.MENGE, A.PRBASIS,
         A.ZUSCHLAG, A.STAFFELNR, A.BKUNDE_ID,
         B.HK1
  FROM BARTPH A
  LEFT OUTER JOIN BSA B ON A.BSA_ID_LINKKEY = B.ID
  WHERE A.ID = :BARTPH_ID
  INTO :BSA_ID, :VK_WAEHRUNG, :MENGE, :PRBASIS,
       :ZUSCHLAG, :STAFFELNR, :BKUNDE_ID,
       :HK1;
  -- Ist der Kunde auch ein Mandant?
  BMAND_ID_KUNDE = NULL;
  SELECT A.ID
  FROM BMAND A
  WHERE A.BKUNDE_ID = :BKUNDE_ID
  INTO :BMAND_ID_KUNDE;
  IF (BMAND_ID_KUNDE IS NULL) THEN EXIT;
  -- Mandantenspezifische Artikelnummer suchen
  EXECUTE PROCEDURE P_BMAND_BSASPEZ(:BMAND_ID, :BSA_ID)
  RETURNING_VALUES (:BSA_ID_MAND);
  -- Bestehende Zuordnungen anpassen
  BSAL_ID = NULL;
  FOR SELECT A.ID
  FROM BSAL A
  WHERE A.BLIEF_ID_LIEFNR = :BLIEF_ID AND
        A.BSA_ID_LINKKEY = :BSA_ID_MAND
  INTO :BSAL_ID
  DO
  BEGIN
    IF (STAFFELNR = 1) THEN
      -- Kein Staffelpreis
      UPDATE BSAL A
      SET A.LISTPREIS = :HK1,
          A.GPRABATT = 0 - :ZUSCHLAG,
          A.PRBASIS = :PRBASIS,
          A.GPNRABATT = :VK_WAEHRUNG
      WHERE A.ID = :BSAL_ID;
    ELSE
    BEGIN
      -- Staffelpreis
      -- Gibt es die Zuordnung schon, wenn ja, dann anpassen, sonst neu anlegen
      BSALP_ID = NULL;
      SELECT A.ID
      FROM BSALP A
      WHERE A.BSAL_ID_LINKKEY = :BSAL_ID AND
            F_LRTRIM(A.MASKENKEY) = :STAFFELNR
      INTO :BSALP_ID;
      IF (BSALP_ID IS NOT NULL) THEN
        UPDATE BSALP
        SET ABMENGE = :MENGE,
            EPREIS = :VK_WAEHRUNG,
            GPRABATT = 0 - :ZUSCHLAG
        WHERE ID = :BSALP_ID;
      ELSE
        INSERT INTO BSALP(
          ABMENGE,
          EKDATUM,
          GPRABATT,
          BSAL_ID_LINKKEY,
          PRBASIS,
          EPREIS)
        VALUES (
          :MENGE,
          CURRENT_DATE,
          0 - :ZUSCHLAG,
          :BSAL_ID,
          :PRBASIS,
          :VK_WAEHRUNG);
    END
  END
END
Die größte Änderung ist, dass der Block zum Anlegen der BSAL verschwunden ist (und damit auch das ganze Problem 

).
Der Grund hierfür ist, dass Preise zwar aktualisiert werden, eine Zuordnung allerdings nicht zwingend erfolgt bzw. diese manuell erfolgen sollte. Eine Verbindung kann es ja auch geben, wenn nicht spezifisch der Kunde hinterlegt ist, sondern nur die Preisliste. Und wenn es gar nichts gibt, müsste dann die Basispreisliste verwendet werden. Das wäre sehr uneinheitlich, so dass wir generell das Erzeugen von Lieferantenverbindungen herausgenommen haben (auf Kundenwunsch).