1

I am importing data from one table(say old_table). I have made a table(say new_table) in another database and i am using mysql stored procedure to populate it. I need to iterate through each record in old_table, and check if users email is already present in new_table(new_table have records already present, migrated from some other table). My cursor fails to retrieve all the records and fails after fetching few records. The value of no_more_rows becomes 1 after fetching few records even though the query gives more values when run separately. Here is the code-

    CREATE DEFINER=`root`@`localhost` PROCEDURE `test_3_1(logging and nested procedure)`(IN `init_count` INT)
    LANGUAGE SQL
    NOT DETERMINISTIC
    MODIFIES SQL DATA
    SQL SECURITY DEFINER
    COMMENT ''
BLOCK1: BEGIN
/*
5.1
migrating users from table con_consumer_detail 
(these con_consumer_detail users are guest checkouts and have no entry in con_consumer)
Tables populated in new db are
um_user
um_user_details -- (no sense to enrich this table)
um_user_shipping_information    --
um_user_proofs          (no proofs in guest checkouts)
um_user_phone_numbers           --
--no guest checkout with entry in table con_consumer_source_detail
*/

declare my_fname varchar(255);
declare my_lname varchar(255);
declare my_email varchar(255);

declare account_type varchar(20);
declare account_status varchar(20);
declare user_type varchar(255); 
declare my_con_consumer_detail_id bigint(20);

declare my_gender varchar(20);
declare my_date_of_birth date;

declare my_address_street1 varchar(255);
declare my_address_street2 varchar(255);
declare my_address_city varchar(255);
declare my_address_state varchar(255);
declare my_address_country varchar(255);
declare my_zip varchar(255);

declare my_pancard_number varchar(15);
declare my_aadharcard_number varchar(15);

declare my_um_user_id bigint(20);

declare no_more_rows1 int default 0;
declare count_id bigint(20) default 0;
declare count_row_completed bigint(20);

declare umuser_cursor cursor for select 
stg_citruspay.con_consumer_detail.first_name,
stg_citruspay.con_consumer_detail.last_name,
stg_citruspay.con_consumer_detail.email,
stg_citruspay.con_consumer_detail.id as con_consumer_detail_id,
stg_citruspay.con_consumer_detail.sex,
stg_citruspay.con_consumer_detail.date_of_birth,
stg_citruspay.con_consumer_detail.address_street1,
stg_citruspay.con_consumer_detail.address_street2,
stg_citruspay.con_consumer_detail.address_city,
stg_citruspay.con_consumer_detail.address_state,
stg_citruspay.con_consumer_detail.address_country,
stg_citruspay.con_consumer_detail.address_zip,

stg_citruspay.con_consumer_detail.pan_card,
stg_citruspay.con_consumer_detail.aadhar_card
from con_consumer_detail 
left join con_consumer on
con_consumer_detail.id=con_consumer.consumer_detail
where con_consumer.id is null 
limit 200;

DECLARE continue handler FOR not found set no_more_rows1= 1;
set count_id=init_count;

open umuser_cursor;
consumer_loop: LOOP

set count_id=count_id+1;


fetch umuser_cursor into my_fname,my_lname,my_email,my_con_consumer_detail_id,
my_gender,my_date_of_birth,my_address_street1,my_address_street2,my_address_city,
my_address_state,my_address_country,my_zip,my_pancard_number,my_aadharcard_number;

set account_status='ENABLED';
set account_type='BASIC';
set user_type='CONSUMER';




select count_id,my_fname,my_lname,my_email,my_con_consumer_detail_id,
my_gender,my_date_of_birth,my_address_street1,my_address_street2,my_address_city,
my_address_state,my_address_country,my_zip,my_pancard_number,my_aadharcard_number;

select "no_more_rows1:"+ no_more_rows1;

 if (no_more_rows1) then
    insert into stg_um_db.logger_table(
    rows_processed,
    procedure_executed
    )
    values(
    count_id-1,
    "5_1_last_row"
    );
leave consumer_loop;
close umuser_cursor;
end if;

/*finding existing user to merge guest checkout*/
    select stg_um_db.um_user.id into my_um_user_id
    from stg_um_db.um_user
    where um_user.email=my_email;

    select "my_um_user_id:"+ my_um_user_id;

    if(my_um_user_id is not null) then
    set count_id=count_id-1;
        select "existing user";
        /*
        if(char_length(my_zip)>32)then
        insert into stg_um_db.um_user_shipping_information(
        stg_um_db.um_user_shipping_information.um_user,
        stg_um_db.um_user_shipping_information.address_first_name,
        stg_um_db.um_user_shipping_information.address_last_name,
        stg_um_db.um_user_shipping_information.address_street1,
        stg_um_db.um_user_shipping_information.address_street2,
        stg_um_db.um_user_shipping_information.address_city,
        stg_um_db.um_user_shipping_information.address_state,
        stg_um_db.um_user_shipping_information.address_country
        )
        values(
        my_um_user_id,
        my_fname,
        my_lname,
        my_address_street1,
        my_address_street2,
        my_address_city,
        my_address_state,
        my_address_country
        );
        else
        insert into stg_um_db.um_user_shipping_information(
        stg_um_db.um_user_shipping_information.um_user,
        stg_um_db.um_user_shipping_information.address_first_name,
        stg_um_db.um_user_shipping_information.address_last_name,
        stg_um_db.um_user_shipping_information.address_street1,
        stg_um_db.um_user_shipping_information.address_street2,
        stg_um_db.um_user_shipping_information.address_city,
        stg_um_db.um_user_shipping_information.address_state,
        stg_um_db.um_user_shipping_information.address_country,
        stg_um_db.um_user_shipping_information.zip
        )
        values(
        my_um_user_id,
        my_fname,
        my_lname,
        my_address_street1,
        my_address_street2,
        my_address_city,
        my_address_state,
        my_address_country,
        my_zip
        );
        end if;
        */
    else
    select "New user";
        /*for new user*//*
        insert into stg_um_db.um_user(
        stg_um_db.um_user.id,
        stg_um_db.um_user.first_name,
        stg_um_db.um_user.last_name,
        stg_um_db.um_user.email,
        stg_um_db.um_user.account_type,
        stg_um_db.um_user.account_status,
        stg_um_db.um_user.user_type,
        stg_um_db.um_user.my_con_consumer_detail_id
        )
        values(
        count_id,
        my_fname,
        my_lname,
        my_email,
        account_type,
        account_status,
        user_type,
        my_con_consumer_detail_id
        );

        insert into stg_um_db.um_user_details(
        stg_um_db.um_user_details.um_user,
        stg_um_db.um_user_details.first_name,
        stg_um_db.um_user_details.last_name,
        stg_um_db.um_user_details.gender,
        stg_um_db.um_user_details.date_of_birth
        )
        values
        (
        count_id,
        my_fname,
        my_lname,
        my_gender,
        my_date_of_birth
        );

        if(char_length(my_zip)>32)then
        insert into stg_um_db.um_user_shipping_information(
        stg_um_db.um_user_shipping_information.um_user,
        stg_um_db.um_user_shipping_information.address_first_name,
        stg_um_db.um_user_shipping_information.address_last_name,
        stg_um_db.um_user_shipping_information.address_street1,
        stg_um_db.um_user_shipping_information.address_street2,
        stg_um_db.um_user_shipping_information.address_city,
        stg_um_db.um_user_shipping_information.address_state,
        stg_um_db.um_user_shipping_information.address_country
        )
        values(
        count_id,
        my_fname,
        my_lname,
        my_address_street1,
        my_address_street2,
        my_address_city,
        my_address_state,
        my_address_country
        );
        else
        insert into stg_um_db.um_user_shipping_information(
        stg_um_db.um_user_shipping_information.um_user,
        stg_um_db.um_user_shipping_information.address_first_name,
        stg_um_db.um_user_shipping_information.address_last_name,
        stg_um_db.um_user_shipping_information.address_street1,
        stg_um_db.um_user_shipping_information.address_street2,
        stg_um_db.um_user_shipping_information.address_city,
        stg_um_db.um_user_shipping_information.address_state,
        stg_um_db.um_user_shipping_information.address_country,
        stg_um_db.um_user_shipping_information.zip
        )
        values(
        count_id,
        my_fname,
        my_lname,
        my_address_street1,
        my_address_street2,
        my_address_city,
        my_address_state,
        my_address_country,
        my_zip
        );
        end if;


        if(my_pancard_number is not NULL and my_pancard_number!='') then
        insert into stg_um_db.um_user_proofs(
        stg_um_db.um_user_proofs.um_user,
        stg_um_db.um_user_proofs.proof_number,
        stg_um_db.um_user_proofs.proof_description_id
        )
        values(
        count_id,
        my_pancard_number,
        3
        );
        end if;

        if(my_aadharcard_number is not NULL and my_aadharcard_number!='') then
        insert into stg_um_db.um_user_proofs(
        stg_um_db.um_user_proofs.um_user,
        stg_um_db.um_user_proofs.proof_number,
        stg_um_db.um_user_proofs.proof_description_id
        )
        values(
        count_id,
        my_aadharcard_number,
        6
        );
        end if;
        */
end if;

        BLOCK2: BEGIN
        declare my_phone_number varchar(255);
        declare my_phone_type varchar(255);

        declare no_more_rows2 int default 0;

        declare um_phone_cursor cursor for select 
            stg_citruspay.con_consumer_detail_phone_number.phone_number,
            stg_citruspay.con_consumer_detail_phone_number.`type`
            from stg_citruspay.con_consumer_detail_phone_number
            where stg_citruspay.con_consumer_detail_phone_number.consumer_detail=my_con_consumer_detail_id;

        declare continue handler for not found
            set no_more_rows2=1;

        open um_phone_cursor;
        phone_loop: LOOP

        fetch um_phone_cursor into my_phone_number,my_phone_type;

/*  
select count_id,phone_number,phone_type,my_con_consumer_detail_id;
*/
        if no_more_rows2 then
            leave phone_loop;
            close um_phone_cursor;
        end if;

        /*
        if(my_um_user_id is not null) then

            if(phone_number is not null  and phone_number!='' ) then 
            insert into stg_um_db.um_user_phone_numbers(
            stg_um_db.um_user_phone_numbers.um_user,
            stg_um_db.um_user_phone_numbers.phone_number,
            stg_um_db.um_user_phone_numbers.phone_type
            )
            values(
            my_um_user_id,
            my_phone_number,
            my_phone_type
            );
            end if;

        else 
            if(phone_number is not null  and phone_number!='' ) then
            insert into stg_um_db.um_user_phone_numbers(
            stg_um_db.um_user_phone_numbers.um_user,
            stg_um_db.um_user_phone_numbers.phone_number,
            stg_um_db.um_user_phone_numbers.phone_type
            )
            values(
            count_id,
            my_phone_number,
            my_phone_type
            );
            end if;

        end if;
        */
        end loop phone_loop;
        end BLOCK2;

if (! (count_id % 10)) then 
set count_row_completed=count_id;

insert into stg_um_db.logger_table(
rows_processed,
procedure_executed
)
values(
count_row_completed,
"5_1"
);

DO SLEEP(0.5);
end if;

end loop consumer_loop;
END BLOCK1
2

NOT FOUND is shorthand for the class of SQLSTATE values that begin with '02'. This is relevant only within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. If no more rows are available, a No Data condition occurs with SQLSTATE value 02000. To detect this condition, you can set up a handler for it (or for a NOT FOUND condition).

This condition also occurs for SELECT ... INTO var_list statements that retrieve no rows."

Work Around: Use put SELECT ... INTO that may return no rows into a separate BEGIN ... END block with its own CONTINUE handler for NOT FOUND as a workaround.

1

Don't do it with a Cursor, do it with 2 SQL statements. One discovers what is new and adds them; the other discovers what has changed and modifies them.

Details.

0

What I do is something like this:

DECLARE id INT;
DECLARE somevar INT; -- example
DECLARE cur CURSOR FOR SELECT id FROM some_table;
DECLARE HANDLER FOR NOT FOUND SET nf = 1;

OPEN cur;


consumer_loop: LOOP
FETCH cur INTO var_id;
IF nf = 1 THEN -- CONDITION A
-- IF is the end of the CURSOR nf turns into zero
-- So we do the validation to continue or break the loop
  LEAVE consumer_loop;
END IF;

-- Any operation not resulting in not found state

SELECT value INTO some_var [WHERE conditions] LIMIT 1;
-- An important thing is that if you use SELECT value INTO some_var
-- The resultset must only have exactly one row.
-- that is why we use limit 1 to ensure this condition.

IF nf = 1 THEN
-- To clean this var because we can have the value from the previous row
  SET some_var = ""; 

-- THIS IS THE MOST IMPORTANT STEP because nf sets to 1 
-- with any NOT FOUND STATE of MYSQL, we can assing value of zero
-- because we already know nf = 0 at CONDITION A
  SET nf = 0; 
END IF;


-- do others operations

end loop consumer_loop;

I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.