Discussion:
IDENTITY_INSERT - Daten mit Identitätsspalten Importieren
(zu alt für eine Antwort)
Thomas Schulz
2005-11-19 16:43:35 UTC
Permalink
Moin,

ich möchte für ein neues .NET-Projekt, bei dem ich den SQL-Server 2000 als Datenbank verwende, Daten einer früheren
ACCESS-Implementierung dieser Applikation weiterverwenden. Komfortablerweise soll der Import programmgesteuert aus einem
Updater-Modul der Anwendung geschehen.
Ich scheitere momentan an der Umsetzung des Imports von Daten aus Tabellen mit Identitätsspalten.
Natürlich benötige ich die ursprünglichen ID's.
Bisher - 'händisch' - verwende ich folgende Strategie:
- Import aus ACCESS per Enterprise Manager über Variante 'Abfrage'. (Dabei werden keinen Identitätseigenschaften erzeugt)
- Nachträgliches Setzen der Identitätseigenschaft mit dem Manager
Nun möchte ich das gerne per Code bewerkstelligen.

Mein erstes Problem, hier aber nur nebenher thematisiert:

Gerne würde ich eine INSERT INTO Konstruktion anwenden, mir ist aber nicht klar, wie ich das über zwei unterschiedliche Connections
hin (SQL-Server/ACCESS) durchführen kann.
Bliebe ja noch die Variante, ein Dataset als Puffer zwischenzuschalten und nach dem Füllen aus ACCESS notfalls auch zeilenweise an
die SQL-Server-Tabellen auszugeben.

Aber spätestens hier kommt mein zweites und ernsthaftes Problem:

Wie schaffe ich es bei dieser Konstellation, die Original-ID's in die 'frischen' SQL-Server-Tabellen mit Identity-Spalten zu
bekommen?
Meine erste Idee: Setzen der Identity-Eigenschaft erst nach dem INSERT
Da scheint es aber keine T-SQL-Syntax für zu geben... ??
Zweite Variante: Anwenden von SET IDENTITY_INSERT 'meineTabelle' ON vor dem Import
Das scheint aber schon beim Simulieren mit dem QUERY-Analyser nicht zu funktionieren.
Der INSERT-Aufruf schlägt wegen Verletzuung der Identity-Bedingung fehl.
Außerdem weiß ich nicht, ob SET Statements überhaupt über die .ExecuteNonQuery() Methode ausgeführt werden können.
Und möglicherweise bekomme ich da auch noch Rechte-Probleme auf dem SQL-Server...

Irgendwie muss es der Enterprise Manager ja aber auch können, denn damit geht's ja.
Wie macht der das bloß?

Für guten Rat bedankt sich

Thomas Schulz
Elmar Boye
2005-11-19 19:10:25 UTC
Permalink
Hallo Thomas,
Post by Thomas Schulz
ich möchte für ein neues .NET-Projekt, bei dem ich den SQL-Server
2000 als Datenbank verwende, Daten einer früheren
ACCESS-Implementierung dieser Applikation weiterverwenden.
Komfortablerweise soll der Import programmgesteuert aus einem
Updater-Modul der Anwendung geschehen.
Ich scheitere momentan an der Umsetzung des Imports von Daten aus
Tabellen mit Identitätsspalten.
Natürlich benötige ich die ursprünglichen ID's.
- Import aus ACCESS per Enterprise Manager über Variante 'Abfrage'.
(Dabei werden keinen Identitätseigenschaften erzeugt)
- Nachträgliches Setzen der Identitätseigenschaft mit dem Manager
Nun möchte ich das gerne per Code bewerkstelligen.
Einfachste Lösung hier:

- SQL Server Tabelle gleich mit IDENTITY Spalte

- SET IDENTITY_INSERT dbo.Tabelle ON
- INSERT Befehl absetzen wie in
http://groups.google.de/group/microsoft.public.de.sqlserver/msg/157ec3dc23a13445
- SET IDENTITY_INSERT dbo.Tabelle OFF

dabei muss die gleiche Verbindung verwendet werden.

Eine Aalternative wäre ein DTS Paket, bei der Datenpumpe gibts
auch eine IDENTITY_INSERT Option.
Post by Thomas Schulz
Der INSERT-Aufruf schlägt wegen Verletzuung der Identity-Bedingung fehl.
Deine Daten müssen dabei sauber sein. Ohne PK kann in Access
(wie beim SQL Server) schnell mal was doppeltes eingefügt werden.

Gruss
Elmar
Thomas Schulz
2005-11-19 19:29:10 UTC
Permalink
Hallo Elmar,
Post by Elmar Boye
- SQL Server Tabelle gleich mit IDENTITY Spalte
OK, kein Problem
Post by Elmar Boye
- SET IDENTITY_INSERT dbo.Tabelle ON
Wie kann ich das aus meinem .NET Code absetzen?
Geht das per .ExecuteNonQuery() Methode über die SQL-Connection?
Post by Elmar Boye
- INSERT Befehl absetzen wie in
http://groups.google.de/group/microsoft.public.de.sqlserver/msg/157ec3dc23a13445
Muss ich das über die JET-Connection an die ACCESS-DB absetzen?
Auch per .ExecuteNonQuery() Methode ?
(wie gesagt, ich will das alles aus dem Code handeln)

Oder gehts auch andersherum, indem per T-SQL auf dem SQL-Server auf die Tabellen der ACCESS-DB zugreife?
Das wäre mir sympathischer.
Post by Elmar Boye
- SET IDENTITY_INSERT dbo.Tabelle OFF
dabei muss die gleiche Verbindung verwendet werden.
(also die SQL-Connection...)
Post by Elmar Boye
Post by Thomas Schulz
Der INSERT-Aufruf schlägt wegen Verletzuung der Identity-Bedingung fehl.
Deine Daten müssen dabei sauber sein. Ohne PK kann in Access
(wie beim SQL Server) schnell mal was doppeltes eingefügt werden.
Nee Nee, ohne PK ging's ja, aber mit PK und der SET IDENTITY_INSERT ... ON ging's im QUERY Analyzer schief.

Vielleicht noch mal 2 Hilfstellungen?

Schönen Samstag Abend, trotzdem!

Gruß,

Thomas Schulz
Elmar Boye
2005-11-20 09:47:43 UTC
Permalink
Hallo Thomas,
Post by Thomas Schulz
Post by Elmar Boye
- SET IDENTITY_INSERT dbo.Tabelle ON
Wie kann ich das aus meinem .NET Code absetzen?
Geht das per .ExecuteNonQuery() Methode über die SQL-Connection?
Mit dem OleDb Client (OleDbCommand) gar nicht, da Du dort keine
CommandProperties setzen kannst, was der Jet OleDb Treiber
erfordern würde.

Der Vollständigkeit halber: Ein VB(A) Schnippsel für ADODB wäre
Set cmdJet = New ADODB.Command
With cmdJet
.ActiveConnection = cnnJet
.CommandType = adCmdText
.CommandText = "SET IDENTITY_INSERT dbo.Tabelle ON"
.Properties("Jet OLEDB:ODBC Pass-Through Statement") = True
.Properties("Jet OLEDB:Pass Through Query Connect String") = _
"ODBC;DSN=EBBASIS;DATABASE=EBBASIS;UID=;PWD=;"
End With

oder auch für DAO:
http://groups.google.de/group/microsoft.public.de.sqlserver/msg/835a0d202f22e664
Post by Thomas Schulz
Oder gehts auch andersherum, indem per T-SQL auf dem SQL-Server auf
die Tabellen der ACCESS-DB zugreife? Das wäre mir sympathischer.
Prinzipiell auch:
http://support.microsoft.com/?kbid=321686
HOW TO: Import Data into SQL Server from Excel

Und ersetze dort Excel durch MDB - ist sowieso alles der Jet
Treiber.

Beachte das für einige Methoden der direkte Zugriff erlaubt
werden muss: http://support.microsoft.com/?kbid=327489
HOW TO: Use the DisallowAdHocAccess Setting to Control Access
to Linked Servers

Aus Sicherheitsgründen sollte das keine Dauereinstellung sein.
Die MDB sollte dann auf dem Server liegen.
Post by Thomas Schulz
Post by Elmar Boye
Post by Thomas Schulz
Der INSERT-Aufruf schlägt wegen Verletzuung der Identity-Bedingung fehl.
Deine Daten müssen dabei sauber sein. Ohne PK kann in Access
(wie beim SQL Server) schnell mal was doppeltes eingefügt werden.
Nee Nee, ohne PK ging's ja, aber mit PK und der SET IDENTITY_INSERT
... ON ging's im QUERY Analyzer schief.
Dann hast Du duplizierte Werte in der Autowertspalte der
Ausgangs Daten - das ist in Access ohne PK ebenso möglich.

Gruss
Elmar
Thomas Schulz
2005-11-21 10:39:20 UTC
Permalink
Hallo Elmar,
Post by Elmar Boye
Oder gehts auch andersherum, indem ich per T-SQL auf dem SQL-Server auf
die Tabellen der ACCESS-DB zugreife? Das wäre mir sympathischer.
http://support.microsoft.com/?kbid=321686
HOW TO: Import Data into SQL Server from Excel
Dieser Link half mir weiter, insbesondere die Variante mit OPENROWSET
Das hier konnte ich (unterstützt durch die SQL-Server-Doku) daraus machen:

-- Kopieren einer ACCESS-Tabelle kunden in bestehende
-- SQL-Server-Tabelle tblkunden
-- Übernahme der korrekten ID's in Identitätsspalte
-- (Spalten gekürzt...)

SET IDENTITY_INSERT dbo.tblkunden ON

INSERT INTO dbo.tblkunden
(kunden_id, kundenname)
SELECT
kunden_id, kundenname
FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'F:\ACCESS-Projekt\KUNDEN.MDB';
'admin';'',
'SELECT kunden.kunden_id, kunden.kundenname
FROM kunden')

SET IDENTITY_INSERT dbo.tblkunden OFF

Schönen Dank u. schöne Woche,

Thomas Schulz

Loading...