Installationsobjekte identifizieren
Jul 12th
USE MASTER GO SELECT CASE OBJECTPROPERTY(id, 'IsMSShipped') WHEN 1 THEN 'Bei Installation erzeugt' WHEN 0 THEN 'Nicht bei Installation erzeugt' END AS [Bei Installation Erzeugt] , CAST(name AS CHAR(30)) AS [name] FROM sysobjects WHERE name = 'sp_helpdb' OR name = 'sp_MBL_SORT' Bei Installation Erzeugt name ------------------------------ ------------------------------ Bei Installation erzeugt sp_helpdb Nicht bei Installation erzeugt sp_MBL_SORT (2 row(s) affected)
Nicht-Unicode Spalten ermitteln
Jul 12th
SELECT
OBJECT_NAME(Id) as [Table]
, name as [Column]
, TYPE_NAME(xusertype) as Type
FROM SysColumns
WHERE TYPE_NAME(xusertype)
IN ('varchar','char')
AND ID IN
(SELECT ID
FROM SysObjects
WHERE xtype = 'U')
ORDER BY OBJECT_NAME(Id), Name
Die Ergebnismenge wird hier nicht wiedergegeben, da sie in der Regel sehr umfangreich ist. Ändert man
WHERE xtype = 'U')
in
WHERE xtype = 'P')
erhält man das Ergebnis für Gespeicherte Prozeduren.
Datumsteile extrahieren
Jul 12th
SELECT
DATEPART(yy , GETDATE()) AS Jahr
, DATEPART(qq , GETDATE()) AS Quartal
, DATEPART(mm , GETDATE()) AS Monat
, DATEPART(dd , GETDATE()) AS Tag
, DATEPART(hh , GETDATE()) AS Stunden
, DATEPART(mi , GETDATE()) AS Minuten
, DATEPART(ss , GETDATE()) AS Sekunden
, DATEPART(ms , GETDATE()) AS Millisekunden
, DATEPART(wk , GETDATE()) AS Woche
Jahr Quartal Monat Tag Stunden Minuten Sekunden Millisekunden Woche
--------- --------- --------- --------- --------- --------- --------- ------------- -----
2004 2 6 23 11 23 59 513 26
(1 row(s) affected)
Weitere Informationen stehen in BOL.
Clustered Index löschen
Jul 12th
Generell gilt, daß Indexes Datenabfragen enorm beschleunigen können. Nachteil aber ist, daß Änderungen an den Daten sich auch in Änderungen in den Indexes manifestieren, falls die entsprechenden Spalten, die von der Änderung betroffen sind, auch gleichzeitig Teil eines oder mehrerer Indexes sind. Indexes aber sind kein starres Konzept, von dem man nicht abweichen darf. So macht es zum Beispiel durchaus Sinn, vor dem Auffüllen einer Tabelle durch einen Massenimport, vorhandene Indexes auf der Tabelle zu löschen, um den Import zu beschleunigen und vielleicht innerhalb eines vorgegebenen Zeitfensters beenden zu können. Die Frage, ob in einem solchen Fall nicht besser die gesamte Tabelle gelöscht und neu erstellt wird, ignorieren wir an dieser Stelle. Sie ist ein eigenes Thema und nicht Gegenstand dieser Betrachtung.
Bevor wir uns mit den Gründen beschäftigen, warum das Löschen eines Clustered Indexes zeitintensiv sein kann, müssen wir einen kurzen Blick auf die verschiedenen Indexstrukturen werfen.
Jede Tabelle im SQL Server kann genau einen Clustered Index haben. Da der Clustered Index die Daten gemäß seiner Schlüssel sortiert, erscheint das auch einleuchtend. Besitzt eine Tabelle keinen Clustered Index, so wird diese auch als Heap bezeichnet.
Die zweite Indexstruktur im SQL Server sind Nonclustered Indexes. Sie können auf Tabellen mit Clustered Index, Heaps und Indexed Views erstellt werden.
Der Unterschied zwischen beiden Indexformen zeigt sich auf der Blattebene. Während sich dort bei einem Clustered Index die eigentlichen Daten befinden, findet man bei einem Nonclustered Index dort Verweise darauf, wo die eigentlichen Daten zu finden sind. Zwei Unterscheidungen muß man jetzt begreifen:
- Besitzt die Tabelle einen Clustered Index, besteht der Verweis aus den Schlüsseln des Clustered Index für diese Zeile.
- Besitzt die Tabellen keinen Clustered Index enthält dieser Verweis die sogenannte RowID (RID), die sich aus FileNumber:Seitennummer:Slot der Zeile zusammensetzt.
Aus diesem Sachverhalt kann man bereits ableiten, wie die effektivste Abfolge beim Löschen von Indexes aussieht. Beim Löschen eines Clustered Index muss SQL Server alle Nonclustered Indexes neu erstellen. Dabei werden die Schlüssel des Clustered Index in den Nonclustered Indexes durch die RID zu den Zeilen ersetzt. Es leuchtet ein, daß dies bei umfangreichen Tabellen und vielen Indexes schon mal Zeit in Anspruch nehmen kann. Die empfohlene Methode ist laut BOL:
"Beim Erstellen von Indizes für umfangreiche Tabellen sollten Sie möglichst mit dem gruppierten Index beginnen und dann die nicht gruppierten Indizes erstellen. Beim Löschen aller Indizes sollten Sie zunächst die nicht gruppierten Indizes und zum Schluss den gruppierten Index löschen. Auf diese Weise müssen keine Indizes neu erstellt werden."
tempDB in den Arbeitsspeicher laden
Jul 12th
In SQL 6.5 gibt es eine Einstellungen 'tempdb in RAM'. Ab Version 7 wird dies nicht mehr unterstützt. Microsoft ist der Ansicht, daß die internen Zugriffe genügend optimiert sind, um dies unnötig zu machen
Unterschied zwischen OSQL und ISQL
Jul 12th
ISQL.exe erkennt keine 'named instances'. Weitere Unterschiede werden in BOL aufgelistet.
Für die meisten Anwendungsgebiete ist wahrscheinlich OSQL die bessere Alternative. Nicht zuletzt deshalb, weil ISQL noch mit der DB-Library arbeitet, die nicht alle Features von SQL Server 2000 unterstützt. während OSQL auf ODBC Basis arbeitet. Eine Übersicht über Unterschiede zwischen beiden findet man unter dieser BOL URL:
Systemobjekte unsichtbar machen
Jul 12th
Vielfach wird diese Frage gestellt, nachdem man Nicht-Administratoren den Zugang zu solchen Tools wie dem Enterprise Manager und/oder Query Analyzer gegeben hat.
AFAIK, ist es nicht möglich im Enterprise Manager nur die Datenbanken anzeigen zu lassen, zu denen ein Benutzer Zugriff hat. Es werden stets alle angezeigt, aber bei denjenigen, auf die der Benutzer keinen Zugriff hat, erfolgt eine entsprechende Meldung. Was man allerdings machen kann, ist die Systemobjekte des Servers auszublenden. Dies geschieht wie folgt:
Rechtsklick auf den Server Knoten in EM ->Edit Sql Server Registration Properties ->Haken entfernen aus 'Show system db's and properties'
Die aber vielleicht wichtigere Frage lautet: Wer sollte Zugriff auf die Administrationstools des Servers haben und warum? Neben lizenzrechtlichen Problemen, sind vor allem sicherheitsrelevante Fragen zu klären. Im allgemeinen ist es keine gute Idee, diese Tools an die Hände von Nicht-Administratoren zu geben. Schon gar nicht mit Zugriff auf Produktivsystemen!
SQL Server Version ermitteln
Jul 9th
Oftmals muss man schnell in der Lage sein, angeben zu können, mit welcher Version des SQL Server man arbeitet. Sei es, wenn man mit dem Microsoft Support telefoniert, sei es, um festzustellen, ob das aktuellste Service Pack installiert ist. Gründe gibt es genug. Die einfachste Möglichkeit, um dies herauszufinden, besteht darin im Query Analyzer folgenden Befehl abzuschicken:
SELECT @@version
-------------------------------------------------------------------------
Microsoft SQL Server 2000 - 8.00.760 (Intel X86)
Dec 17 2002 14:22:05
Copyright (c) 1988-2003 Microsoft Corporation
Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 1)
(1 row(s) affected)
--Alternativen dazu:
SELECT
CAST(SERVERPROPERTY ('productversion') AS CHAR(30))
, CAST(SERVERPROPERTY ('productlevel') AS CHAR(30))
, CAST(SERVERPROPERTY ('edition') AS CHAR(30))
------------------------------ ------------------------------ ------------------------------
8.00.760 SP3 Developer Edition
(1 row(s) affected)
Das CAST im obigen Beispiel ist nicht notwendig, ich verwende es hier nur wegen der einfacheren Formatierung :-) Schliesslich kann man noch ausführen:
exec master..xp_msver
Index Name Internal_Value Character_Value
------ -------------------------------- -------------- -----------------------------------
1 ProductName NULL Microsoft SQL Server
2 ProductVersion 524288 8.00.760
3 Language 1031 Deutsch (Deutschland)
4 Platform NULL NT INTEL X86
5 Comments NULL NT INTEL X86
6 CompanyName NULL Microsoft Corporation
7 FileDescription NULL SQL Server Windows NT
8 FileVersion NULL 2000.080.0760.00
9 InternalName NULL SQLSERVR
10 LegalCopyright NULL © 1988-2003 Microsoft Corp. All ...
11 LegalTrademarks NULL ...
12 OriginalFilename NULL SQLSERVR.EXE
13 PrivateBuild NULL NULL
14 SpecialBuild 49807360 NULL
15 WindowsVersion 170393861 5.1 (2600)
16 ProcessorCount 1 1
17 ProcessorActiveMask 1 00000001
18 ProcessorType 586 PROCESSOR_INTEL_PENTIUM
19 PhysicalMemory 511 511 (535740416)
20 Product ID NULL NULL
(20 row(s) affected)
