Doppelte Einträge in MySQL Datenbank



  • Hallo,

    ich habe folgendes Problem. Ich trage Datensätze in eine MySQL Datenbank ein, das funktioniert auch soweit ganz gut.
    Leider kommt es manchmal vor, dass ein Eintrag doppelt in die Datenbank eingetragen wird.
    Über UNIQUE wird der doppelte Eintrag verhindert, aber schön ist es nicht.
    Für die Kommunikation mit der Datenbank nutze ich das SDK der Datenbank.

    Hier die Funktion, die einen Datensatz in die Datenbank überträgt.

    bool RechnungsDaten::SaveRechnung(int KundenNr, int MitarbeiterNr, double Summe, double Betrag, CString* RechnungsNr, int ZArt)
    {
    	MYSQL* mysql_con = NULL;
    	CString query;
    	/*..*/
    	query.Format("INSERT INTO %s (RechnungsNr,KundenNr,MitarbeiterNr,Summe,Endbetrag,Datum, ZArt) VALUES ('%s',%d,%d,%f,%f,Now(),%d)",
    		m_strSQLTableName1,
    		*RechnungsNr,
    		KundenNr,
    		MitarbeiterNr,
    		Summe,
    		Betrag,
    		ZArt
    		);
    
    	if(m_SQLConnector.ConnectDB() != DB_OK)
    	{
    		AfxMessageBox(m_SQLConnector.GetErrMsg(),MB_ICONERROR | MB_OK);
    		return false;
    	}
    
    	if(m_SQLConnector.SendSQLQuery(query, &mysql_con)!= DB_OK)
    	{
    		AfxMessageBox(m_SQLConnector.GetErrMsg(),MB_ICONERROR | MB_OK);
    		m_SQLConnector.CloseConnection();
    		return false;
    	}
    
    	m_SQLConnector.CloseConnection();
    	return true;
    
    }
    

    Send query befindet sioch in der SQLConnector Klasse

    int SQLConnector::SendSQLQuery(CString query, MYSQL** pMysql_con)
    {
    	if(mysql_real_query(mysql_con, query, query.GetLength()) != 0)
    	{	
    		m_strLastErrMsg.Format("Bad Query. Error: %s", mysql_error(mysql_con));
    		return BAD_QUERY;
    	}
    
    	*pMysql_con = mysql_con;
    	return DB_OK;
    }
    

    Der Aufruf der Aktion wird über ein Button ausgelöst

    void CRechnungsTabelleDlg::OnBnClickedButtonKasse()
    {
    	if(m_iStatus == OFFEN)
    	{
    		HtmlRechnungData data;
    		HtmlRechnung quitung;
    
    /* ... */
    		SwichtAnsichtBezahlt(); //Hier wird der Status auf BEZAHLT gesetzt
    		RechnungsDaten RDaten;
    
    		RDaten.SaveRechnung(m_pKDaten->m_Daten.iKundenNr, m_pMDaten->m_Daten.iMitarbeiterNr, m_dSumme, m_dBetrag, &m_strRechnungsNr, ZArt);
    		/* ... */
    		return;
    
    	}
    
    	if(m_iStatus == BEZAHLT)
    		ShellExecute(0, 0, m_strLastRechnungPfad, 0, 0, SW_SHOW);
    
    }
    

    Ich hoffe mir kann jemand weiterhelfen. Der Fehler ist schwerz zu reproduzieren,
    deshalb hoffe ich, dass jemand im Quellcode schon die mögliche Fehlerquelle findet.

    Vielen Dank
    Gruß charlie



  • Für einen Primary Key ein. Wenn du den doppelt belegen willst, rumst es gewaltig 😃 Daher mit try-catch die Exception abfangen.



  • Hab doch geschrieben, dass ich bereits ein UNIQUE in der Tabelle eingefügt habe.
    Ich bin mit dieser Lösung aber nicht zufrieden. Irgendwo muss ja ein Fehler im
    Code sein.



  • evtl. ein Fehler in der MySQl-API-Anbindung?
    Und was spricht gegen einen Primary Key? Für sowas ist der doch u.a. da.



  • UNIQUE ist doch sowas wie ein Primary Key, oder ?

    Das Speichern in der Datenbank funktioniert ja anscheinend. Ich vermute den Fehler eher in der Bestimmung deiner Parameter (mindestens einer muss dann ja eindeutig sein), z.B. bei der Erzeugung einer eindeutigen Rechnungsnummer.



  • In Primary Key ist die UNIQUE Funktionalität bereits enthalten.

    Die Rechnungsnummern werden eindeutig vergeben, da es sich nur um das aktuelle Datum mit Uhrzeit handelt.
    Das Problem muss irgendwo anders zu finden sein. Die Frage ist, wird die Funktion
    zum Eintragen der Rechnungsdaten doppelt aufgerufen oder liegt der Fehler in der
    Kommunikation mit der Datenbank. Ich werde zu diesem Zweck die Vorgänge in einem
    Logfile mitprotokollieren. Vielleicht komme ich so weiter.



  • Die Datenbank macht nur das was du ihr sagts. Wenn du nur eine Datensatz einfügst dann fügt die Datenbank nicht 2 ein.
    Ein Fehler in der API ist auszuschließen.
    Eine Rechnungsnummer aus Datum und Uhrzeit kann nicht eindeutig sein bzw. nur dann wenn nur einer das Programm aufruft.
    Was aber wenn es 2 gleichzeitig machen!



  • Es ist bisher noch eine Einzelplatz Lösung, es kann also kein Eintrag mit der SELBEN
    Datum und Uhrzeit Kombination vorkommen. Wenn die Datenbank nur das macht, was man
    ihr sagt, wie kommen dann die 2 Einträge in meine Datenbank? Wenn der Button
    Eintragen betätigt wird, kommen 2 Eingage Dialog, dann wird der Status auf BEZAHLT
    gesetzt, danach wird der SQL-Query abgesandt. Meine Frage ist jetzt, wenn die
    Funktion 2 mal aufgerufen wird, wieso kommen die Eingabe Dialog nicht 2 mal?

    Gruß charlie


Anmelden zum Antworten