WHILE Loop for data migration/merge with multiple fields for matching
So I am assuming the tables look something like this (for my easy I am using table variables instead of physical/temp tables):

DECLARE @North TABLE
(
    ID INT NOT NULL,
    FirstName VarChar(20) NULL,
    LastName VarChar(50) NULL,
    Email VarChar(100) NULL,
    [Login] VarChar(20) NOT NULL
)

DECLARE @South TABLE
(
    ID INT NOT NULL,
    FirstName VarChar(20) NULL,
    LastName VarChar(50) NULL,
    Email VarChar(100) NULL,
    [Login] VarChar(20) NOT NULL
)

DECLARE @MigrationPersonLog TABLE
(
    [SourceWfoPersonID] INT NULL
    ,[SourceFirstName] VarChar(20) NULL
    ,[SourceLastName] VarChar(50) NULL
    ,[SourceEmail] VarChar(100) NULL
    ,[SourceLogin] VarChar(20) NULL

    ,[TargetWfoPersonID] INT NULL
    ,[TargetFirstName] VarChar(20) NULL
    ,[TargetLastName] VarChar(50) NULL
    ,[TargetEmail] VarChar(100) NULL
    ,[TargetLogin] VarChar(20) NULL
    ,[Matched] BIT --Matched (= 1) or not (=0)
    ,[MatchArtifact] VarCHar(50) --What was matched or not matched
)


To scsimon's point, SQL really prefers to work in sets instead of iterations.  So anything you can do to avoid loops is preferred in almost all situations.   I think this should solve basically everything you need.  I may not have understood everything you wanted to do with the logging table when it came to inserting new rows into the North table.  But I definitely think this should be a framework you can work with.  I tried to make the code self-documenting but I can always explain something if that is needed.

--Check for all instances where the Login's Match
INSERT INTO @MigrationPersonLog
(
    [SourceWfoPersonID]
    ,[SourceFirstName]
    ,[SourceLastName]
    ,[SourceEmail]
    ,[SourceLogin]
    ,[TargetWfoPersonID]
    ,[TargetFirstName]
    ,[TargetLastName]
    ,[TargetEmail]
    ,[TargetLogin]
    ,[Matched]
    ,[MatchArtifact]
)
SELECT
S.ID,   --[SourceWfoPersonID]
S.FirstName,    --[SourceFirstName]
S.LastName, --[SourceLastName]
S.Email,    --[SourceEmail]
S.[Login],  --[SourceLogin]
N.ID,   --[TargetWfoPersonID]
N.FirstName,    --[TargetFirstName]
N.LastName, --[TargetLastName]
N.Email,    --[TargetEmail]
N.[Login],  --[TargetLogin]
1,  --[Matched]
'Login' --[MatchArtifact]
FROM @South S
    INNER JOIN @North N
        ON S.[Login] = N.[Login]

--Check for All Instances where the Email's Match
INSERT INTO @MigrationPersonLog
(
    [SourceWfoPersonID]
    ,[SourceFirstName]
    ,[SourceLastName]
    ,[SourceEmail]
    ,[SourceLogin]
    ,[TargetWfoPersonID]
    ,[TargetFirstName]
    ,[TargetLastName]
    ,[TargetEmail]
    ,[TargetLogin]
    ,[Matched]
    ,[MatchArtifact]
)
SELECT
S.ID,   --[SourceWfoPersonID]
S.FirstName,    --[SourceFirstName]
S.LastName, --[SourceLastName]
S.Email,    --[SourceEmail]
S.[Login],  --[SourceLogin]
N.ID,   --[TargetWfoPersonID]
N.FirstName,    --[TargetFirstName]
N.LastName, --[TargetLastName]
N.Email,    --[TargetEmail]
N.[Login],  --[TargetLogin]
1,  --[Matched]
'Email' --[MatchArtifact]
FROM @South S
    INNER JOIN @North N
        ON S.Email = N.Email
    LEFT OUTER JOIN @MigrationPersonLog L --This LEFT OUTER JOIN makes sure we don't double log people who match on LoginID and Email
        ON L.[SourceWfoPersonID] = S.ID
WHERE L.[SourceWfoPersonID] IS NULL

--Check for All Instances where the First Name + Last Name Matches
INSERT INTO @MigrationPersonLog
(
    [SourceWfoPersonID]
    ,[SourceFirstName]
    ,[SourceLastName]
    ,[SourceEmail]
    ,[SourceLogin]
    ,[TargetWfoPersonID]
    ,[TargetFirstName]
    ,[TargetLastName]
    ,[TargetEmail]
    ,[TargetLogin]
    ,[Matched]
    ,[MatchArtifact]
)
SELECT
S.ID,   --[SourceWfoPersonID]
S.FirstName,    --[SourceFirstName]
S.LastName, --[SourceLastName]
S.Email,    --[SourceEmail]
S.[Login],  --[SourceLogin]
N.ID,   --[TargetWfoPersonID]
N.FirstName,    --[TargetFirstName]
N.LastName, --[TargetLastName]
N.Email,    --[TargetEmail]
N.[Login],  --[TargetLogin]
1,  --[Matched]
'FirstName+LastName'    --[MatchArtifact]
FROM @South S
    INNER JOIN @North N
        ON (S.FirstName + S.LastName) = (N.FirstName + N.LastName)
    LEFT OUTER JOIN @MigrationPersonLog L --This LEFT OUTER JOIN makes sure we don't double log people who match on First Name + Last Name AND (LoginID and/or Email)
        ON L.[SourceWfoPersonID] = S.ID
WHERE L.[SourceWfoPersonID] IS NULL


--Log all instances which failed previous 3 checks that they failed the checks
INSERT INTO @MigrationPersonLog
(
    [SourceWfoPersonID]
    ,[SourceFirstName]
    ,[SourceLastName]
    ,[SourceEmail]
    ,[SourceLogin]
    ,[TargetWfoPersonID]
    ,[TargetFirstName]
    ,[TargetLastName]
    ,[TargetEmail]
    ,[TargetLogin]
    ,[Matched]
    ,[MatchArtifact]
)
SELECT
S.ID,   --[SourceWfoPersonID]
S.FirstName,    --[SourceFirstName]
S.LastName, --[SourceLastName]
S.Email,    --[SourceEmail]
S.[Login],  --[SourceLogin]
NULL,   --[TargetWfoPersonID]
NULL,   --[TargetFirstName]
NULL,   --[TargetLastName]
NULL,   --[TargetEmail]
NULL,   --[TargetLogin]
0,  --[Matched]
NULL    --[MatchArtifact]
FROM @South S
    LEFT OUTER JOIN @MigrationPersonLog L --This is used to quickly catch anyone who didn't get logged previously.
        ON L.[SourceWfoPersonID] = S.ID
WHERE L.[SourceWfoPersonID] IS NULL

INSERT INTO @North
(
    ID, --Unless this is and Identity and you can ignore it
    FirstName,
    LastName,
    Email,
    [Login]
)
S.ID,   --ID, 
S.FirstName,    --FirstName,
S.LastName, --LastName,
S.Email,    --Email,
S.[Login]   --[Login]
FROM @South S
    LEFT OUTER JOIN @MigrationPersonLog L --This is used to quickly catch anyone who didn't get logged previously.
        ON L.[SourceWfoPersonID] = S.ID
WHERE L.[SourceWfoPersonID] IS NULL


Hope this give you what you are looking for.