Thomas Teufl

Knowledgebase

Archive for the ‘Programmierung’ Category

Testen

Program testing can be used to show the presence of bugs, but never to show their absence!

Edsger Wybe Dijkstra, niederländischer Informatiker.

  • 0 Comments
  • Filed under: Programmierung
  • Coole Charts mit Googles Chart-API

    Diesergooglechart1 oder dieser googlechart2 oder jener Chart googlechart3 sind ganz einfach mit Googles Chart API machbar:

    <img src="http://chart.apis.google.com/chart?
       cht=lc
       &chs=100x30
       &chd=t:5.3,26.5,15.9,31.7,42.3,21.2,26.5,42.3,47.6,95.2,18.5,26.5,21.2,37.0,52.9,58.2,47.6,68.8,26.5,31.7,42.3
       &chco=336699
       &chls=1,1,0
       &chm=o,990000,0,20,4
       &chxt=r,x,y
       &chxs=0,990000,11,0,_|1,990000,1,0,_|2,990000,1,0,_
       &chxl=0:|8|1:||2:||
       &chxp=0,42.3
    ">

    siehe Business vs Programming, Beispiel

  • 0 Comments
  • Filed under: Programmierung
  • MS SQL: REPLACE aus MySQL

    Warum hat MS SQL die wirklich hilfreiche Funktion REPLACE aus MySQL nicht? Gut, ab Version 2008 gibt es etwas vergleichbares namens MERGE. Aber in Vorgängerversionen muss man sich mit einem Workaraound behelfen. Keith hat bei stackoverflow.com eine Funktion Namens “upsert” (von UPdate und inSERT) veröffentlicht.

    siehe upsert bei stackoverflow.com

    MS SQL T-SQL FOR EACH Row

    In Microsofts SQL-Server soll weiterer dynamischer Code zu jeder Zeile einer Abfrage ausgeführt werden. Bei Oracle gibt es dafür FOR EACH row. MS T-SQL hat dieses Konstrukt noch nicht, hier muss man sich mit einem Workaround behelfen. Justin Carmony hat sich damit intensiv beschäftigt. In den Kommentaren sind noch verschiedene andere Möglichkeiten aufgeführt.

    Es fehlt aber noch eine recht einfache über die ab Version 2005 verfügbaren Common Table Expressions:

    DECLARE @cnt int
    DECLARE @cntMax int
    SELECT @cnt=1;
    SELECT @cntMax =Count(ID) FROM myTable WHERE x=1 
    
    DECLARE @y int
    WHILE @cnt <= @cntMax
    BEGIN --While Loop
    	WITH AbfrageLoop AS (
    	SELECT row_number() OVER (ORDER BY ID) AS Row,*
    		FROM  myTable
    		WHERE x=1
    		)
    	SELECT @y=y FROM AbfrageLoop WHERE Row=@cnt
    
    	--do something based on the query
    	DELETE FROM AnotherTable WHERE AnotherY=@y
    
    	SELECT @cnt = @cnt+1
    END --While Loop

    siehe Justin Carmony, MS MSDN

    Möchte man im MS SQL-Server Code zur Laufzeit generieren und Ausführen lassen (hier im Trigger), ist das kein großes Problem:

    DECLARE @SQL nvarchar(200)
    SET @SQL=N'SELECT xy FROM myTable WHERE x=1'
    EXEC @SQL

    Schwieriger wird es, wenn die Abfrage eine Prüfung durchführen soll und aufgrund des Ergebnisses weitere Aktionen ausgeführt werden. Das bedeutet, dass ein Ergebnis zurück in den aufrufenden Code transferiert werden muss. Leider läuft jede EXEC-Anweisung in einem eigenen Kontext, auf den von außen nicht zugegriffen werden kann. Dieses Problem muss man umgehen.

    DECLARE @SQL nvarchar(200)
    DECLARE @rueckgabe int
    SET @SQL=N'SELECT xy,@min=min(y) FROM myTable WHERE x=1'
    EXEC sp_executesql @SQL, N'@min int OUTPUT', @rueckgabe OUTPUT
    IF @rueckgabe>5
    BEGIN
      --do something
    END

    Es wird die mitgelieferte Stored Procedure “sp_executesql” verwendet, mit der der SQL-Code ausgeführt wird. Weiter wird eine interner Parameter definiert (hier @min), der auch noch als Ausgabeparameter gekennzeichnet wird. Dieser kann zurückgegeben und in der der ursprünglichen Codebasis wiederverwendet werden.

    siehe MS MSDN sp_execute