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).