Benutzer:

Passwort:

Claus Rothe

Derzeit im Umbau... Dient vor allem meinem privaten Zweck, wer es trotzdem findet, viel Spaß. ;)


Datenbank Blog

2011-03-18: Except vs. Intersect

Diese Befehle dienen dem Vergleich von Abfrageergebnissen. Während Except die Zeilen bringt, die in der linken Abfrage vorhanden sind, aber nicht in der rechten, soll Intersect dieses in beide Richtungen machen so zumindest verstehen die meisten die Dokumentation von Microsoft.
Sprich als erstes denkt man folgende Statements wären identisch:

 (
	select * from a
	except
	select * from b
)
union all
(
	select * from b
	except
	select * from a
)

 select * from a
intersect
select * from b

Leider ist dieses nicht der Fall. Es ist genau das Gegenteil! Intersect zeigt die Übereinstimmungen an!
Machen wir ein klares Beispiel:

 create table a  
( a int null)
create table b  
( b int null)

insert into a VALUES(null)
insert into a VALUES(1)
insert into a VALUES(2)
insert into a VALUES(3)
insert into b VALUES(null)
insert into b VALUES(2)
insert into b VALUES(3)
insert into b VALUES(4)

In Tabelle A ist der Wert 1 und in Tabelle B ist der Wert 4 allein Vorhanden. Dementsprechnd Ergeben sich folgende

 select * from a
except
select * from b

Ergebnis:

 a
-----------
1

(1 Zeile(n) betroffen)


 select * from b
except
select * from a

Ergebnis:

 b
-----------
4

(1 Zeile(n) betroffen)


Soweit so klar, wer jetzt denkt das Intersect 1 und 4 ergibt, liegt falsch!

 select * from a
intersect
select * from b

Ergebnis:

 a
-----------
NULL
2
3

(3 Zeile(n) betroffen)


Es sind also die Übereinstimmungen die ausgegeben werden.
Was hierbei auch zu beachten ist, NULL = NULL! Im Gegensatz zur normalen Handhabung das immer NULL != NULL ist.

Die Microsoft Doku Teil 1
Die Microsft Doku Teil 2 mit Beispiel
Im Database Journal sieht man es genauso.

2011-03-09: Contains Performance Fehler

Beim SQL Server 2008 / 2008 R2 hat sich ein sehr verehrender Fehler mit Contains eingeschlichen. Durch die doppelte Verwendung von Contains in einem Statement steigt die Ausführungszeit exorbitant. Ein Beispiel:

select  a.* from A 
Inner join B
on A.B_ID = B.ID
Inner join C
on A.C_ID = C.ID
where contains(B.*,N'Suchwort')
and contains(C.*,N'Suchwort')

In der Regel wird für jede Zeile aus der Tabelle A der Volltextindex von Tabelle B und Tabelle C durchsucht, statt dieses nur einmal zu machen. Ausführungszeiten vom 100- fachen sind durchaus normal!
Dieses ist ein bekannter Bug in SQL Server 2008 und SQL Server 2008 R2. Behoben ist dieser erst in SQL Server 2011! Für 2008 und 2008 R2 ist auch kein Bugfixing angekündigt.
Aber für den gewieften SQL Programmierer gibt es hier einfache Lösungen. Die eleganteste ist der Einsatz von Containstable.
Hier das Beispiel:

select  a.* from A 
Inner join containstable(B, *, N'Suchwort') as B
on A.B_ID = B.[KEY]
Inner join containstable(C, *, N'Suchwort') as C
on A.C_ID = C.[KEY]


Schwieriger wird es, wenn die Foreign Keys andersherum sind:

select  a.* from A 
Inner join B
on A.ID = B.A_ID
Inner join C
on A.ID = C.A_ID
where contains(B.*,N'Suchwort')
and contains(C.*,N'Suchwort')


In diesem Fall hilft es so vorzugehen:

select  a.* from A 
Inner join B
on A.ID = B.A_ID
Inner join C
on A.ID = C.A_ID
Inner join containstable(B, *,N'Suchwort') as B
on B.ID = B.[KEY]
Inner join containstable(C, *,N'Suchwort') as C
on C.ID = C.[KEY]

Auch diese Variante ist wesentlich schneller als mit 2 Contains zu arbeiten.
Alternativ kann man noch mit temporären Tabellen arbeiten.

2011-03-07: Ist das Objekt schon da?

Zum Wochenanfang mal was ganz einfaches, wie überprüfe ich, ob eine Tabelle schon da ist?

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tabellenname]') AND type in (N'U'))
...

2011-03-07: Exec mit dynamischer Serverangabe

Und mal wieder ein kleines Beispiel mit dem Verschachteln von Befehlen @Server beinhaltet den Namen des Remoteservers.

exec('exec(''truncate table [Database].[dbo].[Table]'') at ['+@server+']')

2011-03-01: IFilter für die Volltextsuche

Die Volltextsuche vom MS SQL Server beherrscht von Haus aus das Durchsuchen von Dateien. Hierfür stehen aber bei einer „Nackten“ Installation nur wenige Dateitypen zur Verfügung. Um zu sehen welche das sind kann man folgendes SQL ausführen:

EXEC sp_help_fulltext_system_components 'filter';

Um zusätzliche Dateien zu unterstützen muss man sogenannte IFilter installieren. Diese sind für die Microsoft Volltextsuche (also auch Windows oder Sharepoint). Die wichtigsten sind sicherlich die für MS Office 2007+, Outlook MSG Dateien und PDF.
Die Unterstützung von MS Office 2007+ und MSG Dateien kann man durch die Microsoft IFilter für Office 2010 installieren.
Für PDF sucht man ein wenig länger um heraus zu finden, dass man nur den aktuellen Acrobat Reader auf dem Server installieren muss. Dieser bringt die IFilter bereits mit.
Nach der Installation der Komponenten muss man im SQL Server noch folgendes Script ausführen um sie für die Volltextsuche zu aktivieren. Bereits bestehende Volltextindices müssen neu gefüllt werden!

 -- Läd die Filter aus dem System neu
EXEC sp_fulltext_service @action='load_os_resources', @value=1;
-- Aktualisiert die SQL Server IFilterliste
EXEC sp_fulltext_service 'update_languages';
-- Neustart des Volltextdienstes
EXEC sp_fulltext_service 'restart_all_fdhosts';



Die Doku von Microsoft gibt’s hier.


Seite zurück [1] [2] [3] [4] [5] [6] Seite weiter

Impressum

Claus Rothe

Mobil: +49 176 81188859

E-Mail: post@...