# Fehler 2601 trotz SQL-UPDATE ?



## rwolf (7. Nov 2012)

hi all,

muss grade den code eines verunfallten kollegen analysieren und bugs entfernen..

da gibts eine merkwürdige sache :
obwohl eine SQL-UPdate an prepared-statement übergeben wird,
wird der fehler 2601 (MS-SQL-Server 2008)  'duplicate entry at insert..' geworfen !

hä ?

hab extra mit dem NetBeans-Debugger den inhalt des prepared-stmt. gecheckt,
es steht wirklich ein SQL-UPdate drin und kein SQL-INSERT, wie man je leicht vermuten könnte !

hier mal der code :

```
sql_text = "UPDATE " +db_ref.tabnames[db_ref.TABN_EINGANG] +
                                               " SET bereich = ?,be_eg_match = ?,qamatch = ?,webauftrag = ?,"+
                                                " dessin = ?,partie = ?,espezvhd = ?,luser = ?,aendstat = ? "+
                                               " WHERE eingnr = ? AND mandant_id = ? AND jahrgang = ? ";
            
            if(test_flag)
                System.out.println("QPruef_Datahandler ** store_eingang Sichern Eingang-Nr. : "+p_eingnr);
        }
        System.out.println("qpdh ** store_eingang sql : "+sql_text);


        try
        {
            eg_con.setAutoCommit(true);
            ps = eg_con.prepareStatement(sql_text);

            idx++;
            ps.setString(idx, bereich_kurz);    //- 2,1 Bereich
            idx++;
            ps.setString(idx, bereich_kurz);    //- 3,2 BE_EG_MATCH ???
            idx++;
            ps.setInt(idx,i_qamatch);           //- 4,3 QAMATCH
            idx++;
            ps.setInt(idx,Integer.parseInt(wem.tfWebauftrag.getText() ) );    //- 5,4
            idx++;
            ps.setInt(idx,Integer.parseInt(wem.tfDessin.getText() ) );        //- 6,5
            idx++;
            ps.setInt(idx,Integer.parseInt(wem.tfPartieMaschine.getText() ) );    //- 7,6
            idx++;

            int ea_vhd = 0;
            if(espez_angelegt || (! appd_flag))
                ea_vhd = 1;                       //-ESpezvhd.  ja
            ps.setInt(idx,ea_vhd);                                  //- 8,7

            /* --Aenderg. Fr.Kowal. 07.11.2012 : Datum soll das alte bleiben !
            idx++;
            System.out.println("qpdh store_eingang Feld lupdate idx : "+idx);
            ps.setString(idx,mu2.get_date_String(""));  //- 9,8 lupdate
            * 
            * 
            */
            idx++;
            ps.setString(idx,mps.g_bearbeiter);     //- 10,9 luser
            
            idx++;
            ps.setInt(idx,1);                       //- 11, 10 Aendstat.
            
            idx++;
            //- bei Anfuegen Eintrag der neuen EingangsNr., sonst Filter auf EingangNr
            int egnr = 0;
            if(appd_flag)
            {
                if(test_flag)
                    System.out.println("QPruef_Datahandler ** Eingaenge anfuegen EingNr : "+max_eingg_id+" idx : "+idx);
                egnr = max_eingg_id;
            }
            else
            {
                egnr = p_eingnr;
            }
            ps.setInt(idx,egnr);    //- 12,11 eingnr
            
            idx++;
            if(test_flag)
                System.out.println("QPruef_Datahandler ** Eingaenge anfuegen mdt-id idx : "+idx);
            ps.setInt(idx, mps.g_mandant);   //- 13,- mandant_id 

            idx++;
            ps.setInt(idx, mps.akt_jahrgang);   //- 14, - jahrgang 
            
            boolean result = ps.execute();
            
            eg_con.close();
            //System.out.println("QPruef_Datahandler ** Eingaenge anfuegen / sichern : OK ! idx  : "+idx+" result : "+result);
            mps.show_msg_dialog(tla.get_lang_text("MSG_EG_MNG_TITLE"),tla.get_lang_text("MSG_EG_APPD_OK"));
            
            
            mu2.logging(mps.logpath,"QPruef_DataHandler ** Eingang "+p_eingnr+" hinzugefügt !",
                    mps.LOG_CONT, mps.akt_time_stamp);

        }
        catch ( SQLException sqle )
        {
            String meldg = sqle.getMessage();
            int msg_num = sqle.getErrorCode();
            System.err.println("qpdh ** store_eingang ErrorNummer : "+msg_num+" Mesg.: "+meldg);
            if(msg_num == 2601)
                mps.show_msg_dialog(tla.get_lang_text("MSG_EG_DUPLIK_TITLE"),tla.get_lang_text("MSG_EG_DUPLIK_TEXT"));      
            else
                mps.show_msg_dialog("QPruef_DataHandler","**** Eingaenge IDX : "+idx+" SQL-Error : " +sqle.getMessage());
        }
```

hier die Originalmeldung :
qpdh ** store_eingang ErrorNummer : 2601 Mesg.: Cannot insert duplicate key row in object 'dbo.eingang_i' with unique index 'I_UNI_MDTuJGGuEINGNRuBER'. The duplicate key value is (23, P, 12, 2012).

Umgebung : Win7Home,Netbeans 7.1.2,java sdk 1.6.026, MS-SQL-Server 2008 via VPN

schon komisch, gelle ?


----------



## SlaterB (7. Nov 2012)

also du wunderst dich hauptsächlich zur Sprache der Fehlermeldung?
ist doch unnötig da zu unterscheiden, 'Cannot update so that duplicate key row in object' oder was? 

du kannst ja auch ohne Java in einem SQL-Tool nachschauen, welche Fehlermeldung bei einem Update verletztend zum Unique Key kommt

warum dein PreparedStatement welche Werte setzt, gar zweimal, ist hoffentlich nicht deine Frage,
aus dem Codewirrwarr bestimmt nicht zu erkennen


----------



## rwolf (19. Nov 2012)

naja, ich sollte halt bei einem update
die where-klausel immer mit nem SELECT .. testen


----------

