Home > SQL-Server 2005 > ‘virtuelle’ Arrays mit T-SQL

‘virtuelle’ Arrays mit T-SQL

In T-SQL sind per Definition keine Arrays vorgesehen. Es gibt jedoch Fälle in denen der Einsatz eines Arrays von Vorteil wäre.

In einem konkreten Fall soll eine Prozedur einen Datenwert als Parameter erhalten. Dieser Wert wird jedoch in den, für die Abfrage zugrundeliegenden Tabellen nicht direkt verwendet. Vielmehr wird auf den Parameterwert nur indirekt über den Primärschlüssel (IdentityFeld) der Schlüsseltabelle verwiesen.

In der Prozedur müsste jetzt eine Abfrage in der Form:

 T-SQL |  copy code |? 
1
SELECT <feldliste>
2
FROM <komplexe Abfrage>
3
    join Schlüsseltabelle ON Code =
4
<parameterwert>

erstellt werden.

Grundsätzlich ist dagegen ja nichts einzuwenden. Wenn der Join gegen die Schlüsseltabelle jedoch die Laufzeit des Gesamtstatements spürbar verlängert und zusätzlich in der Prozedur dieser Join mehrfach verwendet wird, dann sollte man darüber nachdenken ob es vielleicht eine performantere Lösung gibt.

Da es kein Array in T-SQL gibt kann man dieses als String simulieren. Dieses virtuelle Array trennt die einzelnen Werte durch einen definierten Delimiter (in meinem Fall ‘|’ der senkrechte Strich). Bei der Abfrage muss jetzt nur der Abfragewert in einen String mit umgebenden Delimitern convertiert werden und über CHARINDEX mit der virtuellen Array-Variablen verglichen werden.

Eine Lösung könnte damit in etwa so aussehen:

 T-SQL |  copy code |? 
1
<erstelle ARRAY mit IdentWerten die durch parameterwert definiert sind>
2
SELECT <feldliste>
3
FROM <komplexe Abfrage>
4
WHERE CHARINDEX('|'+CONVERT(VARCHAR(10),<quellfeld>)+'|',@ARRAY) > 0

Ein Beispiel hierfür findet man in nachfolgenden Script:

 T-SQL |  copy code |? 
01
SET NOCOUNT ON 
02
 
03
-- -----------------------------------------------------------------
04
-- Script in Variable @Cmd erstellt Array-String
05
-- -----------------------------------------------------------------
06
 
07
DECLARE @Cmd NVARCHAR(MAX)
08
 
09
SET @Cmd = N'
10
    use <@Datenbank>
11
 
12
    declare @Feld   nvarchar(1000)
13
    declare @Result nvarchar(max)
14
    declare @Delim  nvarchar(10)
15
 
16
    set @Delim = ''|''
17
    set @Result = @Delim
18
 
19
    declare FieldListCur cursor for
20
    select <@QuellFeld> from <@Quelltabelle> where <@Where>
21
 
22
    open FieldListCur
23
 
24
    fetch next from FieldListCur into @Feld
25
 
26
    while @@fetch_status = 0
27
    begin
28
        set @Result = @Result + @Feld + @Delim
29
        fetch next from FieldListCur into @Feld
30
    end
31
 
32
    close FieldListCur
33
    deallocate FieldListCur
34
 
35
    select @Result as Result
36
    '
37
 
38
-- -----------------------------------------------------------------
39
-- Script konfigurieren
40
-- -----------------------------------------------------------------
41
 
42
SET @Cmd = REPLACE(@Cmd,'<@Datenbank>','AdventureWorks')
43
SET @Cmd = REPLACE(@Cmd,'<@QuellFeld>','ContactID')
44
SET @Cmd = REPLACE(@Cmd,'<@Quelltabelle>','Person.Contact')
45
SET @Cmd = REPLACE(@Cmd,'<@Where>','FirstName like ''Fernan%''')
46
 
47
-- -----------------------------------------------------------------
48
-- Script ausführen und Ergebnis in Variable @Array schreiben
49
-- Die @Tabelle wird nur zur temporäran Übernahme des Ergebnisses benötigt.
50
-- -----------------------------------------------------------------
51
 
52
DECLARE @ARRAY NVARCHAR(MAX)
53
DECLARE @TArray TABLE (wert NVARCHAR(MAX))
54
 
55
INSERT INTO @TArray EXEC SP_EXECUTESQL @Cmd
56
 
57
SELECT @ARRAY = wert FROM @TArray
58
 
59
DELETE @TArray
60
 
61
-- -----------------------------------------------------------------
62
-- Anwendungsbeispiel:
63
-- Auslesen von Datensätzen die eine ContactID haben die in
64
-- unserem Array enthalten ist.
65
-- -----------------------------------------------------------------
66
 
67
SELECT *
68
FROM AdventureWorks.Person.Contact
69
WHERE CHARINDEX('|'+CONVERT(VARCHAR(10),ContactID)+'|',@ARRAY) > 0
70

Hinweis: Wer Fragen zu den Beispielen bzw. Themen an mich hat soll doch bitte über die Kommentarfunktion am Ende jedes Artikels seine Fragen einstellen. Direkte Mails gehen zwar auch, jedoch können andere in einem solchen Fall nicht an den Ergebnissen bzw. Verbesserungen teilhaben.

;)

Viel Spaß beim ausprobieren

:)  

KategorienSQL-Server 2005
  1. Bisher keine Kommentare
  1. Bisher keine Trackbacks