Nicht sicher. Brauchen Sie Hilfe für diese beiden Teile.
----#1: Diese Abfrage braucht Zeit (Iterating)
SELECT
COUNT(*)
INTO v_id_count
FROM test.customer_contact
WHERE
contact_other_500 = i_id LIMIT 1;
#2:
: -- Oracle Code --
-- IF length(i_name) > '36' THEN
-- GOTO nextpos;
END IF;
Postgresql Code -> GOTO nextpos; substituted with lv_var.
IF length(i_name) > '36' and lv_var is null THEN
--GOTO nextpos;
lv_var:='36';
END IF;
CREATE OR REPLACE PROCEDURE theta.template_contact()
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
r CURSOR FOR
SELECT DISTINCT
TRIM(account_number),
TRIM(id),
TRIM(replace(replace(replace(TRIM(name),('\N'), NULL), '.', ''), '¿', '')),
TRIM(replace(phone, '\N', NULL)),
TRIM(replace(email, '\N', NULL)),
TRIM(replace(responsibility, '\N', NULL)),
TRIM(replace(fax, '\N', NULL))
FROM
theta.gannett_contact_stg;
i_account_number VARCHAR(50);
i_seq_num VARCHAR(50);
i_id VARCHAR(50);
i_name VARCHAR(50);
i_phone VARCHAR(50);
i_email VARCHAR(50);
i_responsibility VARCHAR(2000);
i_fax VARCHAR(50);
v_gecars_num VARCHAR(50);
v_gecars_count NUMERIC;
v_id_count NUMERIC;
v_contact_count NUMERIC;
v_max_seq NUMERIC;
err_num TEXT;
err_msg TEXT;
--con_exp EXCEPTION;
v_con_count NUMERIC;
lv_var text;
BEGIN
SELECT
COUNT(*)
INTO v_con_count
FROM
theta.gannett_contact_stg;
IF (v_con_count = 0) THEN
RAISE EXCEPTION USING errcode ='COEXP';
END IF;
OPEN r;
LOOP
FETCH r INTO
i_account_number,
i_id,
i_name,
i_phone,
i_email,
i_responsibility,
i_fax;
EXIT WHEN NOT FOUND;
SELECT
COUNT(*)
INTO v_gecars_count
FROM
test.customer
WHERE
cust_client_717 = i_account_number LIMIT 1;
IF ( v_gecars_count = 0 ) and lv_var is null THEN
--GOTO nextpos;
lv_var:='0';
ELSE
SELECT
cust_no_717
INTO v_gecars_num
FROM
test.customer
WHERE
cust_client_717 = i_account_number LIMIT 1;
END IF;
-- Original Code --
-- IF length(i_name) > '36' THEN
-- GOTO nextpos;
------------------
IF length(i_name) > '36' and lv_var is null THEN
--GOTO nextpos;
lv_var:='36';
END IF;
IF length(i_phone) > '25' and lv_var is null THEN
--GOTO nextpos;
lv_var:='25';
END IF;
IF length(i_fax) > '25' and lv_var is null THEN
-- GOTO nextpos;
lv_var:='25';
END IF;
IF length(i_email) > '60' and lv_var is null THEN
--GOTO nextpos;
lv_var:='60';
END IF;
IF length(i_responsibility) > '2000' and lv_var is null THEN
--GOTO nextpos;
lv_var:= '2000';
END IF;
---- This query taking time (It's iterating)
SELECT
COUNT(*)
INTO v_id_count
FROM test.customer_contact
WHERE
contact_other_500 = i_id LIMIT 1;
----
SELECT
COUNT(*)
INTO v_contact_count
FROM
test.customer_contact
WHERE
contact_cust_no_500 = v_gecars_num LIMIT 1;
IF ( v_id_count= 0 AND v_contact_count= 1 ) THEN
SELECT
MAX(contact_seq_no_500) + 1
INTO v_max_seq
FROM
test.customer_contact
WHERE
contact_cust_no_500 = v_gecars_num LIMIT 1;
INSERT INTO theta.temp_customer_contacts3 VALUES (
v_gecars_num,
NULL,
v_max_seq,
i_name,
NULL,
i_phone,
NULL,
i_fax,
i_email,
i_id,
i_responsibility
);
ELSIF ( v_id_count = 0 AND v_contact_count = 0 ) THEN
INSERT INTO theta.temp_customer_contacts3 VALUES (
v_gecars_num,
NULL,
1,
i_name,
NULL,
i_phone,
NULL,
i_fax,
i_email,
i_id,
i_responsibility
);
ELSIF ( v_id_count = 1 AND v_contact_count = 1 ) THEN
UPDATE test.customer_contact
SET
contact_name_500 = i_name,
contact_email_addr_500 = i_email,
contact_tele_500 = i_phone,
contact_fax_500 = i_fax,
contact_notes_500 = i_responsibility
WHERE
contact_other_500 = i_id;
ELSE
--GOTO nextpos;
END IF;
-- <<nextpos>>
--NULL;
END LOOP;
CLOSE r;
EXCEPTION
WHEN sqlstate 'COEXP' THEN
raise notice '%','ERROR: ';
raise notice '%','No data present in abc Contact staging table';
WHEN OTHERS THEN
err_num := sqlstate;
err_msg := sqlerrm;
RAISE;
DELETE FROM theta.abc_contact_stg;
END;
$BODY$;
Ok, Deine Fragen werden präziser, aber im Kontext schwer nachvollziehbar.
Kurze Frage, kurze Antwort:
Das Konzept eine Schleife zu tunen, ist:
Auflösen der Schleife.
Besonders dann, wenn es eine Schleife in einer Schleife ist.
Was dabei eine nicht unerhebliche Rolle spielt, sind die Mengengerüste der verschachtelten Schleifen. Reden wir von Millionen, Tausend, Hundert, Zehn, Einer?
Eine einzelne Schleife über diese Mengen kann gut bewältigt werden. Zwei verschachtelte Schleifen über diese Mengen aber …
Du kannst das selbst ausrechnen.
Wie löse ich zwei verschachtelte Schleifen?
Indem ich die Abfragen der beiden Schleifen vereine (Join) und nur noch über eine Menge iteriere. Dabei gibt es verschiedene Wege, den Join zu vollziehen. Ich kann die Schleifen in die Abfrage verlagern (schlecht) oder ich kann (hoffentlich) einen großen Join erreichen.
Schau Dir das an. Ich melde mich wieder.
Mal grundsätzlich als Gedanke:
Migration funktioniert nicht 1:1, klar oder?
Das liegt nicht nur an inkompatiblen Befehlen. Du kannst leider auch nicht davon ausgehen, daßs die Anwendung, die du migrierst, eine optimale Lösung ist. Und das aus zwei Perspektiven. Fachliche Mängel und technische Mängel bezogen auf die Nutzung der Tools.
Du musst bei der Migration also auch die ursprüngliche Umsetzung hinterfragen und ggf ersetzen/verbessern.
Sicher. Das werde ich tun. Vielen Dank.
Macht für mich keinen Sinn, eine Abfrage mit Limit 1, die sowieso nur einen Datensatz ausgibt. “Limit 1” kann weg. Mit oder ohne Limit 1, zum Problem der Dauer kann man nichts sagen anhand des Beispiels.
Der Sprungbefehl “GOTO …” kann bestimmt nicht nur mit dem Setzen einer Variable migriert werden. Man müsste die Variable dann auch irgendwann prüfen und fallweise den Block vor der Sprungmarke * ausführen oder nicht.
Man kann alle Prüfungen “If length(xy) > ab” mit OR verknüpfen und dann den folgenden Code abhängig davon ausführen oder nicht.
- Der Block zwischen dem letzten GOTO und der Sprungmarke muss konditional ausgeführt werden, wenn man kein GOTO nutzt.