Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

31. August 2009 um 18:07

SQL Server: Langläufer

In dem Artikel "Wer sind heute meine 5 Langläufer? " beschrieb ich ein gefundenes SQL-Statement mit dem man sich Infos zu den langsamsten SQL-Statement anzeigen lassen kann. Im Laufe der zeit modifizierte ich die Abfrage immer weiter.

Hier ist die verbesserte Fassung, die viele weitere interessante Angaben über den Befehl macht:

SELECT TOP(200)
qs.execution_count AS "Executions",
CAST(CAST(qs.total_elapsed_time AS NUMERIC(20,4))/1000/qs.execution_count AS NUMERIC(20,4)) AS "AvgDuration[ms]", – Umrechung in Millisekunden
CAST(CAST(qs.total_worker_time AS NUMERIC(20,4))/1000/qs.execution_count AS NUMERIC(20,4)) AS "AvgCpuTime[ms]", – Umrechung in Millisekunden
SUBSTRING(st.text,(qs.statement_start_offset+2)/2, – Offset wird in Bytes angegeben
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CAST(st.text AS NVARCHAR(MAX)))*2
ELSE qs.statement_end_offset
END – qs.statement_start_offset)/2) AS "SqlStatement",
CAST(CAST(qs.last_elapsed_time AS NUMERIC(20,4))/1000 AS NUMERIC(20,4)) AS "LastDuration[ms]", – Umrechung in Millisekunden
CAST(CAST(qs.last_worker_time AS NUMERIC(20,4))/1000 AS NUMERIC(20,4)) AS "LastCpuTime[ms]", – Umrechung in Millisekunden
CAST(CAST(qs.total_elapsed_time AS NUMERIC(20,4))/1000 AS NUMERIC(20,4)) AS "TotalDuration[ms]", – Umrechung in Millisekunden
CAST(CAST(qs.total_worker_time AS NUMERIC(20,4))/1000 AS NUMERIC(20,4)) AS "TotalCpuTime[ms]", – Umrechung in Millisekunden
qs.total_logical_reads AS "TotalLogicalReads",
qs.total_physical_reads AS "TotalPhysicalReads",
qs.total_logical_writes AS "TotalLogicalWrites",
qs.creation_time AS "FirstExecution",
qs.last_execution_time AS "LastExecution",
db_name(st.dbid) AS "Database"
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
WHERE qs.total_elapsed_time > 0
ORDER BY "AvgDuration[ms]" DESC, qs.execution_count DESC

Viel Erfolg damit… 🙂

30. August 2009 um 18:18

Test-Special über Fahrräder

Wer bei der aktuellen Aktion "Mit dem Rad zur Arbeit" mitmacht oder einfach nur so gerne mit dem Rad fährt, der findet vermutlich das Special von Stiftung Warentest zu Fahrrädern interessant. Dort gibt es Artikel zu den Themen:

  • Fahrradkauf
  • Sicherheit
  • Beifahrer Kind
  • Verkehrsregeln
  • Gegen Diebstahl
  • Reparatur + Pflege
  • Routenplanung
  • Rad als Gepäck

Weitere Tipps gibt es auch beim ADFC (etliche allerdings nur kostenpflichtig).

28. August 2009 um 17:59

Welche Objekte belegen wie viele Datenseiten im Cache-Buffer?

Wenn man im SQL Server 2005 wissen will, was so alles im Datencache steht, dann kann man sich mit Hilfe der Data Management View "sys.dm_os_buffer_descriptors" einen Überblick verschaffen. Man erfährt welche Seite in den Cache geladen wurden.

Mit diesem Statement sieht man sogar wie viele Seiten aktuell von welcher Tabelle aus welcher Datenbank im Cache "belegt" werden:

SELECT CASE GROUPING(db.name) WHEN 0 THEN db.name ELSE N'#all dbs#' END AS [dbname],
CASE GROUPING(object_name(p.object_id)) WHEN 0 THEN object_name(p.object_id) ELSE N'#all objects#' END AS [objname],
CASE GROUPING(p.index_id) WHEN 0 THEN CAST(p.index_id AS NVARCHAR) ELSE N'#all indexes#' END AS [indexid],
COUNT(page_id) AS [pagecount]
FROM sys.dm_os_buffer_descriptors AS bd
JOIN sys.allocation_units AS au
ON bd.allocation_unit_id = au.allocation_unit_id
JOIN sys.partitions p
ON au.container_id = p.hobt_id
JOIN sys.databases as db
ON bd.database_id = db.database_id
GROUP BY db.name, object_name(p.object_id), p.index_id WITH ROLLUP
ORDER BY [pagecount] DESC

Ich hoffe das hilft jemandem… 😉

27. August 2009 um 18:35

Defraggler

Über die PC-Welt wurde ich auf das Tool Defraggler aufmerksam. Damit kann man unter Windows recht komfortabel Partitionen oder auch nur einzelne Dateien defragmentieren. Und das beste ist, dass man das Programm auch einfach auf einen Stick kopieren kann. Es läuft dann ohne Installation. Ich finde das Werkzeug prima. Allerdings kommt es mir etwas langsam vor…

26. August 2009 um 18:18

History of Video Games

Auf der Seite "History of Video Games" unter computerspielemuseum.de findet man eine nette Zusammenstellung von bahnbrechenden Video-Spielen und auch Computerspielen. Man muss Flash leider erlauben um etwas sehen zu können.

Atari wird mit etlichen Meilensteinen erwähnt (natürlich auch "Pong"), ebenso M.U.D. und andere bahnbrechende Spiele. Daneben werden aber auch webweisende Romane erwähnt und bedeutende Spiele-Hardware. Die Ansicht ist etwas spartanisch, aber dennoch einen Blick wert…

via knuttz
25. August 2009 um 18:19

Mit SQL Server Text-Dateien schreiben

Wie man mit dem SQL-Server Text-Dateien einlesen kann, wusste ich schon länger. Dazu musste man früher OpenRowSet mit einem ODBC-Text-Treiber verwenden:

SELECT *
FROM OPENROWSET('MSDASQL',
'Driver={Microsoft Text Driver (*.txt; *.csv)};DEFAULTDIR='E:\data;Extensions=txt;',
'SELECT * FROM [test.txt]') AS t;

Aber das war tricky und der Output war immer pro Zeile ein Datensatz. Freilich konnte man auch die Daten mittels "BULK INSERT" in eine Tabelle laden, aber auch das war umständlich. Seit SQL-Server-2005 gibt es dazu eine gute und dokumentierte Lösung:

SELECT x
FROM OPENROWSET(BULK 'E:\data\test.txt', SINGLE_CLOB) AS t(x);

Das funktioniert auch mit Bildern oder beliebigen anderen Dateien, dann ist es aber ein "SINGLE_BLOB". Aber das Schreiben ist so immer noch nicht möglich. Freilich kann man auch hier wieder mit OpenRowSet arbeiten. Der Text-Treiber kann aber keinen INSERT, daher muss man dann schon den Treiber für Access nehmen und so tun als wäre es eine csv-Datei. Mit dem gelang es aber nicht eine neue Datei anzulegen. Man musste also zuerst eine leere Datei via xp_cmsshell anlegen und konnte sie dann füllen. Das geht aber nur mit 32-Bit-SQL-Servern, weil es gibt keine 64-Bit-Treiber für die Jet-Engine gibt… 🙁

Bei Simple-Talk fand ich eine praktikable Lösung dazu: Man verwendet "bcp" via "xp_cmdshell", um die Daten in eine Text-Datei zu schreiben. Klingt schwierig, ist es aber nicht. Wie für alle obigen Lösungen benötigt man auch hier Admin-Rechte. Die Lösung taugt also nicht für den laufenden Betrieb, aber eignet sich prima für eigene administrative Aufgaben.

DECLARE @Cmd nvarchar(2000);
SET @Cmd = N'bcp "select t from [TestTable]" queryout "F:\temp\outfile.txt" -T -S'
+ @@servername + N' -w'; – "-w" für Unicode-Datei "-c" für ANSI
EXEC xp_cmdshell @Cmd;

Natürlich muss man die Verwendung von xp_cmdshell erst mal erlauben.

Hier steht der Trick im Detail beschrieben und etliches mehr: "The TSQL of Text Files"

24. August 2009 um 18:07

Bewerbern auf den Zahn fühlen

Mein Kollege Peter machte mich auf einen Tests für Bewerber aufmerksam. Man solle Ihnen eine leichte Programmmieraufgabe geben, um die Fähigkeiten des Kandidaten zu erleben. Als Beispiel soll ein Programm die Zahlen von 1 bis 100 ausgeben. Ist die Zahl hingegen durch 3 teilbar, dann statt dessen "Fizz". Ist sie durch 5 teilbar, dann "Buzz". Ist sie aber durch 3 und 5 teilbar, dann "FizzBuzz". Erstmals beschrieben wurde das offenbar im Artikel "Using FizzBuzz to Find Developers who Grok Coding".

Das Ganze hat zwei Aspekte:

  • Taugen solche Tests überhaupt, um im Bewerbergespräch wertvolle Erkenntnisse zu sammeln?
  • Und wie ist die TSQL-Lösung dieser konkreten Aufgabe… 😉

Ich bin unsicher wegen der Aussagekraft: Ich persönlich würde gut ausgearbeitete Tests zur Auswahl der Bewerber befürworten, um einfach besser einschätzen zu können, ob sie die gewünschten Qualifikationen haben. Leider kann ich in Bewerbergesprächen nicht so gut einschätzen, was die Leute nur sagen und was sie tatsächlich können. Leider erlebte ich schon, dass die Selbsteinschätzung und dementsprechend die Darstellung der Bewerber stark von der Wirklichkeit abwich.

Aber was sagt so ein Luschi-Test aus? Ich nehme mal an, dass er nur die totalen Blender ausfiltert, oder? Hat er sonst noch einen positiven Effekt?

Jetzt zum spaßigen Teil. In dem oben genannten Blog-Beitrag bringt jemand eine TSQL-Lösung:

declare @counter int
declare @output varchar(15)
set @counter = 1
while @counter < 101 begin set @output = '' if @counter % 3 = 0 set @output = 'Fizz' if @counter % 5 = 0 set @output = @output + 'Buzz' if @output = '' set @output = @counter print @output set @counter = @counter + 1 end

Diese Lösung gefällt mir besser:

SELECT
CASE WHEN number%15=0 THEN 'FizzBuzz'
WHEN number%3=0 THEN 'Fizz'
WHEN number%5=0 THEN 'Fizz'
ELSE CAST (number AS Varchar(10)) END AS "number"
FROM master.dbo.spt_values
WHERE type='P'
AND number BETWEEN 1 AND 100

Wem das zu wenig tricky ist, hier eine komplexere Lösung, die ohne Modulo auskommt:

SELECT
ISNULL(MAX(T.word),CAST (number AS Varchar(10))) AS "number"
FROM master.dbo.spt_values AS S
LEFT OUTER JOIN ( SELECT 3, 'Fizz' UNION
SELECT 5, 'Buzz' UNION
SELECT 15, 'FizzBuzz') AS T(num,word)
ON S.number%T.num=0
WHERE S.type='P'
AND S.number BETWEEN 1 AND 100
GROUP BY S.number

via Peter (er las es im JavaSPEKTRUM http://www.sigs.de/blog/js/?p=28)
23. August 2009 um 17:33

SQL Server API Server Cursors

Neben den modernen Datenbankzugriffsschichten wie ADO.net, LINQ oder Entity-Framework sind in den älteren Systemen meist noch die guten alten Schnittstellen wie ODBC und OLEDB im Einsatz. Um Daten zu holen gibt es hier nur die Möglichkeit Cursor zu öffnen. Die entsprechenden ODBC- oder OLEDB-Befehle rufen am SQL-Server Stored-Procedures auf, die die Cursorverwaltung und -abarbeitung übernehmen.

Bei sourceforge.net fand ich neulich zufällig eine Beschreibung dieser Prozeduren: "SQL Server API Server Cursors". Wer unbedingt Cursor benötigt, z.B. weil er die Daten seitenweise lesen muss, der könnte sich damit seine eigenen .net-Cursor schreiben…

22. August 2009 um 17:32

Small Basic

Durch die Zeitschrift DotNetPro wurde ich auf die neue Einsteiger-Programmiersprache von Microsoft aufmerksam: Microsoft Small Basic. Sie ist sehr einfach gehalten und richtet sich für Einsteiger in die Programmierung, z.B. Schüler. Das spricht mich sehr an, denn ich lernte auch mit einer sehr minimalistischen Programmiersprache die Softwareentwicklung.

Wenn ich mir vorstelle, dass Schüler mit Java oder C# einsteigen sollten, dann stelle ich mir das viel schwieriger vor als mit einer ganz simplen Sprache. Wir fingen damals in der 7ten mit programmierbaren Taschenrechnern an und stiegen erst in der nächsten Klasse auf Basic (damals auf Apple IIe) auf… 😉

Alles was man in dieser Phase können muss kann Small Basic. Und sonst kaum mehr. In der nächsten Stufe kann man sich dann in Konzepte wie objekt-orientierte Programmierung einarbeiten, aber für den Einstieg dürfte das für viele eine Nummer zu groß sein. Das Paket ist mit weniger als 4 MBytes denkbar klein und ist schnell installiert. Der einzige Haken: Die Entwicklungsumgebung ist komplett auf englisch. Aber ist das wirklich schlimm?

21. August 2009 um 17:28

Noch ein Gewinn? Und so viel gleich…

Manche Trick-Mails sind ja echt so was von peinlich… (Anmerkung: Da wo ich herkomme, drückt man den Superlativ so aus, Beispiel: blöd, blöder, sowas von blöd)

Received: from phpmailer ([82.159.84.218])
by 82.159.84.218 with HTTP (UebiMiau);
Sat, 25 Jul 2009 12:45:13 -0300
To: undisclosed-recipients:;
From: International Lotterie Promotion
Subject: Anspruch Information!!!


Anspruch Information!!!
Herzlichen Glückwunsch an Ihnen, wir können Ihnen die Ergebnisse der Europäische International Lotterie 2009 Promotion mitteilen. Wir sind glücklich Ihnen sagen zu können das Ihre E-Mail Addresse gezogen worden ist und Sie der Gewinner von €1.000.000.00 Euros(Eine Millionen Euro) sind.

ACHTUNG: Um Ihr Gewinn in Anspruch nehmen zu können, kontaktieren Sie bitte die Zahlungsabteilung per E-Mail oder per Telefon.

Kontakt Person: Herr David Lopez
Tel: 0034672822938
EMAIL ( claimoffice313@aim.com )

Beachten Sie bitte das Promotions Datum, die Referenz und Losnummer. Denken Sie bitte daran, bei allen Korrespondenz mit Ihrem Bearbeiter (Herr David Lopez) diese Nummern anzugeben.

Losnummer: SUTO/980/TWM/EU
Lotterie Ref. Nr:345/003/SP/45
Ticket Nr: WRNM/SMI/5990
Lucky Nr: 1 0-23-44-72-80
Serien Nr: MUOTI/82536
Lotterie Datum:15/06/2009.

Ihren Namen
Telefon Nummer
Handy Nummer
Ihr Alter, Geschlecht
Ihr Beruf

Herzlichen Glückwunsch nochmals von allen unseren Mitarbeiter und danke das Sie vertrauen an dieses E-Mail Lotterie Promotion Programm haben

Mit freundlichen Grüßen

Frau Mariam Javier

Ob "claimoffice34@aim.com" viele Antworten bekam in denen Name, Mailadresse, Telefonnummer, Alter, Geschlecht und Beruf drin stand?

Hier hat sich jemand den Spaß gemacht und die Kommunikation aufgenommen: In Wirklichkeit geht es nämlich gar nicht darum Adressen zu sammeln, sondern Geld von den vermeintlichen Gewinnern zu bekommen.

20. August 2009 um 17:32

Zelten unter Männern

Neulich waren wir mit 14 anderen Vätern und 30 anderen Kindern auf einer Vater-Kind-Freizeit unserer Gemeinde. Wir zelteten auf dem Campingplatz am Monte Kaolino (der heißt echt so). Es war echt klasse und ich lernte viel. Zum Beispiel, dass ich nächsten mal besser Luftmatratzen besorge, weil ich für Isomatten zu alt geworden bin… 😉

Nach einem Tag sah ich mit Besorgnis eine kleine Gruppe Jugendlicher nebenan ihr Zelt aufbauen. Die Fahne "100% Atze", die Bierkästen und die Wasserpfeife ließen schon Vorfreude auf die kommenden Nächte aufkommen. 🙁 Aber es kam ganz anders – man sollte niemanden in eine Schublade stecken: Die Jungs waren nett, freundlich und leise. Sie kamen vorbei und fragten ob die Musiklautstärke so für uns OK wäre (sie war genau richtig). Fragten freundlich wegen irgendwelcher Werkzeuge, die umgehend wieder gebracht wurden und mussten wohl mehr unter unserem Kinderlärm leiden als umgekehrt. Der eindeutige Tenor war, dass wir als Jugendliche wohl lauter gewesen wären… 😉

Auf Nachfrage sagten sie, dass Atze "Kumpel" bedeutet und nichts mit der prolligen Kunstfigur von Herrn Albers zu tun hat. Auf der Sommerrodelbahn wurden die Jungs dann Opfer einer echten Pistensau: Ihnen donnerte ein Schlitten derartig heftig hinten drauf, dass einer der Kumpel mit Schleudertrauma abgeholt wurde. Und was lernen wir daraus? Lieber genau hinschauen und sich selber eine Meinung bilden, anstelle sich vom ersten Anschein ein Bild zu machen. Sogar von garstigen Namen sollte man sich nicht gleich abschrecken lassen.

19. August 2009 um 17:30

Mehr als 7 Errorlogs

Bei jedem Start des SQL-Servers wird eine neue Errorlog-Datei angelegt. Die alten werden aber nicht sofort überschrieben. Stattdessen werden die letzten 6 beibehalten. Das gleiche kann man auch dediziert auslösen:

EXEC sp_cycle_errorlog

Dabei passiert Folgendes:

  • Datei "errorlog.6" wird gelöscht
  • Datei "errorlog.5" wird in "errorlog.6" umbenannt
  • Datei "errorlog.4" wird in "errorlog.5" umbenannt
  • Datei "errorlog.3" wird in "errorlog.4" umbenannt
  • Datei "errorlog.2" wird in "errorlog.3" umbenannt
  • Datei "errorlog.1" wird in "errorlog.2" umbenannt
  • Datei "errorlog" wird in "errorlog.1" umbenannt
  • Das neue "Errorlog" wird angelegt.

Man kann sich vom SQL-Server die Liste der aktuell verwalteten Errorlogs anzeigen lassen:
EXEC sp_enumerrorlogs

Beispiel:

Archiv-Nr. Datum Protokolldateigröße (Bytes)
0 08/24/2009 17:45 1468
1 08/24/2009 17:40 15956
2 08/23/2009 20:39 30462
3 08/23/2009 19:50 83076
4 08/23/2009 18:35 17160
5 08/23/2009 18:19 32608
6 08/22/2009 17:37 50104

Will man sich ein Errorlog ansehen, dann geht das mittels sp_readerrorlog:
EXEC sp_readerrorlog 0

Oder mit xp_readerrorlog: Hier gibt es mehr Parameter.
EXEC master.dbo.xp_readerrorlog 6, 1, 'Version', NULL, NULL, NULL, N'asc'

  • Nummer des Errorlogs
  • optional: Typ des Errorlogs: 1=SQL Server (Default), 2=SQL Agent
  • optional: Suchstring 1
  • optional: Suchstring 2
  • optional: Suchstring 3
  • optional: Sortierung "asc" (Default) oder "desc"

Mein Kollege Vladimir zeigte mir einen guten, aber undokumentierten Trick, wie die Anzahl der historischen Errorlogs erhöht werden kann. Dazu muss man unter [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer] den Key "NumErrorLogs" (REG_DWORD) z.B. auf "99" setzen. Wobei "MSSQL.1" für die Instanznummer steht. Die Liste der Instanzen und deren Numemrn steht unter [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL].

Hinweis: Wird der Wert von "99" dann wieder auf einen niedrigeren gesetzt, dann muss man selber dafür sorgen, dass die "alten" Errorlogs über der neuen Maximalzahl gelöscht werden.

Leider fand ich dazu so gut wie keine Infos, lediglich auf MS-Connect ist das mal offiziell erwähnt… 😉