d4shoernchen
Goto Top

Hilfe bei MSSQL-Anweisung, Werte in andere Tabelle einfügen

Guten Morgen,

ich bräuchte einmal Eure Hilfe in Bezug auf MSSQL.

Und zwar habe ich eine Tabelle Namens "[meineDB].[dbo].[tdAddresses]" und eine Namens "[meineDB].[dbo].[tdAddressNotes]".

In Tabelle "[meineDB].[dbo].[tdAddresses]" gibt es die Spalten "[AddressID], [MemoText]" und in der Tabelle "[meineDB].[dbo].[tdAddressNotes]" folgende "[NoteID], [AddressID], [NoteDesc], [NoteText], [CreationDate], [CreationUser], [ChangeDate], [ChangeUser]".

Folgendes Szenario:
Die Memotexte aus der Tabelle "tdAddresses" müssen in die Spalte "NoteText" von der Tabelle "tdAddressNotes". Die MemoTexte sind aber nicht bei allen Datensätzen verfügbar, er müsste also einfach schauen wo welche sind. Die Spalte "AddressID" ist in beiden Tabellen identisch.

Die Spalte "NoteID" ist eine fortlaufende Nummer und müsste bei 60 losgehen. Bei "NoteDesc" sollte bei den neuen Werten immer der Begriff "Memotext" drin stehen. Creationdate kann das aktuelle Tagesdatum sein "2017-04-03 00:00:00.000". Bei "CreationUser" sollte immer "I.001" drin stehen. In die Spalten "ChangeDate" und "ChangeUser" ruhig das gleiche wie bei "Creation*".

Habt ihr eine Idee?

Prinzipiell hätte ich mir eigentlich die Tabelle "tdAddresses" als .csv-Datei exportiert. Allerdings gibt es hier Probleme bei dem "MemoText", da dort Absätze etc. integriert sind und die Memotexte teilweise sehr lang. Dementsprechend ist keine Zuordnung zur "AddressID" mehr vorhanden. Da es sich um ca. ~ 4.000 Datensätze handelt, wäre eine Überarbeitung der .csv-Datei sehr zeitaufwändig.

Besten Dank face-smile

Gruß

Content-ID: 333966

Url: https://administrator.de/contentid/333966

Ausgedruckt am: 22.11.2024 um 02:11 Uhr

sabines
sabines 03.04.2017 aktualisiert um 10:41:47 Uhr
Goto Top
Moin,

und wo ist da jetzt das Problem?
Achte darauf, dass NoteText und MemoText vom gleichen Datentyp sind und lass einen Update Befehl über die Tabelle laufen.
Bspw. mit where tdAddresses.AddressID = tdAddressNotes.AddressID oder mit einem join.

Am einfachsten testest Du sowas mit einem einfachen Select, wenn das Ergebnis so ist, wie Du es erwartest, kannst Du ein Update Befehl daraus bauen.

Entweder ich übersehe was bei der Frage oder Du hat wenig SQL Kenntnisse face-wink

Gruss
d4shoerncheN
d4shoerncheN 03.04.2017 aktualisiert um 10:15:00 Uhr
Goto Top
Hallo sabines,

soweit mir bekannt, überschreibt der UPDATE-Befehl aber nur bestehende Datensätze. Da diese aber neu eingefügt werden müssten, bräuchte man hier schon einen INSERT Befehl.

Nun soll er ja nicht alle Datensätze dort eintragen, sondern nur die, wo auch ein MemoText eingetragen wurde. Neben einer Variable (in dem Fall MemoText) müssen dann noch fünf feste Werte eingetragen werden und eine fortlaufende Zahl.

Hier mal ein kleines Beispiel:

[meineDB].[dbo].[tdAddresses]

AddressID MemoText
56565NULL
32543Ein Text
35543Noch ein Text
79854NULL
75568Letzter Text

[meineDB].[dbo].[tdAddressNotes] (vor dem Befehl)
NoteID AddressID NoteDesc NoteText CreationDate CreationUser ChangeDate ChangeDate
112344Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002
285844Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002
378894Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002

[meineDB].[dbo].[tdAddressNotes] (nach dem Befehl)
NoteID AddressID NoteDesc NoteText CreationDate CreationUser ChangeDate ChangeDate
112344Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002
285844Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002
378894Alte BeschreibungAlterText2016-04-03 00:00:00.000U.0022016-04-03 00:00:00.000U.002
432543MemoTextEin Text2017-04-03 00:00:00.000I.0012017-04-03 00:00:00.000I.001
535543MemoTextNoch ein Text2017-04-03 00:00:00.000I.0012017-04-03 00:00:00.000I.001
675568MemoTextLetzter Text2017-04-03 00:00:00.000I.0012017-04-03 00:00:00.000I.001
Werte 1-3 sind alte, Werte 4-6 die neuen.

Gruß
sabines
sabines 03.04.2017 aktualisiert um 10:47:15 Uhr
Goto Top
Ach so.

Dann mach' doch zuerst ein Update where tdAddresses.AddressID = tdAddressNotes.AddressID und danach ein insert.
Hier selektierst Du dann nur die Daten, die keine Übereinstimmung haben, per join oder Subselect, where tdAddresses.AddressID not in select tdAddressNotes.AddressID from tdAddressNotes, oder andersrum, hab's jetzt nicht noch mal gelesen.

Und die festen Werte kannst Du ja auch fest per Update oder Insert übergeben.
Und in die where clause kannst Du auch nur Datensätze erfassen, die einen Inhalt im Memofeld haben, bspw. where memofeld not Null oder entsprechend (0 etc.).

Sicher die Tabellen vorher und teste das per Select, erst danach updaten/inserten.

Gruss
ukulele-7
Lösung ukulele-7 03.04.2017 um 11:44:32 Uhr
Goto Top
Also mit der AdressID solltest du aufpassen, es kann sein das die durch die DB automatisch vergeben wird (also im INSERT Statement gar nicht angegeben werden darf) oder das sie von der Anwendung anderweitig in einer Tabelle dokumentiert wird (damit die Anwendung sie selbst vergeben kann und weiß, welcher Wert der höchste ist). Das solltest du vorher testen.

MemoText und NoteText haben hoffentlich den selben Datentypen.

Außerdem kannst du zunächst mal nur den Select ausführen und kontrollieren, ob das das ist was du suchst.
INSERT INTO [meineDB].[dbo].[tdAddressNotes]([NoteID], [AddressID], [NoteDesc], [NoteText], [CreationDate], [CreationUser], [ChangeDate], [ChangeUser])
SELECT	60 + ROW_NUMBER() OVER (ORDER BY a.[AddressID]),
		a.[AddressID],
		'Memotext',  
		a.[MemoText],
		cast(cast(getdate() AS DATE) AS DATETIME),
		'I.001',  
		cast(cast(getdate() AS DATE) AS DATETIME),
		'I.001'  
FROM	[meineDB].[dbo].[tdAddresses] a
LEFT JOIN [meineDB].[dbo].[tdAddressNotes] n
ON		a.[AddressID] = n.[AddressID]
WHERE	n.[AddressID] IS NULL
d4shoerncheN
d4shoerncheN 03.04.2017 aktualisiert um 12:54:39 Uhr
Goto Top
Hallo @ukulele-7,

besten Dank. Damit hat's geklappt.

Einzig die Where-Anweisung habe ich auf "WHERE a.[MemoText] IS NOT NULL" geändert.

Die AddressID wird automatisch vergeben, dass ist richtig. Allerdings in der Tabelle "tdAddresses", bei der "tdAddressesNotes" verweisen wir nur noch auf diese ID.

Viele Grüße
ukulele-7
ukulele-7 03.04.2017 um 13:30:19 Uhr
Goto Top
IS NOT NULL ergibt aber keinen Sinn, das müsste überall dort zutreffen wo schon ein Eintrag in tdAddressNotes existiert.
d4shoerncheN
d4shoerncheN 03.04.2017 um 13:34:18 Uhr
Goto Top
Moin,

IS NOT NULL ergibt aber keinen Sinn, das müsste überall dort zutreffen wo schon ein Eintrag in tdAddressNotes existiert.
wieso?

Ich habe ja "WHERE a.[MemoText] IS NOT NULL". a ist ja die Tabelle "[meineDB].[dbo].[tdAddresses]". Sprich er nimmt alle Datensätze der Tabelle, wo etwas in das "MemoText"-Feld eingetragen ist. Diese Werte überträgt er dann in die [meineDB].[dbo].[tdAddressesNotes] und erstellt neue Notizen.

Oder habe ich einen Denkfehler?

Viele Grüße
ukulele-7
ukulele-7 03.04.2017 um 13:48:16 Uhr
Goto Top
Der Left Join holt alle Datensätze der Haupttabelle und dort, wo es einen Datensatz in der "Untertabelle" gibt, fügt er diese Informationen an. Dort wo es in der Untertabelle keinen Datensatz gibt, sind alle Felder in diesen Spalten NULL. Ich hab angenommen du willst nur dort Datensätze einfügen, wo es noch keine gibt.

Man kann das ganze auch noch anders schreiben aber eigentlich dürfte in deinem Beispiel die Werte 1-3 doppelt sein und 4-6 immer noch fehlen.