dubbele records bij csv naar db import

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

James C

James C

27/09/2023 15:55:45
Quote Anchor link
Hallo,

Ik heb een script gemaakt om een csv bestand in te lezen naar een mysql database. Na het inlezen moet vervolgens het bestand verplaatst worden. Nou zie ik dat sommige (maar niet alle) records dubbel in de database komen en ik heb geen idee hoe dat kan. Dit is het scipt, hopelijk ziet iemand de fout want ik zie het na uren staren niet meer.
En de csv bestanden zijn gecheckt maar bevatten geen dubbele records en worden goed verplaatst.
Error reporting geeft geen enkele error.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php

error_reporting(E_ALL);
error_reporting(-1);
ini_set('error_reporting', E_ALL);
ini_set('error_log', '/var/www/error.log');

//
        $tabelnaam = 'testje';  
        $dir = '/var/www//data/www/bestandjes/dos';


// database connectie maken
$conn = mysqli_connect('localhost','user','pass','data');
 if(!$conn)
{

    die(mysqli_error());
}

 
// verander de cwd omdat dit bestand buiten deze map wordt gerunned
chdir ($dir);

// start invoer
foreach (glob("*.csv") as $bestand)
{

$bestandsnaam = fopen($bestand, 'r');
 
// als dit woord in een regel staat dan skip deze regel (de kolomkoppen wil je niet inserten en daar staat o.a. dit woord in)
$woord = "disconnect_reason";
$woord2 = "Incoming"; // regels waar dit woord in staat willen we niet hebben
 
    while (!feof($bestandsnaam))
    {

        $getTextLine = fgets($bestandsnaam);
        // de laatste regel in de csv bestanden die aangeleverd worden is leeg dus deze niet meenemen anders krijgen we een lege regel in onze tabel
            if(empty($getTextLine))
            {

                 continue;
           }

        // de eerste regel bevat de headers dus die willen we ook niet meenemen in de database, dat doen we door te filteren op de var $woord                   
           elseif (strpos($getTextLine, $woord) !== false)
           {

                continue;          
            }

           elseif (strpos($getTextLine, $woord2) !== false)
           {

                continue;
           }

            else
               {          
                    $explodeLine = explode(",",$getTextLine);
                    
                    list($id,$h323_conf_id,$account_id,$cli,$cld,$connect_time_utc,$disconnect_time_utc,$disconnect_description,$disconnect_reason,$used_quantity,$bit_flags,$bitflags_description) = $explodeLine;
                            // zet hier de datums format goed
                                $connect_time_utc_new = date ('Y-m-d H:i:s', strtotime($connect_time_utc));
                                $disconnect_time_utc_new = date ('Y-m-d H:i:s', strtotime($disconnect_time_utc));                         


                    $qry = "INSERT INTO $tabelnaam (idsod, h323_conf_id, account_id, cli, cld, connect_time_utc, disconnect_time_utc, disconnect_description, disconnect_reason, used_quantity, bit_flags, bitflags_description)
                    VALUES('"
.$id."','".$h323_conf_id."','".$account_id."','".$cli."','".$cld."','".$connect_time_utc_new."','".$disconnect_time_utc_new."','".$disconnect_description."','".$disconnect_reason."','".$used_quantity."','".$bit_flags."','".$bitflags_description."')";    
                
                mysqli_query($conn,$qry);

                }
    }

    
// bestand sluiten
fclose($bestandsnaam);
// bestand verplaatsen
rename($bestand, 'verwerkt/'.$bestand.'');


}



?>
 
PHP hulp

PHP hulp

30/05/2024 08:51:19
 
Adoptive Solution

Adoptive Solution

27/09/2023 16:40:35
Quote Anchor link
2 mogelijkheden.

1. Het record komt al voor
2. Een veld is niet uniek. Vermoedelijk idsod. Vandaar 1.

Je voorkomt dubbele records met INSERT ON DUPLICATE UPDATE

Voorbeeld code

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
INSERT INTO
users ( account, registratiedatum, naam, adres, woonplaats )
VALUES ( faccount, now(), fnaam, fadres, fwoonplaats )
ON DUPLICATE KEY UPDATE
    naam = values(naam),
    adres = values(adres),
    woonplaats = values(woonplaats);


waarbij account uniek is.

https://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/

Toevoeging op 27/09/2023 16:54:22:

Even aanvullend.

De code is uit een stored procedure, vandaar de VALUES.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
CREATE PROCEDURE `spUserInsert`(IN `faccount` char(15), IN `fnaam` char(50), IN `fadres` char(50), IN `fwoonplaats` char(50))
Gewijzigd op 27/09/2023 16:41:36 door Adoptive Solution
 
Ivo P

Ivo P

27/09/2023 18:09:37
Quote Anchor link
1)

$explodeLine = explode(",",$getTextLine);

je weet dus 100% zeker dat je velden geen komma's van zichzelf bevatten?

Gebruik anders de csv functies van PHP.
https://www.php.net/manual/en/function.str-getcsv.php

2)
Mysql kent ook zelf de mogelijkheid om CSV files in te lezen, wat een heel stuk sneller is dan via losse query's in php.

"read data infile ... "
 
Aparicio Tello

Aparicio Tello

02/10/2023 08:55:58
Quote Anchor link
Hallo allemaal, Ik denk dat de oplossing van een goede manier is om dit probleem op te lossen. Door een unieke ID toe te voegen aan elk record, kunt u dubbele records detecteren en verwijderen. Ik ben gewoon aan het leren. Hoewel al een half jaar. Het is goed voor mij om onder jullie te zijn.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.