Iteration von Abfragen


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.

1 „Gefällt mir“

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.

2 „Gefällt mir“

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.
1 „Gefällt mir“

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.