Announcement

Collapse
No announcement yet.

Variable ausführen mit Execute

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

  • Variable ausführen mit Execute

    Hallo,

    ich möchte gerne eine Prozedur schreiben,
    die aus einer "Textzahl" mit Leerzeichen (Beispiel " 123,45 ")
    eine "Textzahl" mit fester Breite macht (Beispiel "00123,5").
    Der Prozedur soll die Anzahl der Zeichen und die Anzahl der Nachkommastellen
    mitgegeben werden.

    Wenn ich die unten aufgeführte Script mit fester Vorgabe von
    Länge und Anzahl der Nachkommastellen ausführe,
    erhalte ich das gewünschte Ergebnis.

    Verwende ich variable Version, erhalte ich einen Fehler.

    Der Fehler entsteht,
    wenn die Variable @sql mit EXECUTE ausgeführt wird,
    Anstelle einer "starren" SQL Anweisung.

    Hat jemand eine Idee, wie ich das Problem Lösen kann?

    Gruss
    Carsten





    --------------------------------------------------------------------------------
    gewünschtes Ergebnis

    123.45 Textzahl unformatiert
    123.45 Leerzeichen links entfernt
    123.45 Leerzeichen rechts entfernt

    7 Länge
    1 NachKomma

    SQL EXECUTE Anweisung
    IF cast(@ZahlUnformatiert as decimal(7,1)) > 0 set @ZahlFormatiert = cast(@ZahlUnformatiert as decimal(7,1))

    5 -> Anzahl der Zeichen vor der Scheife

    6 -> Anzahl der Zeichen während der Scheife
    7 -> Anzahl der Zeichen während der Scheife

    00123.5 Zahl formatiert


    --------------------------------------------------------------------------------
    fehlerhaftes Ergebnis

    123.45 Textzahl unformatiert
    123.45 Leerzeichen links entfernt
    123.45 Leerzeichen rechts entfernt

    7 Länge
    1 NachKomma


    SQL EXECUTE Anweisung
    IF cast(@ZahlUnformatiert as decimal(7,1)) > 0 set @ZahlFormatiert = cast(@ZahlUnformatiert as decimal(7,1))
    Server: Nachr.-Nr. 137, Schweregrad 15, Status 2, Zeile 1
    Die Variable '@ZahlUnformatiert' muss deklariert werden.
    Server: Nachr.-Nr. 137, Schweregrad 15, Status 1, Zeile 1
    Die Variable '@ZahlUnformatiert' muss deklariert werden.

    0 -> Anzahl der Zeichen vor der Scheife

    1 -> Anzahl der Zeichen während der Scheife
    2 -> Anzahl der Zeichen während der Scheife
    3 -> Anzahl der Zeichen während der Scheife
    4 -> Anzahl der Zeichen während der Scheife
    5 -> Anzahl der Zeichen während der Scheife
    6 -> Anzahl der Zeichen während der Scheife
    7 -> Anzahl der Zeichen während der Scheife

    0000000 Zahl formatiert


    --------------------------------------------------------------------------------
    Script


    DECLARE @ZahlUnformatiert nvarchar(255)
    DECLARE @Laenge nvarchar(2)
    DECLARE @NachKomma nvarchar(1)
    DECLARE @ZahlFormatiert nvarchar(15)
    DECLARE @AnzahlZeichen int
    DECLARE @SQL nvarchar(255)


    set @sql = ''
    set @ZahlUnformatiert = ' 123.45 '
    set @ZahlFormatiert = ''

    set @Laenge = '7';
    set @NachKomma= '1';

    print @ZahlUnformatiert + ' Textzahl unformatiert';

    set @ZahlUnformatiert = ltrim (@ZahlUnformatiert)
    print @ZahlUnformatiert + ' Leerzeichen links entfernt'

    set @ZahlUnformatiert = rtrim (@ZahlUnformatiert)
    print @ZahlUnformatiert + ' Leerzeichen rechts entfernt'

    print ''
    print @Laenge + ' Länge ' ;
    print @NachKomma + ' NachKomma ';
    print ''

    set @sql =
    'IF cast(@ZahlUnformatiert as ' +
    'decimal(' + @Laenge + ',' + @NachKomma + ')) > 0 ' +
    'set @ZahlFormatiert = cast(' +
    '@ZahlUnformatiert as decimal(' + @Laenge + ',' + @NachKomma + '))'

    --IF cast(@ZahlUnformatiert as decimal(7,1)) > 0 set @ZahlFormatiert = cast(@ZahlUnformatiert as decimal(7,1))

    print ''
    print 'SQL EXECUTE Anweisung'
    print @sql
    execute (@sql) ;


    SET @AnzahlZeichen = len(@ZahlFormatiert)
    print ''
    print cast(@AnzahlZeichen as nvarchar(15)) + ' -> Anzahl der Zeichen vor der Scheife'
    print ''

    SET @AnzahlZeichen = len(@ZahlFormatiert);

    WHILE (@AnzahlZeichen < @Laenge)
    BEGIN
    SET @ZahlFormatiert = '0' + @ZahlFormatiert
    SET @AnzahlZeichen = @AnzahlZeichen + 1
    print cast(@AnzahlZeichen as nvarchar(15)) + ' -> Anzahl der Zeichen während der Scheife'
    END



    print ''
    print @ZahlFormatiert + ' Zahl formatiert'

  • #2
    Hallo,

    wenn eine dynamische SQL-Anweisung ausgeführt werden soll, hat der Weg über sp_excecutesql gegenüber dem EXEC-Weg immer dann Vorteile, wenn Parameter im Spiel sind. Der Grund dafür liegt darin, dass sp_excecutesql ein Interface unterstützt und somit im Gegensatz zu EXECUTE auf lokale Variablen der Stapelanweisung zugreifen kann. Die folgende Stapelanweisung arbeitet das unterschiedliche Verhalten heraus:

    <div style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><pre style="margin: 0px;"><span style="color: blue;">SET NOCOUNT ON</span>;</pre><pre style="margin: 0px;"><span style="color: blue;">USE </span>tempdb</pre><pre style="margin: 0px;">GO</pre><pre style="margin: 0px;">&nbsp;</pre><pre style="margin: 0px;"><span style="color: blue;">IF OBJECT_ID</span>(<span style="color: #a31515;">'TestTbl'</span>) <span style="color: blue;">IS NOT NULL</span></pre><pre style="margin: 0px;">&nbsp; <span style="color: blue;">DROP TABLE </span>TestTbl;</pre><pre style="margin: 0px;">GO</pre><pre style="margin: 0px;">&nbsp;</pre><pre style="margin: 0px;"><span style="color: blue;">CREATE TABLE </span>TestTbl</pre><pre style="margin: 0px;">(</pre><pre style="margin: 0px;">&nbsp; testtbl_id <span style="color: blue;">INT </span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">NOT NULL IDENTITY PRIMARY KEY</span>,</pre><pre style="margin: 0px;">&nbsp; wert&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; NVARCHAR(9) <span style="color: blue;">NOT NULL</span></pre><pre style="margin: 0px;">)</pre><pre style="margin: 0px;">GO</pre><pre style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl (wert) <span style="color: blue;">VALUES </span>(<span style="color: #a31515;">'Test 1'</span>);</pre><pre style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl (wert) <span style="color: blue;">VALUES </span>(<span style="color: #a31515;">'Test 2'</span>);</pre><pre style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl (wert) <span style="color: blue;">VALUES </span>(<span style="color: #a31515;">'Test 3'</span>);</pre><pre style="margin: 0px;">GO</pre><pre style="margin: 0px;">&nbsp;</pre><pre style="margin: 0px;"><span style="color: green;">-- Variante A: EXEC</span></pre><pre style="margin: 0px;"><span style="color: blue;">DECLARE </span>@s <span style="color: blue;">AS VARCHAR</span>(99);</pre><pre style="margin: 0px;"><span style="color: blue;">DECLARE </span>@i <span style="color: blue;">AS INT</span>;</pre><pre style="margin: 0px;"><span style="color: blue;">SET </span>@i = 1;</pre><pre style="margin: 0px;"><span style="color: blue;">SET </span>@s = <span style="color: #a31515;">'SELECT * FROM dbo.TestTbl WHERE testtbl_id = @i;'</span>;</pre><pre style="margin: 0px;"><span style="color: green;">-- EXEC hat kein Interface, daher gelten lokale Variablen dort nicht!</span></pre><pre style="margin: 0px;"><span style="color: blue;">EXEC</span>(@s);&nbsp; </pre><pre style="margin: 0px;"><span style="color: green;">-- Ergebnis: Veto: Die "@i"-Skalarvariable muss deklariert werden.</span></pre><pre style="margin: 0px;">&nbsp;</pre><pre style="margin: 0px;">&nbsp;</pre><pre style="margin: 0px;"><span style="color: green;">-- Variante B: sp_executesql</span></pre><pre style="margin: 0px;"><span style="color: blue;">DECLARE </span>@s <span style="color: blue;">AS </span>NVARCHAR(99);</pre><pre style="margin: 0px;"><span style="color: blue;">DECLARE </span>@i <span style="color: blue;">AS INT</span>;</pre><pre style="margin: 0px;"><span style="color: blue;">SET </span>@i = 1;</pre><pre style="margin: 0px;"><span style="color: blue;">SET </span>@s = <span style="color: #a31515;">'SELECT * FROM dbo.TestTbl WHERE testtbl_id = @recid;'</span>;</pre><pre style="margin: 0px;"><span style="color: green;">-- sp_executesql hat ein Interface, so dass lokale Variablen nutzbar sind!</span></pre><pre style="margin: 0px;"><span style="color: blue;">EXEC </span>sp_executesql @stmt = @s, @params = N<span style="color: #a31515;">'@recid AS INT'</span>, @recid = @i;</pre><pre style="margin: 0px;"><span style="color: green;">-- Ergebnis: 1 Datensatz</span></pre></div>

    Comment


    • #3
      Hallo Andreas,

      Deine Ausführung ist für mich schon sehr hilfreich,
      bringt mich aber nicht ganz ein mein Ziel.

      Ich möchte gerne nachstehenden Ausdruck verwenden:
      set @ZahlFormatiert = cast(@Zahl as decimal(19,2))

      Die Zahlen 19 und 2 sollen durch Variablen ersetzt werden:
      set @ZahlFormatiert = cast(@Zahl as decimal(@vor,@nach))

      ...und hier liegt das Problem.
      Wie kann ich dieses Lösen?


      ------------------------------------------
      Beispiel

      declare @Zahl decimal(19,10)
      declare @ZahlFormatiert nvarchar(30)

      set @Zahl = 123.456789
      print cast(@Zahl as nvarchar(30)) + ' Ursprungszahl'

      set @ZahlFormatiert = cast(@Zahl as decimal(19,2))

      print @ZahlFormatiert + ' Zahl formatiert'

      Comment

      Working...
      X