Announcement

Collapse
No announcement yet.

Nachträglichen Serial anlegen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Nachträglichen Serial anlegen

    Hallo zusammen,

    bin grad bei meiner Recherche auf dieses Forum gestoßen. Ich habe folgendes Problem bei meiner Infomixdatenbank auf der Arbeit.

    Wir haben eine Tabelle für die offenen Posten. Bisher gab es leider kein Serialfeld und die Zugriffe gingen immer über die Rechnungsnummer und 2 adnere Felder. Jetzt brauch ich aber aus diversen Gründen zwingend ein Serial oder zumindest ein uniqueKey Feld in der Tabelle. Ich habe gestern schon ein unload gemacht. Ergebnis, 2.18GB große Datei die ich nirgends öffnen kann um sie zu editieren. Jetzt hab ich schon eine neue Tabelle mit Serialfeld erstellt, kann die DAtei aber nicht darein laden.

    Daher meine Frage, gibt es eine Möglichkeit über irgendwelche umwege nachträglich ein Serialfeld in die Tabelle einzubauen? Mein Teamleiter meinte es gäbe ne Möglichkeit erst ein Integerfeld zu füllen und das dann umzuwandeln in ein serial damit bei jedem neuen Eintrag die Serial fortgeführt wird.

    Hoffe auf eure Hilfe

    Gruß
    Christoph

  • #2
    Hallo Christoph,
    was Dein Teamleiter sagt stimmt schon. Nur musst Du ja das Integerfeld auch irgendwie bestücken. Es gibt in INFORMIX ein internes Serialfeld namens ROWID, was man abfragen kann. Du köntest also an Deine Tabelle ein Integerfeld feldneu, bei dem zunächst NULL zugelassen ist, anfügen und dann updaten:
    update Tabelle1 set feldneu=ROWID

    Dann wandelst Du feldneu in serial um und fertig.

    Die zweite Möglichkeit wäre eine identische leere Tabelle anzulegen, die zusätzlich das Serialfeld enthält. Nun brauchst Du nur die Werte der alten mit Update in die neue Tabelle einzulesen. Das Serialfeld bestückt sich dabei von alleine. Hast Du das Serialfeld am Ende der neuen Tabelle angehängt, kannst Du dann einfach schreiben:

    Insert INTO Tabelle2 Select * from Tabelle1 {ORDER BY ...}

    Gruß
    Zuletzt editiert von frauwue; 20.12.2010, 16:00.
    docendo discimus

    Comment


    • #3
      Morgen Frauwue,

      vielen Dank für deine Hilfe. Werde es im Laute des Tage mal testen und mich dann nochmal melden. Das mit RowID hatte ich auch schonmal gelesen, allerdings den nutzen nicht erkannt

      Schönen Tag noch
      Christoph

      Comment


      • #4
        Hallo zusammen,

        sry das ich mich erst nun melde... Ich habe nun den insert mit dem select versucht. Leider klappt der nicht. Ich bekomme immer folgenden Fehler:
        -458 Long transaction aborted
        -12204 RSAM error: Long transaction detected
        Wie kann ich den Fehler umgehen. In der Tabelle sind über 11Mio einträge

        Comment


        • #5
          Hi,

          vielleicht kannst Du die einzulesenden Sätze etwas aufteilen mit verschiedenen where Bedingungen.

          Gruß
          docendo discimus

          Comment


          • #6
            Jo danke, das war der entscheidende Tip. Habs nun in 8 Blöcke aufgeteilt und es ging dann

            Comment


            • #7
              Ich muss mich hier leider nochmal melden. Und zwar habe ich es ja hinbekommen, wenn ich im dbaccess den insert auf 8 Blöcke aufgeteilt habe klappte es ja. Jetzt wollte ich ein Script machen damit es Abends automatisch läuft, da es schon recht lange dauert.

              Leider bekomme ich da immer zwei Fehlermeldungen. Ich habe folgendes Script:
              declare sc_ops scroll cursor with hold for
              select * FROM opstamm
              open sc_ops

              LET x = 0
              LET pi = 0
              LET fehler = 0

              display "System arbeitet..."
              foreach sc_ops into r_ops.*

              LET x = x + 1
              LET pi = pi + 1
              if x = 1 then
              begin work
              end if
              insert into opstamm_test
              VALUES (r_ops.*)

              if x = 500000 then
              commit work
              display pi,' Sätze geschrieben'
              LET x = 0
              end if

              end foreach
              Dabei bekomme ich nach 6.5 Mio Datensätzen immer den selben Fehler.
              SQL Statementerror -264
              System Error -131

              Hat jemand evtl eine Idee, warum diese Fehler kommen und warum er überhaupt in eine tmp Datei schreibt?

              Comment


              • #8
                Hi,

                in meiner alten Informix Version, bedeuten diese Fehler, dass die Platte voll ist. Hast Du keine Informix Fehlerliste für Dein System?
                Warum musst Du das überhaupt per Script laufen lassen? Ich dachte das wäre eine einmalige Angelegenheit.
                Wofür brauchst Du eigentlich die Transaktionen? Lass die doch mal ganze weg.

                Gruß
                Zuletzt editiert von frauwue; 21.01.2011, 11:45.
                docendo discimus

                Comment


                • #9
                  Hi, ja eigentlich ist es auch eine einmalige Angelegenheit. Allerdings dauert es, wenn ich es im dbaccess einzeln mache, auch ca 4 - 5 Stunden bis die Sätze geschrieben sind und wir wollen das über Nacht laufen lassen, damit am nächsten Morgen die Kollegen mit der Tabelle arbeiten können. Wo ich das erfolgreich getestet habe war im Test bei uns. Das sind alle Tabellen 1:1 mit der Produktion. Zusätzlich müssen nachher noch automatisch die Indizes und Trigger für die Tabelle angelegt werden. Alles per Hand wäre etwas zu umständlich.

                  Und mit den Fehler hast du Recht. Es bedeutet kein Platz mehr. Aber wieso ist kein Platz mehr nach 6.5 Mio Sätzen? Eigentich sollte doch spätestens nach dem commit die tmp Tabelle wieder leer sein oder hab ich da nen Denkfehler?

                  Comment


                  • #10
                    Hi,

                    gerade habe ich meinen vorherigen Beitrag nochmal editiert. Ich würde die Transaktionen ganz weglassen, sodass jeder Satz einzeln weggeschrieben wird.
                    docendo discimus

                    Comment


                    • #11
                      Meinst du ohne begin und commit? Das hab ich auch schon mal versucht. Dann ist bereits nach ca 3.5 Mio Ende mit dem Fehler long transaction oder so.

                      Comment


                      • #12
                        Hi,

                        dann solltest Du Deine Lesezugriffe aus der Originaltabelle schon in Gruppen einteilen (so hatte ich es ursprünglich sowieseo gemeint). Veilleicht kannst Du dabei ja das Feld ROWID verwenden.

                        Gruß
                        docendo discimus

                        Comment


                        • #13
                          Hallo,

                          also zu guter letzt hat es jetzt geklappt. Mit folgendem Script:
                          Code:
                              while pi != anzahl
                                  if (x = 0 and pi0 = true) or (x != 0 and pi0 = false) then
                                      if pi != 0 then
                                          LET d = i+1
                                      else
                                          LET d = 0
                                      end if
                                          select count(*) into anz FROM opstamm
                                              where ops_ktonr between d and i
                          
                                          while anz = 0 
                                              LET i = i + 10000
                                              select count(*) into anz FROM opstamm
                                                  where ops_ktonr between d and i
                                          end while
                          
                                          declare sc_ops scroll cursor with hold for
                                          select * FROM opstamm
                                              where ops_ktonr between d and i
                                          open sc_ops  
                                  end if
                          
                                  foreach sc_ops into r_ops.*
                          
                                      LET x = x + 1           
                                      LET pi = pi + 1
                                      LET anz = anz - 1
                                      if x = 1 then
                                          begin work
                                      end if
                                      insert into opstamm_neu    
                                          VALUES (r_ops.*)        
                          
                                      if x = 500000 or anz = 0 then
                                          LET pi0 = true
                                          commit work
                                          display pi,' Sätze geschrieben'
                                          LET x = 0
                                      else
                                          LET pi0 = false
                                      end if
                          
                                  end foreach
                                  close sc_ops
                              end while
                          Versteht nur nicht warum man den Cursor einteilen muss? Hat ein Cursor auch ein limit?

                          Comment


                          • #14
                            Cursor und Commit?

                            Hi,

                            werden Cursor nicht automatisch beim Commit/Rollbak geschlossen, wenn man sie nicht als WITH HOLD deklariert? Wie wäre es, die neue Zieltabelle als "raw" Tabelle anzulegen, und dann den "insert into ... select * from" zu starten?

                            alter table opsstamm_neu type(raw);
                            insert into ...
                            alter table opsstamm_neu type(standard);

                            LG

                            Originally posted by chicky View Post
                            Hallo,

                            also zu guter letzt hat es jetzt geklappt. Mit folgendem Script:
                            Code:
                                while pi != anzahl
                                    if (x = 0 and pi0 = true) or (x != 0 and pi0 = false) then
                                        if pi != 0 then
                                            LET d = i+1
                                        else
                                            LET d = 0
                                        end if
                                            select count(*) into anz FROM opstamm
                                                where ops_ktonr between d and i
                            
                                            while anz = 0 
                                                LET i = i + 10000
                                                select count(*) into anz FROM opstamm
                                                    where ops_ktonr between d and i
                                            end while
                            
                                            declare sc_ops scroll cursor with hold for
                                            select * FROM opstamm
                                                where ops_ktonr between d and i
                                            open sc_ops  
                                    end if
                            
                                    foreach sc_ops into r_ops.*
                            
                                        LET x = x + 1           
                                        LET pi = pi + 1
                                        LET anz = anz - 1
                                        if x = 1 then
                                            begin work
                                        end if
                                        insert into opstamm_neu    
                                            VALUES (r_ops.*)        
                            
                                        if x = 500000 or anz = 0 then
                                            LET pi0 = true
                                            commit work
                                            display pi,' Sätze geschrieben'
                                            LET x = 0
                                        else
                                            LET pi0 = false
                                        end if
                            
                                    end foreach
                                    close sc_ops
                                end while
                            Versteht nur nicht warum man den Cursor einteilen muss? Hat ein Cursor auch ein limit?

                            Comment

                            Working...
                            X