none
INSERT Trigger - Neuer DS in anderer Tabelle RRS feed

  • Frage

  • hallo zusammen,

    zuerst vielen dank für die bemühungen bei meinen letzten fragen. eure antworten haben früchte getragen und ich konnte mich in letzter zeit immer mehr mit dem SQL server vertraut machen. meine hausaufgaben habe ich soweit erledigt :-)

    heute habe ich folgende frage bzw die problemstellung ist folgende.

    ich habe vor, bei einem insert (web interface) einen db trigger auszulösen. dieser soll teile des aktuellen datensatzes in eine bereits bestehende tabelle eintragen.

    bildlich gesprochen geht es darum, dass wenn ein vorgang angelegt wird, werte (user, level etc) aus diesem übernommen werden und die in eine status tabelle eingefügt werden, sozusagen als erster status (vorgang wurde angelegt).

    ich habe das soweit versucht nur wurde dann immer die komplette tabelle eingefügt :-) die frage ist also wie kann ich genau filtern dass es der letzte datensatz ist der da übergeben werden soll. bzw der letzte das sind immer wieder so access anflüge von mir. es ist mit sicherheit möglich aus dem gerade erstellten datensatz einen neuen woanders zu generieren ohne rücksicht darauf nehmen zu müssen dass die evtl mehrmals zur exakt gleichen zeit passiert wo mir dann die sache mit letzter datensatz nach datum zu unsicher wäre?

    hat sowas schonmal jemand realisiert?

    viele grüße hannes

     

     

     

    • Bearbeitet hannes.am Montag, 24. Januar 2011 08:34 edit
    Montag, 24. Januar 2011 08:31

Antworten

  • Hallo Hannes,

    calssic asp vb. es geht um insert bzw update eines datensatzes. datenmanipulation geht ja nur über tabellen.

    Bedingt. Aber das hat mit deiner Datumsproblematik nichts zu tun :)

    Du kannst auch in Classic ASP mit Parametern und Commands arbeiten. D.h. Du kannst die Werte nicht als formatierten String in ein SQL Statement basteln sondern einfach bspw.:

      <Record>.Fields( "Datumsfeld" ) = <Variable>

    schreiben. Die Doku zu ADODB ist zwar etwas gewöhnungsbedürftig aber beinhaltet trotzdem auch ein paar Beispiele, die zu gebrauchen sind.

      http://msdn.microsoft.com/en-us/library/ms675841.aspx

    Wenn Du das Datum als String schreiben willst:

      yyyy-mm-ddThh:nn:ss

    wäre dann wohl das passende Format. Du müsstest Dir dann nur eine Funktion schreiben, die dir das Datum so umsetzt. Eine Standardfunktion gibt es dafür aber nicht.

    access hat es mir auf tabellenbasis ja schließlich auch als dd.mm.yyyy zur verfügung gestellt obwohl im hintergrund sicherlich wieder was anderes stand.

    Access hat es dir nur anders dargestellt. Intern steht da nirgends dd.mm.yyyy oder ein anderes Format. Das ist nur in der Oberfläche für die Ausgabe so zu sehen, also in etwa dasselbe, was Du in deiner Classic ASP Anwendung machen musst :)

    cast, convert etc pp beziehen sich doch immer nur auf abfragen oder? tabellendaten damit zu manipulieren ist doch nicht möglich oder?

    Klar.

    ist es denn möglich das ausgabeformat eines datumsfeldes zu manipulieren?

    Das sollte immer in deiner Anwendung passieren, nicht per SQL, da Du ansonsten ggfs. nicht mit dem Datum als Datum arbeiten kannst, sondern halt nur als String. Das würde dann bspw. auch die Sortierung beeinflussen, Berechnungen (DateAdd, DateDiff, ...) verhindern, usw.

    schön wäre halt wenn das datumsformat gleich richtig in der anwendung ankommt.

    Könnte man, sollte man aber nicht-

    sollte ich es so belassen und mich bzgl der convertierung rein auf die anwendung bzw das interface konzentrieren?

    Ja :)

    belehrt mich eines anderen aber ich finde es durchaus "mühsam, auch wenn nur einmal nötig) in den abfragen das datum zu konvertieren.

    Nicht in den Abfragen, nur in den Ausgabeskripten. Anstelle von

      Datum: <%= Recordset.Fields( "Datumsspalte" ) %>

    schreibst Du dann halt:

      Datum: <%= FormatiereDatumFuerAusgabe( Recordset.Fields( "Datumsspalte" ) ) %>

    wobei "FormatiereDatumFuerAusgabe" dann eine eigens gestrickte Funktion ist (könnte man ggfs. auch mit FormatDateTime machen, ist aber, je nach Anwendungsfall, nicht so sinnvoll).

    Für DML Statements schreibst Du dann (wenn Du nicht mit Parametern arbeiten willst)

      "INSERT INTO <Tabelle>( Spalte1, Spalte2, Datumsspalte ) VALUES( ..., ..., " & FormatiereDatumFuerSQL( <Variable> ) & " )"

    BTW: Wenn man sowas macht (also SQL Statements als String ohne Parameter zusammenbasteln), sollte man sich dringend mal mit SQL Injection befassen. Ich würde mit an Sicherheit grenzender Wahrscheinlich behaupten, dass das in deiner Anwendung ein Problem ist.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 27. Januar 2011 12:18
    Moderator

Alle Antworten

  • Hallo Hannes,

    dafür gibt es in den Triggern die Tabellen inserted und deleted . Diese beinhalten die Daten der eingefügten/geänderten/gelöschten Datensätze.

    Du müsstest eigentlich nur auf diese Tabellen zugreifen.

    Bein einem INSERT also nicht

      INSERT INTO <AndereTabelle>( ... ) SELECT ... FROM <OriginalTabelle>

    sondern

      INSERT INTO <AndereTabelle>( ... ) SELECT ... FROM inserted

    In der Praxis ergeben sich da noch einige Gemeinheiten, insbesondere, wenn Du noch Joins auf andere Tabellen brauchst, ... aber für den Start sollte das so ausreichen.

    Lies dich mal in obigem Link in die Thematik ein. Wenn noch Fragen bestehen, einfach nochmal hier melden :)

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Montag, 24. Januar 2011 08:51
    Moderator
  • puh :-)

    hm, also dann mach ich mich mal an die arbeit. verstanden habe ich das soweit noch nicht...

    danke!

     

    sagt mal, wie um himmels willen kann ich ein für alle mal mein datumsformat im sql server einstellen dass das auch so bleibt.

    momentan habe ich 2005-03-22, ich brauche dauerhaft 22.03.2005.

     

    grüße

    Donnerstag, 27. Januar 2011 11:03
  • Schau Dir das mal an: Verwenden der Tabellen inserted und deleted Das erläutert das Konzept hinter diesen "virtuellen" Tabellen.

    Fürs Datumsformat lies Dir das mal durch: http://www.insidesql.org/blogs/frankkalis/2010/08/19/der-ultimative-guide-fuer-die-datetime-datentypen . Datumsformate werden nicht gespeichert, sie werden nur verwendet, wenn es um die Anzeige eines Datumswertes geht.


    -- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org
    Donnerstag, 27. Januar 2011 11:28
  • Hallo Frank,

    Schau Dir das mal an: Verwenden der Tabellen inserted und deleted Das erläutert das Konzept hinter diesen "virtuellen" Tabellen.

    hatte ich ihm schon verlinkt. Aber wenn ichs richtig verstanden hab, hat er genau damit noch Verständnisprobleme.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 27. Januar 2011 11:40
    Moderator
  • hallo frank,

    das mit den virtuellen tabellen ja...

    ich könnts täglich hinschmeissen :-)

    die seite mit dem datum, da war ich auch schon gefühle 1 mio mal, habe aber nichts gefunden was mein problem angeht, oder doch? :-)

     und nicht kapiert...

     

    also mir geht es darum das datum in einer tabelle in diesem format (dd.mm.yyyy) zu erhalten. ich benötige das für mein webinterface, hier kann ich nicht mit den abfragen arbeiten...

     

    Donnerstag, 27. Januar 2011 11:41
  • Hallo Hannes,

    das mit den virtuellen tabellen ja...

    ich könnts täglich hinschmeissen :-)

    ist aber doch eigentlich ganz ordentlich erklärt. Beispiel hatte ich auch gepostet. Was genau verstehst Du denn dabei nicht? Evtl. kann man dann noch detaillierter auf die einzelnen Punkte eingehen.
    also mir geht es darum das datum in einer tabelle in diesem format (dd.mm.yyyy) zu erhalten. ich benötige das für mein webinterface, hier kann ich nicht mit den abfragen arbeiten...

    Dein Webinterface ist für die Ausgabeformatierung zuständig. Für deine Anwendung ist ein Datum auch nur ein Datum, hat also gar kein Format. Dieses wird bspw. durch die Ländereinstellungen des Servers, durch die Einstellungen deiner Anwendung, durch den Code, ... bestimmt.

    Mit welcher Technologie arbeitest Du denn in deiner Webanwendung?

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 27. Januar 2011 11:46
    Moderator
  • hallo frank,

    das mit den virtuellen tabellen ja...

    ich könnts täglich hinschmeissen :-)

    die seite mit dem datum, da war ich auch schon gefühle 1 mio mal, habe aber nichts gefunden was mein problem angeht, oder doch? :-)

     und nicht kapiert...

     

    also mir geht es darum das datum in einer tabelle in diesem format (dd.mm.yyyy) zu erhalten. ich benötige das für mein webinterface, hier kann ich nicht mit den abfragen arbeiten...

     

    Wenn Du sowieso gerade beim Lesen bist, dann lies Dir bitte mal CAST und CONVERT in BOL durch. :-)

    -- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org
    Donnerstag, 27. Januar 2011 11:47
  • Hallo Frank,

    Schau Dir das mal an: Verwenden der Tabellen inserted und deleted Das erläutert das Konzept hinter diesen "virtuellen" Tabellen.

    hatte ich ihm schon verlinkt. Aber wenn ichs richtig verstanden hab, hat er genau damit noch Verständnisprobleme.

    Sorry, das habe ich nicht gesehen. :-)

    -- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org
    Donnerstag, 27. Januar 2011 11:47
  • bzgl trigger werde ich definitiv wieder auf euch zukommen müssen.

    webinterface:

    calssic asp vb. es geht um insert bzw update eines datensatzes. datenmanipulation geht ja nur über tabellen.

    nun dachte ich mir ich könnte das datum aus der tabelle auch in deutsch ausgeben. das datumsformat würde ich eigentlich soweit ich es verstanden habe auch nicht anrühren sondern es "international" belassen. access hat es mir auf tabellenbasis ja schließlich auch als dd.mm.yyyy zur verfügung gestellt obwohl im hintergrund sicherlich wieder was anderes stand. ist halt mein access trip :-)

    cast, convert etc pp beziehen sich doch immer nur auf abfragen oder? tabellendaten damit zu manipulieren ist doch nicht möglich oder?

    ist es denn möglich das ausgabeformat eines datumsfeldes zu manipulieren?

    schön wäre halt wenn das datumsformat gleich richtig in der anwendung ankommt.

    sollte ich es so belassen und mich bzgl der convertierung rein auf die anwendung bzw das interface konzentrieren?

    belehrt mich eines anderen aber ich finde es durchaus "mühsam, auch wenn nur einmal nötig) in den abfragen das datum zu konvertieren.

    mein ewiger access trip, das hat mir eine "falsche" sicht der dinge vermittelt.

    grüße

     

     

    Donnerstag, 27. Januar 2011 12:00
  • Normalweise würde Deine Web-Applikation das "richtige" Format anzeigen.

    In Abfragen kannst Du etwas in dieser Richtung machen:

    DECLARE @t TABLE (dt datetime)

    INSERT INTO @t (dt) VALUES ('2011-01-27 12:13:27')
    INSERT INTO @t (dt) VALUES ('2015-01-27 12:13:27')
    INSERT INTO @t (dt) VALUES ('2013-01-27 12:13:27')
    INSERT INTO @t (dt) VALUES ('2010-01-27 12:13:27')

    SELECT
        CONVERT(char(10), dt, 104)
    FROM
        @t T   

    27.01.2011
    27.01.2015
    27.01.2013
    27.01.2010

    (4 row(s) affected)

    Der "Nachteil" bei dieser Methode ist aber, dass das Ergebnis ein Zeichenfolgen-Datentyp ist und kein Datums-Datentyp mehr.


    -- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org
    Donnerstag, 27. Januar 2011 12:17
  • Hallo Hannes,

    calssic asp vb. es geht um insert bzw update eines datensatzes. datenmanipulation geht ja nur über tabellen.

    Bedingt. Aber das hat mit deiner Datumsproblematik nichts zu tun :)

    Du kannst auch in Classic ASP mit Parametern und Commands arbeiten. D.h. Du kannst die Werte nicht als formatierten String in ein SQL Statement basteln sondern einfach bspw.:

      <Record>.Fields( "Datumsfeld" ) = <Variable>

    schreiben. Die Doku zu ADODB ist zwar etwas gewöhnungsbedürftig aber beinhaltet trotzdem auch ein paar Beispiele, die zu gebrauchen sind.

      http://msdn.microsoft.com/en-us/library/ms675841.aspx

    Wenn Du das Datum als String schreiben willst:

      yyyy-mm-ddThh:nn:ss

    wäre dann wohl das passende Format. Du müsstest Dir dann nur eine Funktion schreiben, die dir das Datum so umsetzt. Eine Standardfunktion gibt es dafür aber nicht.

    access hat es mir auf tabellenbasis ja schließlich auch als dd.mm.yyyy zur verfügung gestellt obwohl im hintergrund sicherlich wieder was anderes stand.

    Access hat es dir nur anders dargestellt. Intern steht da nirgends dd.mm.yyyy oder ein anderes Format. Das ist nur in der Oberfläche für die Ausgabe so zu sehen, also in etwa dasselbe, was Du in deiner Classic ASP Anwendung machen musst :)

    cast, convert etc pp beziehen sich doch immer nur auf abfragen oder? tabellendaten damit zu manipulieren ist doch nicht möglich oder?

    Klar.

    ist es denn möglich das ausgabeformat eines datumsfeldes zu manipulieren?

    Das sollte immer in deiner Anwendung passieren, nicht per SQL, da Du ansonsten ggfs. nicht mit dem Datum als Datum arbeiten kannst, sondern halt nur als String. Das würde dann bspw. auch die Sortierung beeinflussen, Berechnungen (DateAdd, DateDiff, ...) verhindern, usw.

    schön wäre halt wenn das datumsformat gleich richtig in der anwendung ankommt.

    Könnte man, sollte man aber nicht-

    sollte ich es so belassen und mich bzgl der convertierung rein auf die anwendung bzw das interface konzentrieren?

    Ja :)

    belehrt mich eines anderen aber ich finde es durchaus "mühsam, auch wenn nur einmal nötig) in den abfragen das datum zu konvertieren.

    Nicht in den Abfragen, nur in den Ausgabeskripten. Anstelle von

      Datum: <%= Recordset.Fields( "Datumsspalte" ) %>

    schreibst Du dann halt:

      Datum: <%= FormatiereDatumFuerAusgabe( Recordset.Fields( "Datumsspalte" ) ) %>

    wobei "FormatiereDatumFuerAusgabe" dann eine eigens gestrickte Funktion ist (könnte man ggfs. auch mit FormatDateTime machen, ist aber, je nach Anwendungsfall, nicht so sinnvoll).

    Für DML Statements schreibst Du dann (wenn Du nicht mit Parametern arbeiten willst)

      "INSERT INTO <Tabelle>( Spalte1, Spalte2, Datumsspalte ) VALUES( ..., ..., " & FormatiereDatumFuerSQL( <Variable> ) & " )"

    BTW: Wenn man sowas macht (also SQL Statements als String ohne Parameter zusammenbasteln), sollte man sich dringend mal mit SQL Injection befassen. Ich würde mit an Sicherheit grenzender Wahrscheinlich behaupten, dass das in deiner Anwendung ein Problem ist.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 27. Januar 2011 12:18
    Moderator
  • hallo zusammen,

    also dann arbeite ich jetzt konsequent daran das datum so zu belassen um auch soweit als möglich der SQL I aus dem weg zu gehen.

    konsequent also datum in der anwendung formatieren. das hat mir jetzt schonmal sehr geholfen.

     

    vielen dank und bis sehr bald

    hannes

    Donnerstag, 27. Januar 2011 14:15