SSIS-Pakete verteilen

Dieser Artikel soll erklären, welche einfache Möglichkeit es gibt, um Pakete zu verteilen, ohne die Konfiguration in den Paketen ändern zu müssen.

Ganze Geschichte »

Zeilenversionsverwaltung (Row Level Versioning)

Ein Feature, welches mit SQL Server 2005 gekommen ist und meiner Meinung nach bisher nur wenig Beachtung gefunden hat, ist die Möglichkeit auf eine Zeile zuzugreifen, während jemand anders in einer Transaktion eine Änderung durchführt und diese noch nicht mit Commit abgeschlossen hat. Bislang gab es nur die Möglichkeit des Dirty Read, mit dem Nachteil, dass man nie wusste, ob die gelesenen Daten überhaupt jemals Realität werden. Von Roy Ernest wurde auf SQLServerCentral im April 2008 ein Artikel publiziert, den ich im folgenden einfach als Übersetzung wiedergebe, da ich finde, dass hier alle wesentlichen Punkte angesprochen werden und diese gute Vorlage einfach verwenden möchte. Weitere Informationen zu dem Thema finden sich auch im TechNet, wobei Teile daraus bereits in diesem Artikel verwendet wurden.

Ganze Geschichte »

Serverweite Berechtigungen und verwaiste Benutzer

Ausgehend von der Fragestellung, einen Überblick über die Berechtigungen in den verschiedenen Datenbank eines Servers zu erstellen, fand ich die dahinter gelagerten Möglichkeiten auch recht reizvoll.

Nachdem ich bereits vor einigen Wochen ein kleines Skript gepostet habe, welches die Berechtigungen in einer Datenbank darstellt, kam jetzt die Anforderung auf, die Berechtigungen in allen Datenbanken eines ganzen Servers zu dokumentieren. Was lag da näher, als die undokumentierte Prozedur sp_MSforeachdb zu verwenden. Diese Prozedur befindet sich in der master-Datenbank und erwartet im einfachsten Falle einen Befehl, in dem das Fragezeichen als Platzhalter für den Datenbanknamen steht.

Beispielaufruf

exec sp_MSforeachdb @command1='use [?]; select db_name()'
Dieses Skript wechselt also zuerst den Datenbank-Kontext und ruft danach die Funktion zur Ermittlung des Datenbank-Namens auf.

Ermittlung der Berechtigungen

Hier deklariere ich zuerst eine Variable, der ich den Code der Abfrage zuweise und rufe danach die oben beschriebene Prozedur auf. Damit ich die Werte aber dauerhaft habe, lege ich vorher noch eine temporäre Tabelle an, die ich anschliessend für weitere Auswertungen verwenden kann. Hierbei fiel mir auf, dass in einigen Datenbanken WINDOWS_USER existieren, die Spalte Login aber NULL ist. Die Ursache war schnell gefunden: Das Login wurde auf dem Server gelöscht und der Benutzer blieb erhalten. Ähnliches kann auch passieren, wenn man eine Datenbank per Backup/Restore auf einen anderen Server bringt, wo nicht die gleichen Logins angelegt sind. Spontan fielen mir folgende Suchen ein:

  • WINDOWS_USER ohne Login
  • SQLUSER ohne Login
  • DBOs ohne Login

Ich denke, die Möglichkeiten dieser Sammlung werden schnell deutlich. Vielleicht fallen ja dem ein oder anderen noch interessante Ergänzungen ein, die er hier als Kommentar posten möchte.

  Berechtigungen in allen Datenbanken.sql

Anbindung von iSeries (sprich AS/400) an SQLServer2005

Dieser Artikel beschäftigt sich mit der Anbindung von iSeries-Systemen an den SQL Server 2005. IBM liefert entsprechende Client-Software, so dass diese sowohl über OLE-DB, als auch über ODBC erfolgen kann. Vorweg noch ein paar Worte zur Historie: Im Jahre 2000 wurde die AS/400 in iSeries umbenannt, im Oktober 2003 wurde der Name iSeries i5 geprägt, und seit 2006 gibt es die Modelle IBM System i5. Der neueste Name seit 2007 ist System i. Der alte Name hält sich aber hartnäckig und wird noch oft verwendet. In diesem Artikel verwende ich die Bezeichnung iSeries, da auch die Client-Software den Namen iSeries-Navigator trägt.

Ganze Geschichte »

Mehrere PIVOT-Ergebnisse in einem Resultset anzeigen

Der PIVOT-Operator bietet diese Funktionalität nur für eine Spalte. Wenn man mehrere PIVOT-Ergebnisse in einem Resultset haben möchte, kann man dies durch einen Join der beiden PIVOTs erreichen.

Set Nocount on

go
CREATE TABLE #p
( Year      SMALLINT,
  Quarter   TINYINT,
  Amount      DECIMAL(2,1) )
GO
INSERT INTO #p VALUES (1990, 1, 1.1)
INSERT INTO #p VALUES (1990, 2, 1.2)
INSERT INTO #p VALUES (1990, 3, 1.3)
INSERT INTO #p VALUES (1990, 4, 1.4)
INSERT INTO #p VALUES (1991, 1, 2.1)
INSERT INTO #p VALUES (1991, 2, 2.2)
INSERT INTO #p VALUES (1991, 3, 2.3)
INSERT INTO #p VALUES (1991, 4, 2.4)
GO

-- Ohne schöne Spaltenüberschrift
select a.year, a.[1], a.[2], a.[3], a.[4], b.[1], b.[2], b.[3], b.[4]
from
(SELECT * FROM #p
PIVOT (sum(Amount) FOR Quarter IN ( [1],[2],[3],[4] )) as x) a,
(SELECT * FROM #p
PIVOT (count(Amount) FOR Quarter IN ( [1],[2],[3],[4] )) as y) b
where a.year = b.year
GO

-- Mit schöner Spaltenüberschrift
select a.year, a.Q1, a.Q2, a.Q3, a.Q4, b.Count_Q1, b.Count_Q2,
b.Count_Q3, b.Count_Q4
from
(SELECT year, [1] AS Q1,[2] AS Q2,[3] AS Q3, [4] AS Q4
FROM
(SELECT * FROM #p) AS #p
PIVOT (sum(#p.Amount) FOR #p.Quarter IN ( [1],[2],[3],[4] )
) AS x) a,
(SELECT year, [1] AS Count_Q1,[2] AS Count_Q2,[3] AS Count_Q3, [4] AS
Count_Q4
FROM
(SELECT * FROM #p) AS #p
PIVOT (count(#p.Amount) FOR #p.Quarter IN ( [1],[2],[3],[4] )
) AS x) b
where a.year = b.year


go
drop Table #p

  Pivot SQL