Announcement

Collapse
No announcement yet.

Schwierigkeiten mit selbsdefinierter Funktion.

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

  • Schwierigkeiten mit selbsdefinierter Funktion.

    Moin!

    Seit einiger Zeit versuche ich mich mit MS SQL Server anzufreunden. Nun habe ich mit der Programmierung der „user defined function“ und „stored procedure“ angefangen. Dabei bin ich auf Probleme gestoßen, die ich mit eurer Hilfe lösen möchte.

    <B>Ausgangssituation:</B>
    MS SQL Server, Test-Tabelle, selbstdefinierte Funktion und SQL Query Analyzer.

    <B>Test-Tabelle:</B><br>
    id, zahl, string<br>
    1 1 abc<br>
    2 3 def<br>
    3 7 ghi<br>

    <B>Selbstdefinierte Funktion:</B><br>
    <PRE>create function fkt_ContString()
    returns varchar(200) as
    begin
    declare @return_string varchar(200), @id int, @zahl int, @string varchar(10);
    declare
    o_cursor cursor for
    select @id, @zahl, @string
    from shortstring;<br>

    open o_cursor<br>

    fetch next from o_cursor
    into @id, @zahl, @string<br>

    while @@fetch_status = 0
    begin
    select @return_string = @return_string + @string
    end<br>

    close o_cursor<br>

    return(@return_string)
    end
    </PRE>

    Als Ergebnis erwarte ich, dass folgende Zeichenkette zurückgeliefert wird: “abcdefghi”.

    <B>Aufruf in SQL Query Analyzer:</B><br>
    select dbo.fkt_ContString() as 'myString'

    Ich habe versucht die Funktion in SQL Query Analyzer aufzurufen. Der Server scheint zwar sehr beschäftigt zu sein, doch leider passiert nicht viel mehr. Deswegen musste ich nach einiger Zeit die Abarbeitung der Query abbrechen.

    Was mache ich falsch?<br>
    Wie testet man die selbstdefinierten Funktionen im „Enterprise Manager“?<br>
    Kann man eine selbsterstellte Funktion in SQL Query Analyzer debugen?<br>

    Viele Grüße<br>
    Markus

  • #2
    Hallo Markus,

    Ohne näher auf deine procedure eingehen zu wollen - was ist die Abbruchbedingung der while-Schleife?? Wohl die Variable @@fetch_status. Diese wird aber nur durch einen Fetch gesetzt. Den ersten machst du zwar noch draußen, aber innerhalb der while-Schleife gibt es keinen neuen Fetch mehr. Klassische Endlosschleife würde ich sagen. Erklärt aber die Arbeitsamkeit deines Rechners :-))

    Bezüglich Debuggen von stored Procs, das geht normalerweise im QueryAnalizer. Dazu den Objektkatalog öffnen (F2), sofern nicht schon offen, die Datenbank wählen, auf gespeicherte Proceduren gehen, die zu debuggende mit der rechten Maustaste anklicken und im Menü ganz unten "debuggen" wählen. Ist aber eine etwas eigenartige Sache. Auf meinem Rechner ging's anfangs, dann musst ich mal neu aufsetzten, seitdem kann ich zwar noch die Startparameter eingeben, allerding geht kein Step und kein Breakpopint mehr. <br>
    Ein anderer Debugger kommt von DBArtisan, der kostet aber mächtig Geld.

    bye,<br>
    Helmu

    Comment


    • #3
      Hallo Markus,<BR><BR>ein Cursor ist immer ziemlich Bäh. Vielleicht bringt dich der Schnippsel auf eine neue Idee?!
      <PRE>
      create table #a (ID int identity primary key, Zahl int, String varchar(10))
      --
      insert into #a values(1, 'abc')
      insert into #a values(3, 'def')
      insert into #a values(7, 'ghi')
      --
      declare @c as varchar(200)
      set @c = '' -- !
      --
      select @c = @c + String
      from #a
      --
      select @c
      --
      drop table #a
      </PRE>
      Viele Grüße Ola

      Comment


      • #4
        Moin!

        Vielen dank für eure prompte Antworten. Den Fehler mit fehlendem „fetch“ innerhalb der „while“ habe ich beseitigt. Nun sieht meine Funktion folgendermaßen aus:

        <PRE>create function fkt_ContString ()
        returns varchar(200) as
        begin
        declare @return_string varchar(200), @id int, @zahl int, @string varchar(10);
        declare
        o_cursor cursor for
        select @id, @zahl, @string
        from shortstring;<BR>

        set @return_string = ''
        open o_cursor<BR>

        fetch next from o_cursor
        into @id, @zahl, @string<BR>

        while @@fetch_status = 0
        begin
        select @return_string = @return_string + @string<BR>

        fetch next from o_cursor
        into @id, @zahl, @string
        end<BR>

        close o_cursor<BR>

        return(@return_string)
        end</PRE>

        Und siehe da! Der Rechner ist nicht mehr so schwer „beschäftigt“ wie früher und erledigt die Query in Null Komma Nix. Vielen Dank Helmut! Eigentlich sollte ich selber drauf kommen. Aber was soll’s -> Anfänger-Fehler.

        Nun endlich bekomme ich ein Rückgabewert. Leider den Falschen. Statt „abcdefghi“ bekomme ich als Resultat NULL, obwohl in der Test-Tabelle „shortstring“ drei Sätze vorhanden sind (siehe mein erstes Posting). Eigentlich schade! Warum das so ist wollte ich durch debugen rausfinden. Leider musste ich feststellen, dass man im Gegensatz zu Proceduren, die selbstdefinierte Funktionen nicht debugen kann. Der Menüpunkt „Debug...“ bleibt bei Funktionen deaktiviert (grau dargestellt). Weil ich das selber nicht debugen kann, stehe ich ziemlich ratlos vor meinem Problem: NULL statt „abcdefghi“.

        Was ist immer noch falsch in meiner Funktion?

        Danke im Voraus und viele Grüße<BR>
        Marku

        Comment


        • #5
          Hallo Markus,<BR><BR>der fehler ist das SELECT Statement für deinen Cursor, da du nicht die Feldnamen aufzählst sondern die Variablen, die zu diesem Zeitpunkt ja NULL sind.<BR>Etwas überarbeitet funktioniert es:
          <PRE>
          /*
          create table shortstring (ID int identity primary key, Zahl int, String varchar(10))
          --
          insert into shortstring values(1, 'abc')
          insert into shortstring values(3, 'def')
          insert into shortstring values(7, 'ghi')
          */
          --
          create function fkt_ContString ()
          returns varchar(200) as
          begin
          declare @return_string varchar(200), @id int, @zahl int, @string varchar(10);
          declare
          o_cursor cursor for
          select id, zahl, string
          from shortstring;
          set @return_string = ''
          open o_cursor
          fetch next from o_cursor into @id, @zahl, @string
          while @@fetch_status = 0
          begin
          select @return_string = @return_string + @string
          fetch next from o_cursor into @id, @zahl, @string
          end
          close o_cursor
          return(@return_string)
          end
          --
          --print dbo.fkt_ContString()
          --Ausgabe: abcdefghi
          </PRE>
          Aber mal ehrlich, sieht die andere Variante nicht etwas angenehmer aus?
          <PRE>
          alter function fkt_ContString ()
          returns varchar(200) as
          begin
          declare @return_string varchar(200)
          set @return_string = ''
          --
          select @return_string = @return_string + string
          from shortstring
          --
          return(@return_string)
          end
          --
          --print dbo.fkt_ContString()
          --Ausgabe: abcdefghi
          </PRE>
          Viele Grüße Ola

          Comment


          • #6
            Moin Olaf!

            Vielen Dank für deine Fehlererklärung. Hab ich kapiert!

            Außerdem gebe ich zu: deine Variante ohne, ist viel eleganter als meine mit dem Cursor,
            obwohl ich in beiden Fällen das gleiche Ergebnis bekommen habe: "abc_______def_______ghi_______".

            Trotzdem habe ich schon wieder was gelernt!

            Noch mal vielen Dank!

            Viele Grüße<br>
            Marku

            Comment

            Working...
            X