rene1976
Goto Top

SQL 2008 - Tote Spalten in der Tabelle oder in der ganzen DB finden - Wie?

Hallo Gemeinde,

gibt es im SQL 2008 Server eine Möglichkeit auf einen Schlag alle Tabellen mit Spalten zu finden, die schon mal angelegt wurden, aber trotzdem noch nie benutzt wurden (tote, leere Spalten, null oder '').
Nach einer Prüfung würde ich diese gerne entfernen (um wieder die Bäume im Wald zu sehen face-wink)

Hintergrund:
Es wurden Tabellen aus einem anderen System importiert. Nicht alle Tabellen und Spalten werden benötigt.

Am besten wäre es, wenn man ein Abfrage mit folgenden Spalten machen könnte:

Ausgabe:
Tabellenname - Spalten - leerer oder Null Wert


Am besten wäre, wenn man ein Set von Tabellen definieren kann, z.B. alle Tabellen mit Tabellenname like "A%", damit die Abfrage auch irgendwann fertig wird face-wink

Kennt jemand eine Möglichkeit?

P.S.:
Gibt es weiterhin eine Möglichkeit herauszufinden, wann in einer Spalte (allen Spalten) der letzte Datensatz erfaßt wurde?
Das wäre auch ein Indiz für eine veraltete nicht mehr gebrauchte Spalte.


Ausgabe:
Tabellenname - Spalten - Datum letzter Eintrag


Besten Dank.

Rene

Content-Key: 191498

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

Printed on: April 18, 2024 at 02:04 o'clock

Member: Pjordorf
Pjordorf Sep 19, 2012 at 16:52:38 (UTC)
Goto Top
Hallo,

Zitat von @Rene1976:
gibt es im SQL 2008 Server eine Möglichkeit auf einen Schlag alle Tabellen mit Spalten zu finden, die schon mal angelegt wurden, aber trotzdem noch nie benutzt wurden (tote, leere Spalten, null oder '').
Direkt von Haus aus schon? Nein. Warum auch.

Es wurden Tabellen aus einem anderen System importiert. Nicht alle Tabellen und Spalten werden benötigt.
Das ist doch nicht Schuld des SQL Servers, oder?face-smile

Am besten wäre es, wenn man ein Abfrage mit folgenden Spalten machen könnte:
Dann mach es doch.

Am besten wäre, wenn man ein Set von Tabellen definieren kann, z.B. alle Tabellen mit Tabellenname like "A%", damit die Abfrage auch irgendwann fertig wird face-wink
Dann tu es.

Gibt es weiterhin eine Möglichkeit herauszufinden, wann in einer Spalte (allen Spalten) der letzte Datensatz erfaßt wurde?
Ja.

Das wäre auch ein Indiz für eine veraltete nicht mehr gebrauchte Spalte.
Sicher das die dann trotz letzter Änderung vor 90 Jahren nicht gebraucht wird?face-smile

Gruß,
Peter
Member: filippg
filippg Sep 19, 2012 at 18:59:27 (UTC)
Goto Top
Hallo Peter,

super Beitrag!

> Gibt es weiterhin eine Möglichkeit herauszufinden, wann in einer Spalte (allen Spalten) der letzte Datensatz
erfaßt wurde?
Ja.
Das täte mich ja auch interessieren. Hättest du die unendliche Gnade, uns zu erläutern, wie?
(Und jetzt komme bitte nicht mit "man muss einen Trigger anlegen, der dann einen Zeitstempel in eine andere Spalte schreibt").

Zur eigentlichen Frage weiß ich leider auch keine Lösung.
Alle in einer Spalte verwendeten Werte lassen sich realtiv einfach herauskriegen, z.B. einfach mit SELECT DISTINCT Spalte FROM Tabelle.
Um wie viele Spalten & Tabellen handelt es sich denn? Wenn das überschaubar ist, könnte man einfach für jede Spalte eine Abfrage erstellen: SELECT '<Tab>' AS Tabelle '<Spalte>' AS Spalte COUNT(*) FROM <Tab> WHERE <Spalte> NOT IsNull <Spalte> (für Syntax übernehme ich keine Garantie)
Das ganze würde ich z.B. in Excel packen, und <Tab> und <Spalte> durch alle relevanten Tabellen/Spalten ersetzen. Dann noch die Zeilen mit UNION verknüpfen und alle gemeinsam ausführen => Du erhältst eine Tabelle, in der für jede Spalte in jeder Tabelle steht, wie viele nicht-Null-Felder sie enthält. (nicht gleich mit 10.000 Abfragen gegen ein Produktivsystem laufen lassen ist natürlich immer ratsam)

Natürlich wird mich jetzt der eine oder andere steinigen wollen, weil das so unglaublich unelegant ist - aber mir reicht es i.A., wenn es funktioniert...

Gruß

Filipp
Beispiel:
Member: Pjordorf
Pjordorf Sep 19, 2012 at 22:16:48 (UTC)
Goto Top
Hallo,

Zitat von @filippg:
(Und jetzt komme bitte nicht mit "man muss einen Trigger anlegen, der dann einen Zeitstempel in eine andere Spalte schreibt").
jetzt sag nicht du kennst tatsächlich andere Wege? face-smileNatürlich bringt der SQL Server keine Funktion von Haus aus mit welches dies mal eben macht. Warum auch. Das Wissen wann eine Spalte in einer Tabelle einer Datenbank zuletzt geändert wurde ist vermutlich zu 99,9% unwichtig und nur Ballast. Wenn ich also dies wissen will, werde ich nicht umhin kommen mir so eine Information zu schaffen damit ich spätrer daraus zugreifen kann. Möglich ist dies ohne weiteres, aber nicht ohne Aufwand. Ob sinnvoll ist wieder etwqas anderes. Dein Ansatz ist schon ein Lösungsansatz.

Ich habe doch nur die Frage vom TO ob es möglich sei wahrheitsgemäß beantwortetface-smileface-smileface-smile

Gruß,
Peter
Member: Rene1976
Rene1976 Sep 20, 2012 updated at 14:03:56 (UTC)
Goto Top
Hallo,

vielen Dank für die Antworten.
Hier mein erste Teilerfolg:
Damit kann man all Tabellen mit ihren Spalten, Datentypen und Feldlängen auslesen.
SELECT
        Tabellenname=sysobjects.name,
        Spaltenname=syscolumns.name,
        Datentyp=systypes.name,
        Feldlänge=syscolumns.length
FROM
        sysobjects
                JOIN syscolumns ON sysobjects.[id] = syscolumns.[id]
                JOIN systypes ON syscolumns.xtype=systypes.xtype
WHERE
        sysobjects.[xtype]= 'U'  
ORDER BY
        sysobjects.[name],
        syscolumns.colid

Was noch fehlt ist ob in die Spalte jemals schon einmal geschrieben wurde:

Bis jetzt habe ich einzelne Spalten z.B. so überprüft:

select * from Adresse where Telefon <> '' or Telefon is not null

Falls ein Ergebnis herauskam, dann wurde die Spalte schon "irgendwann" einmal benutzt.

Trotzdem weiß ich nicht, wann die Spalte das letzte mal benutzt wurde, bzw. wann in dieser Spalte das letzte Mal ein Wert geändert wurde.

Konkrete Frage:
Protokolliert der SQL Server 2008 in Sys-Tabellen so etwas.
Wenn ja in welchen SysTabelle steht so etwas?
Ich geh mal davon aus das dies nicht der Fall ist.

Was ich such ist eine Metainfo in einer SysTabelle die so lauten müßte: SysColumnLastValueChange
Ich brauche also nur das letzte Datum wann in einer Spalte einmal ein Wert geändert wurde, nicht jedes Änderungsdatum pro Zelle.

Tabellenspalteneigenschaften gibt es hier, allerdings nicht den Wert den ich suche.
http://technet.microsoft.com/de-de/library/ms177173.aspx

Mit der Abfrage "Exec sp_help 'adresse'" bekommt man z.B. auch eine Spalte Created_datetime.
Dies ist zwar nicht das Erstellungsdatum wie der Name einem suggeriert, sondern das letzte Strukturänderungsdatum der Tabelle.

So ein Wert suche ich für die Tabellen-Spalte.
Gibt es so eine Info irgendwo in den SysTabellen?

Grüße,

Rene
[Edit Biber] Codeformatierung. [/Edit]
Member: Rene1976
Rene1976 Sep 20, 2012 at 13:38:46 (UTC)
Goto Top
Hab eine Seite gefunden die sich auch mit dem Thema befasst.

http://stackoverflow.com/questions/63291/sql-select-columns-with-null-v ...

Gruß,

Rene
Member: Biber
Biber Sep 20, 2012 at 18:03:26 (UTC)
Goto Top
Moin Rene1976,

ich denke (ähnlich wie es auch bei Pjordorf annehme), dass die Fragestellung selbst nicht sinnvoll ist.

Eine Spalte ist doch nicht dann "überflüssig", wenn in der gesamten Tabelle für dieses Feld kein Wert "erfasst wurde".
Sondern erst dann, wenn niemand, sei es User oder Applikation, auf dieses Feld zugreifen kann (z.B. über VIEWs geregelt).

Du kannst beispielsweise jahrelang eine Mitarbeiter-Tabelle in deinem System haben mit den Feldern "Verstorben am", "Vorstrafen" und "Sonderbonus gezahlt", in denen auch bei 150, bei 1500 oder 15000 Datensätzen kein einziges dieser Felder gefüllt ist.

Die Denkrichtung kann doch nicht sein, " wenn in einem dieser Felder etwas steht, dann ist das Feld sinnvoll", sondern doch umgekehrt "wenn es ein als sinnvoll identifiziertes Attribut für mein Entity/für meinen Informationsklumpen 'MITARBEITER' gibt, dann muss es erhalten bleiben/angelegt werden."

Da kannst du nicht mit Datenbank-Automatismen rangehen, sondern die fachlich Verantwortlichen müssen sagen "Brauchen wir/brauchen wir nicht".

Gruß
Biber
Member: Rene1976
Rene1976 Sep 20, 2012 at 18:36:31 (UTC)
Goto Top
Hallo Biber,

danke für den Hinweis.
Das ist mir schon klar.

Es geht erst einmal darum solche Felder zu identifizieren.
Dann zu pürfen ob eine Anwendung diese Felder "schon" gebunden hat und ob sie aus fachlicher Sicht gebraucht werden.
Wir wollen natürlich auch nicht das die Anwendung danach "abraucht" weil die Spalten nicht mehr da sind.

Das ganze Verfahren ist mir natürlich klar und ich hab nicht vor blind alle Spalten zu löschen die leer sind.
Ein menschliche Abwägung wird es natürlich bei jedem einzelnen Feld geben.

Aber:
Wir wollen in unserer Applikation für neue Module ein neues Datenmodell einführen.
Hier wollen wir keine alten, überflüssigen Felder "mappen", vor allem keine Felder die redundant sind, z.B. weil es eine alte Telefonspalte in Tabelle A und eine neue Telefonspalte in Tabelle B gibt (DB Design hat sich geändert).

Das führt immer wieder zu Verwirrungen bei neuen Programmieren welche Spalte denn die aktuelle und richtige ist.

Also keine Sorge, wir wissen grundsätzlich schon genau was wir machen wollen.

Das Problenm haben anscheinend auch andere Teams aus dem ein oder anderen Grund.

Hier noch zwei Links:

http://stackoverflow.com/questions/63291/sql-select-columns-with-null-v ...
http://stackoverflow.com/questions/9539084/find-columns-that-contain-on ...

Ich denke, irgendwann wird es Zeit sinnvoll aufzuräumen, solange noch jemand da ist der sich damit auskennt face-wink

Grüße,

Rene
Member: filippg
filippg Sep 20, 2012 at 23:31:34 (UTC)
Goto Top
Hallo Peter,

> (Und jetzt komme bitte nicht mit "man muss einen Trigger anlegen, der dann einen Zeitstempel in eine andere Spalte
schreibt").
jetzt sag nicht du kennst tatsächlich andere Wege? face-smile
Nee, kenne ich nicht - deswegen hat mich das ja auch interessiert. Aber du hast so getan. Die Frage war nämlich nicht "kann ich das irgendwie so einrichten, dass ich das in Zukunft sehe" sondern "kann ich das abfragen"

Natürlich bringt der SQL Server keine Funktion von Haus aus mit
welches dies mal eben macht. Warum auch.
Ja, warum auch? Warum sollten Menschen auf den Mond fliegen wollen? Recht hast du bestimmt mit der Aussage, dass das in den allermeisten Fällen unnötiger Overhead wäre. Deswegen hätte es mich ja auch gewundert.

Ich habe doch nur die Frage vom TO ob es möglich sei wahrheitsgemäß beantwortetface-smileface-smileface-smile
Ja, ganz toll.
Ich denke da immer an die Feuerzangenbowle: "Stellen wir uns ma janz dumm. Wat is ne Dampfmaschine?" Wobei der Schwerpunkt meiner Gedanken natürlich auf dem ersten Satz liegt.

Filipp
Member: MadMax
MadMax Sep 21, 2012 at 11:04:44 (UTC)
Goto Top
Hallo Rene,

die halbe Miete hast Du ja schon mit der Abfrage auf die Systemtabellen. Damit erstellst Du Dir einen Cursor, bastelst Dir Deine Abfrage, wie Du einzelne Spalten überprüfst, in eine nvarchar-Variable zusammen und läßt das ganze als dynamisches SQL laufen (exec sp_executesql). Schon hast Du alle leeren Spalten beisammen.

Gruß, Mad Max