none
Stored Procedure Parameter behält seinen Wert RRS feed

  • Frage

  • Hallo Gemeinde,

    ich habe ein Phänomen das ich mir nicht erklären kann.

    Durch eine Stored Procedure werden Daten in eine Tabelle geschrieben.

    PROCEDURE [dbo].[sp_write_evt] @piid varchar(80), @timestamp datetime, @value int, @status int, @direction varchar(255), @product_id varchar(40), @distance int AS ....

    Wenn in der product_id ein Wert übergeben wird, der küzer als der des letzten Aufrufes ist bleiben die überschüssigen Zeicher erhalten.

    Beispiel:

    1. Aufruf    1111.2222.3333.1.1    (Wird korrekt in die Datenbank schrieben)
    2. Aufruf    4444.5555.6666          (Schreibt 4444.5555.6666.1.1 in die Datenbank)

    Ich gehe doch eigentlich davon aus das die Variable @product_id bei jedem Aufruf neu initialisiert wird?

    Das Problem trat früher schon mal bei einem SQL Server 2000 auf. In der Zwischenzeit sind wir bei einem 2008 R2.
    Da die Längenabweichungen nur recht selten vorkommen ist mir das erst später aufgefallen.
    Gibt es da eine bekannte Konstellation für so ein Verhalten?
    Wenn weitere Informationen benötigt werden bitte fragen.

    Gruß
    Wolfgang

    Mittwoch, 12. März 2014 08:34

Antworten

  • Hallo Wolfgang,
    weitere Antworten inline:

    die Stored Procedure wird von einem Ausgabeinterface eines SCADA Systems aufgerufen.
    Ich kann dort die übergebenen Parameter überprüfen.

    Prima! Das sollte schon mal etwas Klarheit bringen.

    Leider fehlt mir ein wenig das KnowHow zum Thema Debugger innerhalb des Management Studios.
    Mit DIESER Variable wird innerhalb der Procedur nichts weiter gemacht als sie in einem Insert into
    zu verwenden.  Ist es möglich die übergebenen Parameter in eine Textdatei zu speichern?
    Ich habe nur Erfahrung mit dem .NET Studio Debugger. Wenn ich einen Breakpoint in der Prozedur
    setzte, wird der dann auch beachtet wenn ein externer Aufrufer die Prozedur aufruft?
    Kann ich mir nicht vorstellen.

    Der Debugger würde nur interaktiv laufen. Wenn Du keinen Testaufruf machen kannst, dann würde ich mir die Parameter (mit Zeitpunkt des Aufrufs) in einer Tabelle abspeichern. Warum Text-Datei?

    Hier noch mal die komplett Pozedur.
    Wenn Dir (Euch) ein grober handwerklicher Fehler auffällt bitte laut Schreien. :)

    Die Prozedur ist nicht transaktionssicher und es gibt keinerlei Fehlerbehandlung (BEGIN TRY... oder Auswertung von @@ERROR).
    Dann fehlt noch überall ein Semikolon am Ende, damit man schon mal zukunftssicher programmiert.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. März 2014 13:41

Alle Antworten

  • Hallo Wolfgang,
    wie wird der Parameter denn vor dem Aufruf gefüllt?
    Wie sieht das Update dann wirklich aus?

    Hast Du mal den Debugger bemüht?

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. März 2014 08:43
  • Hallo Christoph,

    die Stored Procedure wird von einem Ausgabeinterface eines SCADA Systems aufgerufen.
    Ich kann dort die übergebenen Parameter überprüfen.
    Leider fehlt mir ein wenig das KnowHow zum Thema Debugger innerhalb des Management Studios.
    Mit DIESER Variable wird innerhalb der Procedur nichts weiter gemacht als sie in einem Insert into
    zu verwenden.  Ist es möglich die übergebenen Parameter in eine Textdatei zu speichern?
    Ich habe nur Erfahrung mit dem .NET Studio Debugger. Wenn ich einen Breakpoint in der Prozedur
    setzte, wird der dann auch beachtet wenn ein externer Aufrufer die Prozedur aufruft?
    Kann ich mir nicht vorstellen.

    Hier noch mal die komplett Pozedur.
    Wenn Dir (Euch) ein grober handwerklicher Fehler auffällt bitte laut Schreien. :)

    Gruß
    Wolfgang

    ALTER PROCEDURE [dbo].[sp_write_evt_merge] @piid varchar(80), @timestamp datetime, @value int, @status int, @direction varchar(255), @product_id varchar(40), @distance int AS
    
    SET NOCOUNT ON
    
    	DECLARE
    		@event_id     int,
    		@machine_id   int,
    		@cause_id     int,
    		@equipment_id int,
        @dif_dist     int,
        @master_id    int
        
      IF @status = 0
      BEGIN --<@status = 0>
      
        -- look in event_alias table for alias
        SELECT @master_id = master_id,
               @dif_dist = dif_dist
        FROM   event_alias
        WHERE  piid = @piid
    
        if @@rowcount = 1
        BEGIN --<event_alias exists>
      
          -- Look in event_id table for event specific parameters
          SELECT @event_id = id, @machine_id = machine_id, @cause_id = cause_id, @equipment_id = equipment_id 
          FROM   event_id 
          WHERE  piid = @piid
    
          -- Check if event is defined in event_id table
          IF @@rowcount = 1
          BEGIN --<event_id exists>
            
            IF @value = 0
            BEGIN -- <@value = 0>
              PRINT 'Process value is 0, closing an active event'
              UPDATE event_track_merge 
              SET    end_dt = @timestamp, end_dist = @distance 
              WHERE  id = @event_id AND machine_id = @machine_id AND end_dt IS NULL
            END -- <@value = 0>
    
            IF @value = 1
            BEGIN --<@value = 1>
              PRINT 'Process value is 1, creating a new event'
              -- Check if an existing event is still active in which case we don't create a new one
              UPDATE event_track_merge 
              SET    id = @event_id 
              WHERE  id = @event_id AND machine_id = @machine_id AND end_dt IS NULL
    
              IF @@rowcount = 0
              BEGIN --<@@rowcount = 0>
                -- Create a new event
                INSERT INTO event_track_merge (id, begin_dt, machine_id, equipment_id, cause_id, product_id, begin_dist, direction, master_id)
                  VALUES (@event_id, @timestamp, @machine_id, @equipment_id, @cause_id, @product_id, @distance, LOWER(SUBSTRING(@direction,1,1)), @master_id)
              END --<@@rowcount = 0>	
              
            END --<@value = 1>
          END --<event_id exists>
          ELSE
            PRINT 'Event is not defined in event_id table'
        END --<event_alias exist>
      END --<@status = 0>
      ELSE 
        PRINT 'Event has bad status'
    
    SET NOCOUNT OFF

    Mittwoch, 12. März 2014 09:23
  • Hallo Wolfgang,
    weitere Antworten inline:

    die Stored Procedure wird von einem Ausgabeinterface eines SCADA Systems aufgerufen.
    Ich kann dort die übergebenen Parameter überprüfen.

    Prima! Das sollte schon mal etwas Klarheit bringen.

    Leider fehlt mir ein wenig das KnowHow zum Thema Debugger innerhalb des Management Studios.
    Mit DIESER Variable wird innerhalb der Procedur nichts weiter gemacht als sie in einem Insert into
    zu verwenden.  Ist es möglich die übergebenen Parameter in eine Textdatei zu speichern?
    Ich habe nur Erfahrung mit dem .NET Studio Debugger. Wenn ich einen Breakpoint in der Prozedur
    setzte, wird der dann auch beachtet wenn ein externer Aufrufer die Prozedur aufruft?
    Kann ich mir nicht vorstellen.

    Der Debugger würde nur interaktiv laufen. Wenn Du keinen Testaufruf machen kannst, dann würde ich mir die Parameter (mit Zeitpunkt des Aufrufs) in einer Tabelle abspeichern. Warum Text-Datei?

    Hier noch mal die komplett Pozedur.
    Wenn Dir (Euch) ein grober handwerklicher Fehler auffällt bitte laut Schreien. :)

    Die Prozedur ist nicht transaktionssicher und es gibt keinerlei Fehlerbehandlung (BEGIN TRY... oder Auswertung von @@ERROR).
    Dann fehlt noch überall ein Semikolon am Ende, damit man schon mal zukunftssicher programmiert.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. März 2014 13:41
  • Noch eine Kleinigkeit.
    Wer soll denn die Ausgaben von den PRINT-Anweisungen lesen? Sollte man die nicht (wenn überhaupt) in eine Tabelle schreiben?
    Alternativ einen Parameter übergeben, mit dem man zu Debug-Zwecken das PRINT an- oder abschaltet.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Mittwoch, 12. März 2014 13:44
  • Hallo Christoph,

    >Der Debugger würde nur interaktiv laufen.

    Das habe ich mir gedacht.

    >Wenn Du keinen Testaufruf machen kannst, dann würde ich mir die >Parameter (mit Zeitpunkt des Aufrufs) in einer Tabelle abspeichern. Warum Text-Datei?

    Weil ich es mit einer Tabelle schon probiert habe und dort die gleichen falschen Variableninhalte eingetragen wurden. Mit Textfile wolle ich ausschließen, das das Problem im INSERT auftritt, bzw. einen ungeahnten Nebeneffekt hat.

    >Die Prozedur ist nicht transaktionssicher und es gibt keinerlei Fehlerbehandlung (BEGIN TRY... oder Auswertung von @@ERROR).

    Daran werde ich arbeiten.

    >Dann fehlt noch überall ein Semikolon am Ende, damit man schon mal zukunftssicher programmiert

    Ist das ein neues Paradigma?

    >Wer soll denn die Ausgaben von den PRINT-Anweisungen lesen?

    Das war zur Debug Ausgabe um bei der Entwicklung handangestoßene Aufrufe kontrollieren zu können.
    Ist schon so lange her und ist nur nicht rausgefallen. Die Ausgabe geht IMHO ja in das Ausgabefenster.

    Ich werde als Workaround wohl jetzt zusätzlich einen Parameter für die Länge des Strings mitgeben und dann beim Insert bei Bedarf kürzen. Auch wenn ich das ganze schon recht merkwürdig finde. Ich muss aber eine zuverlässige schnell implementierbare Lösung finden.

    Danke für Deine Antworten
    Wolfgang

    Mittwoch, 12. März 2014 14:53
  • Hallo Wolfgang!

    Weil ich es mit einer Tabelle schon probiert habe und dort die gleichen falschen Variableninhalte eingetragen wurden. Mit Textfile wolle ich ausschließen, das das Problem im INSERT auftritt, bzw. einen ungeahnten Nebeneffekt hat.

    Dann gehe ich zu 100% davon aus, dass der falsche Wert übergeben wird.

    (Semikolon) Ist das ein neues Paradigma?

    So neu ist das nicht:
    http://technet.microsoft.com/de-de/library/ms177563.aspx
    Transact-SQL-Syntaxkonventionen (Transact-SQL)

    Zitat: ; - Transact-SQL Anweisungsabschlusszeichen.Dieses Abschlusszeichen ist für die meisten Anweisungen in dieser Version von SQL Server nicht zwingend erforderlich, in zukünftigen Versionen kann sich dies jedoch ändern.

    WITH erfordert es z. B. schon heute zwingend vorher. Am besten gewöhnt man sich das schon mal an, da es auch die Skripte für mich besser unterteilt und damit lesbarer macht.
     >Ich werde als Workaround wohl jetzt zusätzlich einen Parameter für die

    Länge des Strings mitgeben und dann beim Insert bei Bedarf kürzen. Auch wenn ich das ganze schon recht merkwürdig finde. Ich muss aber eine zuverlässige schnell implementierbare Lösung finden.

    Wenn Du die Möglichkeit hast, dann kannst du auch dort prüfen, ob der Inhalt des Parameters wirklich der erwarteten Länge entspricht. Es bringt nichts, die Länge eines falsch gefüllten Parameters zu überprüfen und durchzureichen.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu


    David Wilkinson | Visual C++ MVP
    Donnerstag, 13. März 2014 08:12
  • Das letzte Posting war definitiv nicht von David. Da hat uns wohl das Forum oder die NNTP-Bridge einen Streich gespielt! ;-)
    Donnerstag, 13. März 2014 09:44
  • Das letzte Posting war definitiv nicht von David. Da hat uns wohl das Forum oder die NNTP-Bridge einen Streich gespielt! ;-)

    You are correct,  I did not write this post. But it showed up in My Threads.

    Edit: This is the second SQL-related post that has been attributed to me today. Both of them supposedly came from the NNTP bridge. At one time I was using the bridge, but I have not been using it recently.


    David Wilkinson | Visual C++ MVP


    • Bearbeitet davewilk Donnerstag, 13. März 2014 10:08
    Donnerstag, 13. März 2014 10:01
  • Hallo Christoph,

    irgend etwas scheint grade mit dem Forum nicht zu stimmen.
    Hängt sich beim Posten auf und Forum ist danach 30 Minuten nicht erreichbar.

    Danke für Deine Antworten.

    Ich werde mich mal wieder auf den neuesten Stand in Sachen Transact SQL bringen müssen.

    Ich komme eher aus der Ecke VB6, C# und PL/SQL.

    Ich wünsche Euch allen einen schönen Tag.

    Gruß
    Wolfgang

    Donnerstag, 13. März 2014 10:20
  • You will become a SQL Server MVP, too!

    Greetings,
    Christoph
    SQL Server MVP

    Donnerstag, 13. März 2014 10:51
  • Das Durcheinander mit den falsch zugewiesenen Postings ist gestern abend noch gefixed worden!

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Freitag, 14. März 2014 09:46
  • Hallo Wolfgang,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Wenn nicht, neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.

    Danke und viele Grüße,
    Ionut


    Ionut Duma, MICROSOFT   Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-PrinzipEntwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Freitag, 21. März 2014 13:01
    Moderator
  • Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat

    Hallo Ionut,

    das hat es tatsächlich.

    Die Antworten haben mich bestärkt doch noch einmal genau die übergebenen Parameter zu überprüfen.
    Und das SCADA hat tatsächlich schon falsche Parameter übergeben, trotz das sie dort eigene Debugausgabe
    einen korrekten Wert anzeigt. Problem wurde jetzt vom Entwickler bestätigt und konnte nachgestellt werden.

    Danke noch mal an alle.

    Gruß
    Wolfgang

    Freitag, 21. März 2014 16:43