MS Sql Management Studio: Datenimport aus Access.

MysterioJN

SQL-Guru
Beiträge
158
Hallo zusammen. Ich hänge wieder an einer Sache, die ich bisher nicht geschafft habe zu lösen.

Wir haben eine alte AccessDatenbank für all unsere Artikel. In mühseliger Handarbeit habe ich jetz 15 Jahre Daten sinnvoll normalisiert, in Relationen gesetzt und um zahlreiche Tabellen für spätere Funktionen erweitert. Das alles in Access.

Nun hab ich die Daten durch das Management Studio 2012 importiert. Der Export aus Access heraus (upsizing wizard) wurde nach 2010 eingestellt und auf den Sql Importer vom MmStudio verwiesen.

Riesen Problem habe ich aber nach dem Import:

1. Er verwirft mir alle PK und FK. Was aber ok ist, hab es manuell in der neuen SQL Datenbank nachgepflegt. Sprich: erledigt.

2. AutoIncrement werden zwar inhaltliche in die neue Datenbank übernommen, aber nicht als solches hinsichtlich Typ erkannt. Ich kann es auch nicht im Nachgang unter Eigenschafte abändern, sondern müsste eine neue Spalte anlegen. Das bringt mir aber garnichts, da alle Autowerte unverändert!!! genuzt werden müssen, so wie sie von der Accesdatenbank vergeben wurden. Grund ist natürlich die Relationen zwischen den Tabellen da meist der PK auch der Autoincrement 1.1 ist (bzw. Ursprünglich war).

Ich hoffe so sehr, das jemand einen Tip für mich hat. Sonst kann ich meine 7 monatige manuell angelegte Datenbank parallel zum Echtsystem komplett vergessen... :(


3. An welcher Stelle hinterlege ich im Management Studio in den Tabelle, bzw. Entsprechenden Spalten Funktionen für
- Created DateTime
- Created User
- modified DateTime
- modified User
- und z.b. Berechnung und speichern des Nettoverkaufspreises in einer Spalte, an Hand des eingetragenen Bruttowertes in einer anderen Spalte der Tabelle?

In Access is das einfach. Ich glaube im MmStudio auch. Weiß nur noch nicht wo und ggf. wie.

Aber Punkt 2 ist erstmal wichtiger, weil ohne did Autowerte kann ich alles vergessen und mir meine kündigung abholen ;)
 
Zuletzt bearbeitet:
Werbung:
zu 2.)
Es ist eigentlich unmöglich IDENTITY nachträglich einer Tabelle hinzuzufügen wenn schon Daten vorhanden sind. Ich habe das neulich selbst versucht, habe dann aber wegen Problemen davon abgesehen da die Tabelle sowieso migriert wird. Ich habe aber einen sehr aufschlussreichen Artikel gefunden:
SQL SERVER - Add or Remove Identity Property on Column

Es läuft in jedem Fall darauf hinaus die Daten in eine andere Tabelle zu verschieben und dann die original Tabelle neu zu erstellen.

zu 3.)
Ich würde sagen du suchst Default Constraints:
Working with Default Constraints
 
Was bedeutet neu zu erstellen? Die Tabelle neu machen und alle Spalten entsprechend der originalen anlegen? Und wenn ja, wie bekomm ich denn den Inhalt dann in die "neue" Tabelle???
Kann ja keine 100.000 Datensätze manuell anlegen... oh man... ich dreh durch...
 
Der verlinkte Artikel beschreibt genau was zu tun ist. Hier mal in Kurzform:
- Es gibt in SQL Management Studio die Möglichkeit, eine Spalte auf IDENTITY umzustellen (siehe Screenshots im Artikel)
- Management Studio erstellt dann ein Script das alles, was zu tun ist, erledigen soll.
- Der Artikel beschreibt, was das Script tut: Es kopiert die Tabelle + Inhalte in eine Temp-Tabelle, es löscht die Tabelle, es legt sie mit IDENTITY Spalte neu an, kopiert die Daten zurück, löscht die Temp-Tabelle und freut sich.
- Sobald deine Tabelle verzahnt ist durch Dinge wie Constraints scheitert das Script natürlich. Daher muss man es mit hoher Warscheinlichkeit nicht einfach nur anklicken sondern Schritt für Schritt Constraints löschen und später neu anlegen, hier kommt dann Handarbeit ins Spiel.
 
hmm ich muss wirklich ruhiger werden und nicht direkt in Panik verfallen...
... aber zum Glück hab ich euch ;)

Komischer weise hat es jetzt auch im Management Studio geklappt in wie folgt:
- Eigenschaften der Tabelle
- entsprechende Spalte --> Identitätsspezifikation
- "ja" und Startwert NACH dem zuletzt verwendeten Wert. Ich Depp hab es immer auf 1 stehen gehabt.
Und schwupps, es klappt nun ....



@ akretschmar: meckert er dann nicht bzgl. der unterschiedlichen Spaltenanzahl? Die neue Tabelle hat dann schließlich die "neue" Autowert-Spalte mehr als die andere.
Ich bin echt so unerfahren und ängstlich mit SQL.
 
Ok gecheckt. Danke!

Hab ihr einen Linktipp um mit Triggern oder diesen Default Constraints zu arbeiten? Der hier genannte Link ist mir irgendwie zu weit voraus - oder ich einfach zu weit dahinter.

Ziel soll es sein in jeder Tabelle folgende Werte mitzuschreiben:
1. Datum/Zeit WANN die Datenzeile erzeugt wurde
2. Benutzername der die Datenzeile erzeugt hat
3. Datum/Zeit WANN die Datenzeile das letzte Mal verändert wurde
4. Benutzername der die Datenzeile das letzte Mal verändert hat

Die Spalten habe ich bereits überall angelegt und wurden bisher händisch von mir, bzw. mittels Access inhaltlich gepflegt.

In Access hats gut geklappt. After Update und dann GetDate(), GetUser(), etc...

Aber trotz dem Link komme ich nicht klar, wie und wo ich diese "Funktionen" einer BESTEHENDE Tabelle anlege. Ich verstehe echt nicht wo man Trigger anlegen kann im Management Studio.
 
für PG könnt ich es quasi aus dem Ärmel schütteln, aber ich denke, Du bist schon nah dran. Allerdings würde ich eher zu einem BEFORE-Trigger greifen, wenn ich den eingefügten/veränderten Datensatz noch manipulieren will, bevor er gespeichert wird ...
 
CREATE OR ALTER TRIGGER Mitarbeiter_BU1 FOR Mitarbeiter
ACTIVE BEFORE INSERT OR UPDATE POSITION 1
AS
BEGIN
new.Last_User = CURRENT_USER;
new.Last_Change = CURRENT_TIMESTAMP;
END


Einführung in SQL: Trigger – Wikibooks, Sammlung freier Lehr-, Sach- und Fachbücher


Selbst dafür bin ich zu blöd.

Sagen wir mal die Tabelle heißt: tblUmfang

Die zu füllenden Spalten:
- CreatedUser
- CreatedDateTime
- ModifiedUser
- ModifiedDateTime

Hier sind doch dann denke ich zwei Trigger notwendig oder? Einer der bei Anlage der Datenzeile und einer der bei Modifikation der Datenzeile loslegt, richtig?

Wie müsste der denn dann aussehen wenn man nur mal den für Create nimmt?
 
Man kann nicht alles im Management Studio irgendwo durch klicken einstellen, das Studio ist eher dazu gedacht Befehle an die DB abzusetzen und Abfragen zu starten.

Also bei Erfassung / Anlage des Datensatzes kannst du z.B. so folgendes nutzen:
Code:
ALTER TABLE [dbo].[tabelle] ADD CONSTRAINT constrain_name DEFAULT SYSTEM_USER FOR [CreatedUser];
ALTER TABLE [dbo].[tabelle] ADD CONSTRAINT constrain_name DEFAULT getdate() FOR [CreatedDateTime];

Bei Werten wie letzerbenutzer die sich nach Anlage des Datensatzes ändern reicht ein Default Wert natürlich nicht aus. Hier wäre ein Trigger nicht verkehrt, den könnte man auch für beides nutzen:

Code:
CREATE TRIGGER    [dbo].[trigger_name]
    ON            [dbo].[tabelle]
    INSTEAD OF INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO tabelle(pk,spalte1,spalte2,CreatedUser,CreatedDateTime)
    SELECT    i.pk,
            i.spalte1,
            i.spalte2,
            SYSTEM_USER AS CreatedUser,
            getdate() AS CreatedDateTime
    FROM    INSERTED i
    LEFT JOIN DELETED d
    ON        i.pk = d.pk
    WHERE    d.pk IS NULL

    UPDATE    tabelle
    SET        tabelle.pk = i.pk,
            tabelle.spalte1 = i.spalte1,
            tabelle.spalte2 = i.spalte2,
            tabelle.CreatedUser = i.CreatedUser,
            tabelle.CreatedDateTime = i.CreatedDateTime,
            tabelle.ModifiedUser = SYSTEM_USER,
            tabelle.ModifiedDateTime = getdate()
    FROM    tabelle
    INNER JOIN INSERTED i
    ON        tabelle.pk = i.pk
    INNER JOIN DELETED d
    ON        tabelle.pk = d.pk
END;
Instead of-Trigger wäre die saubere Lösung, Nachteil ist das du beim Anpassen der Tabelle auch immer den Trigger anpassen musst denn er aktualisiert neue Spalten sonst nicht.
 
Krass. Du bist toll! Glaub ich versteh so langsam das Prinzip. Bei "spalte 1" oder "Spalte 2" gehört der Name der Spalte 1 bzw. Spalte 2 meiner Tabelle rein oder? Entschuldige wenn ich so doof nachfrage :-/


Hab jetzt erst Mal die "einfache" Variante versucht und erfolgt gehabt:

ALTERTABLE tblUmfang ADD CONSTRAINT CreateDT DEFAULT getdate()
FOR tblUmfang_CreatedDT;

Kann man im Nachgang auch sehen, das Constraints aktiv sind/vorhanden sind? Wenn ich diese z.B. wieder löschen möchte?

Edit: Geht statt Datenbanknutzer auch der Windows/Domänennutzer? Problem ist die Anbindung an die Datenbank läuft über root bzw. sa. Der Benutzer arbeitet Zukünftig aber im Front End mit seinem Namen - lediglich die Verbindung geht auf die Datenbank mit "sa".
Hintergrund ist der Wegfall einer weiteren Benutzerverwaltung/Rollenvergabe auf dem Server.
 
Zuletzt bearbeitet:
Spalte1, 2 und so weiter sind alle Spalten deiner Tabelle. Fehlen die, werden die Daten von einem Instead-of-Trigger nicht in die Tabelle geschrieben.

Im Management Studio siehst du alle Tabellen und auch recht bequem alle Constraints dazu (Einschränkungen und Schlüssel) oder Trigger. Trigger kannst du deaktivieren, Constraints gelten immer sobald sie bestehen und können nicht verletzt werden.

Du kannst einer Domänenbenutzergruppe Rechte auf der DB geben, dann kannst du die Windows-Benutzeranmeldung einfach an die DB weiterreichen. Wenn deine Aplikation sich mit einem User an der DB anmeldet hat die DB keine Möglichkeit zu sehen, von wem etwas ausgeführt wird. Dann muss die Aplikation diesen Wert in die Spalte eintragen.
 
Werbung:
Super. Danke Ukulele! Auch das mit der Benutzerverwaltung hast du mir extrem erleichtert. So werden wir es machen. Unser AD wird derzeit eh neu strukturiert, da kann man das gleich mit bedenken.
Bisher hantieren wir immer noch mit Benutzer, Schemas und Rollen rum. Zudem die Dopplung im ActiveDirectory und im Front-End. Das ist quatsch und wird geändert.

Herzlichsten Dank für Deine/Eure Hilfe! Bin froh hier angemeldet zu sein!!!
 
Zurück
Oben