primaryKey über mehrere Spalten

Hallo,

ich suche für meine Aufgabe Tipps, ratschläge wie ich an die folgende Problematik am besten rangehen soll/kann:
Also ich habe eine Access-Datei. Die ersten drei Spalten sollen den "Primarykey" darstellen. Wenn ich diesen über den Code zusammenstellen will, wird die Fehlermeldung "diese Spalten haben momentan keine eindeutigen Werte" ausgegeben. (Die Datensätze wird in einem DataGridView dargestellt über ein DataTable, Dataset). Die Daten werden trotz Fehlermeldung geladen und dargestellt.
Also die erste Spalte beinhaltet Zahlen, die 2te Text und die Dritte auch wieder eine Zahl(laufende Nummer). Nun suche ich auf jeden Fall nach einer Lösung wie ich den Inhalt der dritten Spalte automatisch in Bezug zu den anderen 2 "berechnen" lassen kann(man müsste die 3te Spalte nach der höchsten Zahl durchsuchen, 1 dazuzählen, und natürlich noch die beiden anderen Spalten berücksichtigen-> nur wie mach ich das am besten? Weil das DataGridView die Daten nicht unbedingt sortiert darstellt)
Hat jemand einen Tipp oder kleinen Vorschlag?
 
Hallo Sarah,

zunächst einmal verstehe ich nicht alles so genau was du da schreibst.

Du möchtest einen PK über 3 Felder einer Access DB erstellen.
Wenn ich das richtig verstanden habe soll das ganze per Code passieren.
Wie sind diese 3 Felder genau in der DB angelegt ?
Kannst du den PK über die 3 Felder mittels Access anlegen ?

Wenn nicht gibt es entweder Einträge mit NULL wo kein NULL
sein darf oder es gibt doppelte gleiche Einträge in den 3 Feldern.
Die Inhalte eines PK müssen eindeutig sein.

Um die 3. Spalte mit der laufenden Nummer zu erhöhen beim Hinzufügen
von neuen Datensätzen gibt es mehere Möglichkeiten.

1. Das Feld in Access oder per Code auf AutoWert zu stellen
(dann wird dieses Feld automatisch immer um eins erhöht)
2. Oder selber im Code per SQL die höchste Zahl ermitteln, 1
dazu addieren und als Standardwert zu setzen.


Ohne den Code genauer zu kennen und mehr Infos kann man
hier nicht viel mehr dazu sagen.

Gruß
Jens
 
Die 3Spalten sind noch nicht als Primarykey in Access angelegt- dachte man kann nur einer Spalte diesen "Wert" zuweisen..werde ich aber morgen auf Arbeit mal schauen..
Na aus diesen 3Spalten soll eine eindeutige ID erstellt werden:(es gibt eine überschaubare Anzahl an Datensätzen)
08 KK 01
usw..
2. Oder selber im Code per SQL die höchste Zahl ermitteln, 1
dazu addieren und als Standardwert zu setzen.
Ok, danke für den Hinweis, werde ich auch mal nachschauen wie man das am besten implementiert..Kannst du mir aber evtl. noch einen Ratschlag hierfür geben?
 
Hallo Sarah,

natürlich kann man auch nur einem Feld den PK zuweisen. Wenn das Feld 3 mit der laufenden Nummer eindeutig ist bietet sich das an.
Wobei ich aus Sicherheitsgründen gerne GUID's dazu nehme, da diese im Prinzip
Rechnerübergreifend eindeutig sind.

Bei Bedarf kann ich gerne ein Bsp. zeigen wie man programmgesteuert das Feld
laufende Nummer um 1 erhöht.

Das wäre aber wesentlich leichter bzw. mit weniger Nacharbeit verbunden, wenn
man ewtas Code von dir sieht wie du bspw. Daten hinzufügst.
Denn es gibt viele Wege um Datensätze in eine Access mdb einzufügen.
Und meine wahrsagende Kristallkugel funktioniert gerade nicht :)

Gruß
Jens
 
natürlich kann man auch nur einem Feld den PK zuweisen
Naja mein "PrimaryKey-Feld" verläuft ja über 3Spalten, also muss ich mir ne andre Lösung suchen..
Momentan arbeite ich mit OleDBCommands und Dataset bzw. DataTable (gebundenes DataGridView).
Wobei bei mir der UpdateCommand bei neueingefügten Datensätzen die Daten nicht in die mdb-Anwendung übernimmt. Habe es mit CommandBuilder (übernimmt nur die ID-Spalte die ich jetzt erstmal hinzugefügt habe)und mit manuellem Setzen des Updatestrings probiert(speichert gar nichts)- funktioniert beides nicht so..naja eigentlich ist das ja auch wieder ein neues Thema..ich werd morgen mal einen Schnipsel Code zeigen.
Danke dir für die Hilfe!
 
Hallo Sarah,

zeige mal von beiden nicht funktionierenden Varianten den relavanten Code.
Dann werden wir den Fehler auch finden.

Und warum (was an sich kein Problem ist) einen PK über alle 2 Felder ?
Kannst du die mdb mal gezippt mit anhängen, wenn sie noch nicht zu groß
ist ?

Gruß
Jens
 
Also hier mein einer Code:
Code:
myDataAdapter.InsertCommand = conn.CreateCommand();
            myDataAdapter.InsertCommand.CommandText = "INSERT INTO [Projektnummer]  ( [Jahr],[Kundenkürzel],[lfdNummer],[Projektbezeichnung],[Status],[Vergabedatum],[PL],[AG] ,[PLAG],[Vorgang],[Sammelprojekt],[LinkelektrPO],[AnhangBemerkung])" +
    "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";"SELECT [ID] = SCOPE_IDENTITY()";

            myDataAdapter.InsertCommand.Parameters.AddWithValue("@Jahr", dataGridView1.Rows[row1].Cells[1].Value);
            myDataAdapter.InsertCommand.Parameters.AddWithValue("@Kundenkürzel", (string)dataGridView1.Rows[row1].Cells[2].Value);
usw..

 int ins = myDataAdapter.InsertCommand.ExecuteNonQuery();

            myDataAdapter.UpdateCommand = conn.CreateCommand();
            myDataAdapter.UpdateCommand.CommandText = "UPDATE [Projektnummer] SET     [Jahr]= ?,  [Kundenkürzel]=? ,  [lfdNummer]  =? , [Projektbezeichnung]= ?, [Status]=?, [Vergabedatum] = ?, [PL]=? , [AG]=?,  [PLAG]= ?,  [Vorgang]=?,  [Sammelprojekt]= ?,  [LinkelektrPO]=? , [AnhangBemerkung]=?  WHERE [ID]=?";
            foreach (DataRow row in table.Rows)
            {
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    if (row[i] is DBNull)
                    {
                        if (table.Columns[i].DataType == typeof(int))
                            row[i] = (int)0;
                        else if (table.Columns[i].DataType == typeof(short))
                            row[i] = (short)0;
                        else if (table.Columns[i].DataType == typeof(string))
                            row[i] = "";
                        else if (table.Columns[i].DataType == typeof(decimal))
                            row[i] = (decimal)0;
                        else if (table.Columns[i].DataType == typeof(double))
                            row[i] = (double)0;
                        else if (table.Columns[i].DataType == typeof(DateTime))
                            row[i] = new DateTime();
                        else row[i] = null;
                    }
                }
            }

            myDataAdapter.UpdateCommand.Parameters.AddWithValue("@Jahr", (string)dataGridView1.Rows[row1].Cells[1].Value);
            myDataAdapter.UpdateCommand.Parameters.AddWithValue("@Kundenkürzel", (string)dataGridView1.Rows[row1].Cells[2].Value);
usw..

  int upd2 = myDataAdapter.UpdateCommand.ExecuteNonQuery();


            dataGridView1.EndEdit();
Hier mein anderer:(hier speichert er mir nur die ID´s)
Code:
OleDbCommandBuilder update = new OleDbCommandBuilder(myDataAdapter);
            myDataAdapter.UpdateCommand = update.GetUpdateCommand();

            OleDbCommandBuilder insertcommand = new OleDbCommandBuilder(myDataAdapter);
            myDataAdapter.InsertCommand = insertcommand.GetInsertCommand();

habe schon rausgefunden dass Access anscheinend keine 2Strings im Command nimmt. Nun wie soll ich aber am besten die ID generieren lassen für den DataTable(Access macht das ja automatsich da die Spalte Autoinkrement ist)..

Naja ich möchte auf jeden Fall dass sich die dritte Spalte meines "PK" automatisch berechnen lässt(mal unabhängig von meinem ID-Wert, der ist ja für das update, etc schon sinnvoll(also wenn ich das mit meinem eigenen PK über 3Spalten nicht hinbekommen sollte)); aber wahrscheinlich muss ich hierfür einfach einen Algorithmus finden a la "suche größte Zahl von Spalte 3(wobei die ja an sich schon mehrmals auftauchen kann, weil es eben nur ein TEIL der "ID"/PK ist), schaue in Spalte 1 und 2, setze das in Verbindung und gib die neue Zahl für Spalte 3 aus"..nur wie
 
Hallo Sarah,

ich werde mal ein Bspw. posten wo beides funktioniert.
Dauert aber bischen.

Kannst du nicht ma die Access mdb als File hier anhängen ?

Oder zummindest nochmal den genauen Aufbau posten ?
Damit ich auch zum testen die einzelnen Datentypen kenne.

Gruß
Jens
 
Eine Frage noch, da ich nicht den ganzen Code kenne.

Wie gibst du die neuen Daten ein ? Wie es aussieht direkt im DataGridview oder
gibt es da noch Textboxen ?
Wenn du die Daten direkt im DataGridview hinzufügst ist der ganze Ansatz von dir
falsch. Später mehr dazu.
Eins ist mir sofort aufgefallen.
SELECT [ID] = SCOPE_IDENTITY()";
ist typisch für einen SQL Server, hat aber nix mit Access zu tun und funktioniert
da auch nicht.

Muss das Bspw. in C# sein (geht auch) oder darf es VB.NET sein ?

Gruß
Jens
 
Also ich fülle die Daten über eine 2te Form in das DGV(das klappt auch), und will die Daten über einen SpeicherButton speichern.
Die MDB-datei besteht aus 14Spalten(inkl. ID),
Datentypen sind folgende:
Autowert, 5mal Text, 1mal Datum/Uhrzeit, 3mal Text, 1mal Zahl, 3mal Text.

Wenn du die Daten direkt im DataGridview hinzufügst ist der ganze Ansatz von dir
falsch.
wenn ich das speichern über die DataTable anspreche sagt er mir dass in dieser Zeile kein Wert vorhanden ist(wegen dem * am Anfang der zeile( ist noch im Bearbeitungszustand; deshalb hab ich auch mit Focus() versucht das zu umgehen(hab das mal in nem andren Post gelesen))..wobei ich es noch nicht probiert habe nach dem Insert anstatt über dataGridView1.Row.. über table.Row.. zu gehen..oder lieg ich hiermit auch falsch

SELECT [ID] = SCOPE_IDENTITY()";
ist typisch für einen SQL Server, hat aber nix mit Access zu tun
Na das wusste ich auch nochnicht..wieder was gelernt:)

Na VB kanns auch sein, so bißchn versteh ichs ja schon;-) (und wenn nicht kann ich dich bestimmt/hoffentlich dazu fragen)

Danke für deine Hilfe!
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück