Announcement

Collapse
No announcement yet.

View Spalten verrutschen bei Tabellenänderung (TSQL)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • View Spalten verrutschen bei Tabellenänderung (TSQL)

    Ich habe folgendes Phänomen festgestellt:

    Wenn ich eine View aus zwei Tabellen erzeuge in diesem Format:

    SELECT T1.*, T2.*
    FROM T1
    INNER JOIN T2
    ON T1.ID = T2.ID

    Und dann in der Tabelle T1 eine neue Spalte hinzufügen. Dann sind plötzlich in der View alle Spalten verschoben, das heißt die neue Spalte wird in den Inhalt von der ersten Spalte von T2 gefüllt.

    Man kann das Problem leicht beheben indem man einfach "ALTER VIEW" aufruft (ohne etwas zu verändern). Danach sind die Spalten richtig.

    Meine Frage wäre nur: Kann man irgendetwas einstellen, dass die VIEW automatisch aktualisiert wird, wenn sich Tabelle T1 ändert?

  • #2
    Keine Antwort auf Deine Frage, aber vielleicht hilfreich. Du kannst den View mit expliziten Feldnamen definieren und "Schemabinding" einbauen. Dann bleibt der View zumindest konsistent.
    (Solange lediglich Spalten in den Basistabellen hinzugefügt werden natürlich)
    Code:
    CREATE VIEW anyView
    WITH SCHEMABINDING
    AS
    SELECT...
    Ich bin kein MSSQL Spezi, aber vielleicht kann man dieses Verfahren nutzen, um konsistente / inkonsistente Views via information schema / dictionary (heraus)zu finden.
    Gruß, defo

    Comment


    • #3
      Ich würde mich eher fragen ob das Design grundsätzlich nicht fragwürdig ist. Nach meiner Definition haben * rein gar nix in einem View zu suchen genauso wenig wie Schemaänderungen als normaler Vorgang zur Laufzeit einer Anwendung.

      Nichts desto trotz schau dir mal die sp_refreshview Stored Proc an. Insbesondere das letzte Codebeispiel um eine Aktualisierung abhängiger Views selbst auszulösen.

      Comment


      • #4
        Originally posted by Ralf Jansen View Post
        Ich würde mich eher fragen ob das Design grundsätzlich nicht fragwürdig ist. Nach meiner Definition haben * rein gar nix in einem View zu suchen genauso wenig wie Schemaänderungen als normaler Vorgang zur Laufzeit einer Anwendung.
        [OT]
        Mmh, ein schönes Thema!
        Wir setzen Selet * gezielt in Views und (Client) Anwendungen ein. Allerdings machen wir das auf einer Oracle DB, die abhängige Objekte automatisch rekompilieren kann.
        Was ist denn eine "normaler Vorgang zur Laufzeit", bzw. wann ist es außerhalb dessen und wäre damit okay?
        Selbst wenn man kein 24/7 Betrieb hat und gemütlich nach Feierabend der Mitarbeiter oder meinetwegen im definierten Support Zeitfenster exclusiv an der DB arbeiten kann, auch hier ändert sich ja nichts an der Problematik, dass abhängige Objekte gefunden und rekompiliert werden müssen.

        Geht man den empfohlenen Weg, muss diese Arbeit bereits im Vorfeld erfolgen, überall explizite Select und Anpassungen dort, wo neue oder geänderte Spalten weiterverarbeitet oder durchgereicht werden.
        Das setzt aber voraus, dass der Entwickler diese Fälle untersucht und auch die Rechte dazu hat. Das ist evtl. nicht immer gegeben.

        An dieser Stelle sieht man sehr gut, welche Bedeutung Views als Interface Mechanismus haben können bzw. sollten.
        [/OT]
        Gruß, defo

        Comment


        • #5
          Selbst wenn man kein 24/7 Betrieb hat und gemütlich nach Feierabend der Mitarbeiter oder meinetwegen im definierten Support Zeitfenster exclusiv an der DB arbeiten kann, auch hier ändert sich ja nichts an der Problematik, dass abhängige Objekte gefunden und rekompiliert werden müssen.
          Ein Schemaänderung kann und muß natürlich auch im laufenden Betrieb erfolgen können. Aber eben meiner Meinung nach nicht automatisch. Das sehe ich aus Programmiersicht extrem kritsch. Schemaänderungen sollten ein manueller Vorgang sein. Die entsprechend geplant, in einem Staging System getestet und von einer Person überwacht gehört. Dieser manuelle Vorgang kann dann natürlich auch die Schritte zum rekompilieren abhängiger Objekte enthalten. Die Forderung nach Automatik macht für mich nur Sinn wenn es eine normale Funktion der Anwendung ist das sich Schemas ändern. Also zum Beispiel das man einem User erlaubt Custom Properties zu Typen anzulegen und das dann eine Schemaänderung ist da neue Spalten an Tabellen erzeugt werden anstatt dies in einer geeigneten Datenstruktur ablegt wird in der das gleiche Feature nur eine Datenänderung darstellt. Es gibt soviele Problem die bei Schemaänderungen auftreten können (in den meisten DB Systemen sind die nicht mal transaktional) die nicht nur die darauf laufenden Anwendungen stören sondern auch die DB selbst zerlegen könnten das das meiner Meinung nach nie unbeobachtet passieren sollte.

          Comment


          • #6
            Der Vorteil von * ist halt, dass wenn man jetzt eine neue Spalte in einer Tabelle hinzufügen will, man diese (theoretisch) automatisch auch in allen Sub-Abfragen hat.
            Stell dir vor du hast 100 Views, die auf die geänderte Tabelle zugreifen und müsstest jetzt in jeder dieser Views diese Spalte hinzufügen. Das ist viel Arbeit + das Risiko eine View zu vergessen.
            Sub-Abfragen gibt es ja noch häufiger, da wäre es dann noch mehr Arbeit, aber da kann man ja zum Glück * benutzen, weil er beim Ausführen auch mitbekommt, dass sich die Tabelle geändert hat. Bei Views anscheinend nicht.

            Ja man könnte theoretisch an jede Tabelle einen Trigger anhängen der die abhängigen Views aktualisiert, aber das ist auch ziemlich viel Arbeit hmmm. Hatte im Hinterkopf dass ich beim Studium mal gehört hatte, dass es bei Views eine Eigenschaft gibt, die bewirkt, dass sie automatisch aktualisiert werden... "with recompile" oder so? Naja vielleicht verwechsle ich auch etwas.

            Comment


            • #7
              Das ist viel Arbeit + das Risiko eine View zu vergessen.
              Ah du möchtest also das Risiko was zu vergessen gegen Leichtfertigkeit tauschen. Klingt clever

              Erst wenn du dir alle Abhängigkeiten angesehen hast bei einer potentiellen Änderung kannst du sicherstellen das die auch wie gewünscht funktionieren. Wie garantierst du die Performance wenn du irgendwo in einer tiefliegenden Tabelle ein Feld hinzufügst wenn du scheinbar nicht mal weist wo die überall verwendet wird("Hey Kollegen ein Blob Feld für ein Bild unserer Kunden und/oder Mitarbeiter in der Person Tabelle wäre doch eine riesen Idee")? KEINE Änderungen ohne Test.
              Wenn du eine Tabelle ändern willst such dir die Abhängigkeiten in sys.sql_expression_dependencies raus, prüf die Abhängigkeiten ob das Feld da hilfreich ist und ziehe die entsprechend nach (oder eben nicht).
              Die Änderungen überprüfst du dann in einem Staging System und danach kann es dann mit der nötigen Sicherheit online gehen.

              Comment


              • #8
                Originally posted by Rya View Post
                Der Vorteil von * ist halt, dass wenn man jetzt eine neue Spalte in einer Tabelle hinzufügen will, man diese (theoretisch) automatisch auch in allen Sub-Abfragen hat.
                Stell dir vor du hast 100 Views, die auf die geänderte Tabelle zugreifen und müsstest jetzt in jeder dieser Views diese Spalte hinzufügen. Das ist viel Arbeit + das Risiko eine View zu vergessen.
                Sub-Abfragen gibt es ja noch häufiger, da wäre es dann noch mehr Arbeit, aber da kann man ja zum Glück * benutzen, weil er beim Ausführen auch mitbekommt, dass sich die Tabelle geändert hat. Bei Views anscheinend nicht.

                Ja man könnte theoretisch an jede Tabelle einen Trigger anhängen der die abhängigen Views aktualisiert, aber das ist auch ziemlich viel Arbeit hmmm. Hatte im Hinterkopf dass ich beim Studium mal gehört hatte, dass es bei Views eine Eigenschaft gibt, die bewirkt, dass sie automatisch aktualisiert werden... "with recompile" oder so? Naja vielleicht verwechsle ich auch etwas.
                Wenn man so arbeitet, muss man wirklich wissen, was man tut. Die "Select *" Abfragen müssen dafür gezielt verwendet werden. Wie gesagt mir ist das nicht unsympathisch, zumal es offenbar in anderen Systemen "glatter" funktioniert.
                Mit MS Systemen habe ich wenig Praxiserfahrung, aber wenn ein * Subselect erkannt und aktualisiert wird, kann man diesen Effekt vielleicht nutzen und die gesamten Abfrage auf oberster Ebene noch mal verschachteln.
                Ob das geht und ob man es dann einsetzt wäre genau zu prüfen.
                Trigger an jeder Tabelle würde ich dafür gar nicht einsetzen, dann eher die Operation, die Views gezielt recompiliert.
                "with recompile " geht ja wohl nur für Prozeduren.
                Gruß, defo

                Comment

                Working...
                X