Overblog
Folge diesem Blog Administration + Create my blog
Blog von Olaf Helper
Neueste Posts

T-SQL Objekt-Definitionen durchsuchen

22. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

Bei Designänderungen Im MS Sql Server muss man alle eventuellen Seiteneffekte beachten, spricht man muss prüfen, welche Auswirkungen die Änderungen auf abhängige Objekte haben. Natürlich hat man alles gut dokumentiert, so dass man schnell herausfindet, welche Objekte eben abhängig von einem anderen sind.

Aber nur um ganz sicher zu gehen ;-), kann man die Objekt-Definitionen auch in der Datenbank per SQL durchsuchen lassen, schließlich muss der SQL Server es ja am besten wissen, wie was zusammenhängt.

Mit dem folgenden Script kann man das erledigt. Wie immer gibt es eine kleine Einschränkung, verschlüsselt angelegte Objekte, also die mit der Option ENCRYPTION, können natürlich nicht im Klartext durchsucht werden; CLR Assemblies erst recht nicht; ist logo.
 

 SELECT OBJ.name, OBJ.xtype, PAR.name AS Parent, 
  COM.Text 
 FROM sys.syscomments AS COM 
  INNER JOIN 
  sys.sysobjects AS OBJ 
  ON COM.id = OBJ.id 
  LEFT JOIN  
  sys.sysobjects AS PAR 
  ON PAR.id = OBJ.parent_obj 
 WHERE OBJ.xtype IN ('P ', 'TR', 'FN', 'V ') 
  AND COM.Text LIKE '%SalesPerson%' 
 ORDER BY OBJ.xtype, OBJ.name, PAR.name 

 

Ergebnis:



Hier noch eine zweite Variante, die das Systemview sys.sql_modules verwendet:

 -- Objektdefinition nach Begriffen durchsuchen 
 SELECT OBJSCH.name AS ObjectSchema, OBJ.name AS ObjectName, 
  OBJ.type_desc AS ObjectType, 
  PARSCH.name AS ParentSchema, PAR.name AS ParentName, 
  PAR.type_desc AS ParentType, 
  MOD.definition,  
  OBJ.create_date, OBJ.modify_date 
 FROM sys.sql_modules AS MOD 
  INNER JOIN sys.objects AS OBJ 
  ON MOD.object_id = OBJ.object_id 
  INNER JOIN sys.schemas AS OBJSCH 
  ON OBJ.schema_id = OBJSCH.schema_id 
  LEFT JOIN sys.objects AS PAR 
  ON PAR.object_id = OBJ.parent_object_id 
  LEFT JOIN sys.schemas AS PARSCH 
  ON PAR.schema_id = PAR.schema_id 
 WHERE MOD.definition LIKE '%SalesPerson%' 
 ORDER BY OBJ.name, PAR.name 

 

Weiterlesen

Beispiel & Sourcen zu Wrox-Büchern

21. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #MSSQL

Um mich in MS SQL Server - Analysis Services und MDX einzuarbeiten, hatte ich mich nach Büchern zum Thema umgesehen. Da ich unter den deutschsprachigen keins gefunden hatte, was mich ansprach, habe ich mir vom amerikanischen Verlag Wrox das Buch Buch „Professional SQL Server Analysis Services 2005 with MDX" gekauft.


Obwohl mein (Fach-) Englisch (noch) nicht unbedingt das Allerbeste ist, lässt es sich wirklich sehr gut lesen (und ich lerne so das fehlende Fachvokabular hinzu).
Sehr gut finde ich die Best-Practice Tipps und die Hinweise, was man besser nicht macht oder nur mit Vorsicht zu genießen ist, weil es Performance-Einbusen bringen kann.

Wen es interessiert, zu diesem und anderen Büchern des Verlages kann man frei die Beispiel & Sourcen herunter laden, für das meine hier.

Wenn man aus der Übersicht, z.B. der für den MS SQL Server, die Details öffnet, findet man i.d.R. oben den Link „Download Code"

Weiterlesen

Wer blockiert wen … oder wird es vielleicht bald?

21. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

In den letzten Wochen ist es ein paar mal vorgekommen, das ein User einen längeren Prozess angestartet hatte, der Client bzw. die Citrix-Session brach ab, der Prozess auf dem SQL Server blieb bestehen und blockierte durch seine Sperren andere. Bis Helpdesk die Session rausgesucht und zwangsweise beendet hat, geht doch etwas Zeit ins Land. Da habe ich schneller den Prozess auf dem MSSQL beendet, so dass der Betrieb weiter gehen kann.

Nur auch der „Aktivitätsmonitor“ vom Management Studio ist etwas sehr träge und in so einem Fall muss man genauso erst suchen, bis man den Verursacher gefunden hat.

Ein kleines T-SQL Script dazu ist effizienter und das Ergebnis lässt sich fix per <F5> aktualisieren. Es listet alle blockierten Prozess und alle mit einer offenen Transaktion auf; man bekommt also immer den Verursacher mit seinen "Opfern" zu sehen.

 
-- Welcher Process blockiert welchen Process und das ggf. rekursive
 -- Ebenso werden alle Processe mit offenen Transaction angezeigt, 
 -- die somit zur Blockade werden könnte. 
 SELECT PRO.spid, PRO.blocked, 
PRO.waitresource, PRO.waittime,
  PRO.last_batch, PRO.status, 
PRO.open_tran, PRO.hostname,
  PRO.program_name, PRO.loginame, 
DBS.name as DatabaseName
 FROM sys.sysprocesses AS PRO 
  INNER JOIN sys.sysdatabases AS DBS 
  ON PRO.dbid = DBS.dbid 
 WHERE PRO.blocked <> 0  
  OR PRO.open_tran > 0 
 ORDER BY PRO.blocked ASC, PRO.spid ASC 
Weiterlesen

VARCHAR(MAX) Textbehandlung mittels .WRITE

20. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

 Bis einschließlich SQL Server 2000 konnte man lange Texte, größer 8KB, nur als LOB (large object) ablegen. Dadurch war das „Bearbeiten“ von diesen Texten per T-SQL entsprechend kompliziert und umständlich. 
 Mit SQL Server 2005 wurde dann der neue Datentyp VARCHAR(MAX) und damit auch die neue .WRITE-Syntax eingeführt, dass es einem etwas vereinfacht.
 UPDATE  
  { { <object> } 
 SET  
  { { column_name { .WRITE ( expression , @Offset , @Length ) } 
   

Bei der Syntax vermisst man zunächst das Gleichheitszeichen, aber .WRITE (Punkt Write) stellt eine statische Funktion zum Datentypen VARCHAR(MAX) da.
Hier ein Beispiel T-SQL Script zur Verwendung der Funktion:

 SET NOCOUNT ON 
 -- Temporäre Tabelle anlegen 
 CREATE TABLE ##myLongText 
  (ID int NOT NULL PRIMARY KEY, 
   LongText varchar(max)); 
 GO 
 --Einen Beispielsatz einfügen 
 INSERT INTO ##myLongText  
 VALUES (1, 'Ich werde später einmal ein langer Textblock'); 
 -- Kontrollausgabe 
 SELECT * FROM ##myLongText; 
   
 --Text innen einfügen 
 UPDATE ##myLongText 
 SET LongText .Write(', wenn ich groß bin,', 16, 0) 
 WHERE ID = 1; 
 SELECT * FROM ##myLongText; 
   
 -- Text innen ersetzen 
 UPDATE ##myLongText 
 SET LongText .Write('alt', CHARINDEX('groß', LongText, 1) - 1, LEN('groß')) 
 WHERE ID = 1; 
 SELECT * FROM ##myLongText; 
   
 -- Textende ersetzen  
 UPDATE ##myLongText 
 SET LongText .Write('Artikel', 54, NULL) 
 WHERE ID = 1; 
 SELECT * FROM ##myLongText; 
   
 -- Am Textende anfügen 
 UPDATE ##myLongText 
 SET LongText .Write(' in einem Blog', LEN(LongText), NULL) 
 WHERE ID = 1; 
 SELECT * FROM ##myLongText; 
   
 DROP TABLE ##myLongText; 
   
 Ergebnis: 
   
 ID LongText 
 ----------- ----------------------------------------------------------------- 
 1 Ich werde später einmal ein langer Textblock 
   
 ID LongText 
 ----------- ----------------------------------------------------------------- 
 1 Ich werde später, wenn ich groß bin, einmal ein langer Textblock 
   
 ID LongText 
 ----------- ----------------------------------------------------------------- 
 1 Ich werde später, wenn ich alt bin, einmal ein langer Textblock 
   
 ID LongText 
 ----------- ----------------------------------------------------------------- 
 1 Ich werde später, wenn ich alt bin, einmal ein langer Artikel 
   
 ID LongText 
 ----------- ----------------------------------------------------------------- 
 1 Ich werde später, wenn ich alt bin, einmal ein langer Artikel in einem Blog 
   
Weiterlesen

Microsoft SQL Server Release Services

20. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #MSSQL

Wer es noch nicht kennt, es gibt den Blog „Microsoft SQL Server Release Services“, wo alle veröffentlichten Updates bekannt geben werden.

Aktuell sind es „Cumulative Update #1 for SQL Server 2005 Service Pack 3“ und “Cumulative Update #3 for SQL Server 2008 RTM”.

Weiterlesen

INSERT INTO / SELECT FROM … Multiple-Values

19. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

Wenn man mal eben ein paar Werte / Zeile braucht, um Logiken u.ä. zu testen, dann hat man bis zum MS SQL Server 2005 meist ein temporäre Tabelle angelegt, ein paar Daten eingefügt und die dann verwendet; sah dann so aus: 

 CREATE TABLE #Dummy 
  (NumFeld int, Datum datetime); 
 -- Einzeln per Hand 
 INSERT INTO #Dummy (NumFeld, Datum) VALUES (1, GETDATE()); 
 INSERT INTO #Dummy (NumFeld, Datum) VALUES (2, GETDATE()); 
 INSERT INTO #Dummy (NumFeld, Datum) VALUES (3, GETDATE()); 
 -- oder per SELECT UNION 
 INSERT INTO #Dummy (NumFeld, Datum) 
 SELECT 4, GETDATE() UNION ALL 
 SELECT 5, GETDATE() UNION ALL 
 SELECT 6, GETDATE() 

 

Ab dem MS SQL Server 2008 kann man nun auch „Multiple Values“ angeben. Zugegeben, nicht unbedingt ein riesiges neues Feature, aber es ist recht praktisch, da es Tipparbeit spart. 

 -- Multiple Values ab MSSQL2008 
 INSERT INTO #Dummy (NumFeld, Datum) 
 VALUES (7, GETDATE()), 
  (8, GETDATE()), 
  (9, GETDATE()) 
 SELECT * FROM #Dummy  
 DROP TABLE #Dummy; 
 GO 

 


Man kann sich nun aber auch die temporäre Tabelle sparen und VALUES gleich als „derivated table“ verwenden, mit dem Alias gibt man dann die Feldnamen an und mit dem ersten VALUES kann man den Datentypen explizit festlegen:

 SELECT * 
 FROM (VALUES(CAST(1 AS smallint), CAST('20090118' as datetime)), 
  (2, GetDate()), 
  (3, GetDate()) 
  ) AS myValues(NumFeld, Datum) 
   
Weiterlesen

Größe zu allen Objekten ermitteln

16. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

Die Größe seiner MS SQL Server Datenbanken hat man im Allgemeinen immer im Blick. Nur wie teilt sich das auf meine Objekte und dort auf die Daten, Indizes etc. auf?

Mittels
 

EXEC sp_spaceused @objname = 'Schema.Objectname'


kann man es sich je Objekt ausgeben lassen, nur ist das etwas müßig, wenn man es für mehrere haben möchte.

Also habe ich ein kleines T-SQL Script geschrieben, das per Cursor für alle Objekte die Größe ermitteln lässt, das Ergebnis in eine temporäre Tabelle schreibt und das kann man dann schön auswerten; ist das T-SQL Script dazu; funktioniert ab MS SQL Server 2000:

 -- Größe aller Objekte ermitteln 
 SET NOCOUNT ON 
 DECLARE @Update varchar(5), 
  @SchemaObject varchar(257), 
  @Type varchar(2); 
 -- Soll die Usage aktualisiert werden ? true/false 
 SET @Update = 'false'  
   
 -- Temporäre Tabelle anlegen 
 CREATE TABLE ##ObjectSize 
  (name nvarchar(128) NOT NULL, 
  rows char(11) NULL, 
  reserved varchar(18) NULL, 
  data varchar(18) NULL, 
  index_size varchar(18) NULL, 
  unused varchar(18) NULL); 
 -- Cursor über alle Objekte 
 DECLARE AllObjs CURSOR LOCAL FOR 
  SELECT S.name + '.' + O.Name AS SchemaObject, O.type 
  FROM sys.objects AS O 
  INNER JOIN 
  sys.schemas AS S 
  ON O.schema_id = S.schema_id  
  WHERE O.type IN ('U ', 'S ', 'V ', 'SQ', 'IT') 
 -- Mittels Cursor zu allen Objecten die Größe ermitteln 
 OPEN AllObjs 
 FETCH NEXT FROM AllObjs INTO @SchemaObject, @Type 
 WHILE @@FETCH_STATUS = 0 
 BEGIN 
  IF @Type IN ('V ', 'SQ') 
  INSERT INTO ##ObjectSize 
  EXEC sp_spaceused @objname = @SchemaObject -- Kein Update 
  ELSE 
  INSERT INTO ##ObjectSize 
  EXEC sp_spaceused @objname = @SchemaObject, @updateusage = @Update 
   
  FETCH NEXT FROM AllObjs INTO @SchemaObject, @Type 
 END 
 CLOSE AllObjs 
 DEALLOCATE AllObjs 
   
 -- Die Daten haben wir, aber in unbrauchbaren Textformat 
 -- => In Nums umwandelt 
 ALTER TABLE ##ObjectSize 
  ADD ireserved bigint NULL, 
  idata bigint NULL, 
  iindex_size bigint NULL, 
  iunused bigint NULL 
 -- KB bleibt, MB in KB umsetzen, nach bigint wandeln 
 -- NULL bleibt wie es ist 
 UPDATE ##ObjectSize 
 SET ireserved = CONVERT(bigint, REPLACE(REPLACE(reserved, ' KB', ''), ' MB', ''))  
  * CASE WHEN RIGHT(reserved, 2) = 'MB' THEN 1024 ELSE 1 END, 
  idata = CONVERT(bigint, REPLACE(REPLACE(data, ' KB', ''), ' MB', '')) 
  * CASE WHEN RIGHT(data, 2) = 'MB' THEN 1024 ELSE 1 END, 
  iindex_size = CONVERT(bigint, REPLACE(REPLACE(index_size, ' KB', ''), ' MB', '')) 
  * CASE WHEN RIGHT(index_size, 2) = 'MB' THEN 1024 ELSE 1 END, 
  iunused = CONVERT(bigint, REPLACE(REPLACE(unused, ' KB', ''), ' MB', '')) 
  * CASE WHEN RIGHT(unused, 2) = 'MB' THEN 1024 ELSE 1 END 
 -- Details auslesen, abst. sortiert nach Gesamtgröße 
 SELECT * 
 FROM ##ObjectSize 
 ORDER BY ISNULL(ireserved, 0) DESC, ISNULL(idata, 0) DESC, 
  ISNULL(iindex_size, 0) DESC, ISNULL(iunused, 0) DESC, 
  ISNULL(rows, 0) DESC 
 -- und Gesamtsummen 
 SELECT SUM(ISNULL(ireserved, 0)) AS ReservedSum, 
  SUM(ISNULL(idata, 0)) AS DataSum, 
  SUM(ISNULL(iindex_size, 0)) AS IndexSizeSum, 
  SUM(ISNULL(iunused, 0)) AS UnusedSum 
 FROM ##ObjectSize 
 -- DB Größe 
 EXEC sp_spaceused 
 -- Temp abräumen 
 DROP TABLE ##ObjectSize 
Weiterlesen

Microsoft SQL Server Protocol Documentation

16. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #Download MSSQL

Wer Interesse an technischen Dokumentationen zum MS SQL Server 2008, es gibt die „Microsoft SQL Server Protocol Documentation“ zum Download.

Weiterlesen

Access 2007 Download: Access Developer Extensions

16. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #Office

Die aktuellen kostenlose „Developer Extensions für MS Access 2007“ gibt es zum Download in Deutscher und Englischer Version.

Es enthält unter anderem Tools zum Erstellen und Bereitstellen von Runtime-Version von Access Anwendungen.

Weiterlesen

Wo finde ich es in Office 2007 wieder?

15. Januar 2009 , Geschrieben von Olaf Helper Veröffentlicht in #Office

Wenn man von Office 2003 oder einer vorigen Version auf Office 2007 wechselt, dann stehen die meisten erst mal wie der Ochs vorm Berg und fragt sich, wo ist das nur abgeblieben? Geht mir jedenfalls so und anderen wohl auch.

 

Zum Download:

 

Als Online-Variante:

 

Weiterlesen
<< < 10 20 21 22 23 24 > >>