Tijdelijke tabellen zijn precies dat. Ze worden het meest gebruikt om werkruimte te bieden voor de tussenresultaten bij het verwerken van gegevens binnen een batch of procedure. Ze worden ook gebruikt om een tabel door te geven vanuit een tabelwaardefunctie, om tabelgebaseerde gegevens door te geven tussen opgeslagen procedures of, meer recentelijk in de vorm van tabelwaardeparameters, om volledige alleen-lezen tabellen van applicaties naar SQL Server-routines te verzenden , of geef alleen-lezen tijdelijke tabellen door als parameters. Als ze eenmaal klaar zijn met het gebruik ervan, worden ze automatisch verwijderd.
Voordat we te diep in de technologie ingaan, raad ik u aan waar mogelijk tabelvariabelen te gebruiken. Ze zijn gemakkelijk en SQL Server doet het werk voor u. Ze hebben ook de neiging om minder problemen te veroorzaken voor een hardwerkend OLTP-systeem. Af en toe moet u ze misschien verfijnen om goede prestaties van ze te krijgen in joins, maar ik zal dat in een oogwenk uitleggen.Als u echter complexere verwerking van tijdelijke gegevens uitvoert of waarschijnlijk meer dan redelijk kleine hoeveelheden gegevens erin, dan zijn lokale tijdelijke tabellen waarschijnlijk een betere keuze.
Tabelvariabelen
Tabelvariabelen worden gebruikt binnen het bereik van de routine of batch waarin ze zijn opgenomen gedefinieerd, en zijn oorspronkelijk gemaakt om tabelwaardige functies mogelijk te maken. Ze zijn echter goed voor veel van de toepassingen waarvoor de traditionele tijdelijke tafel werd gebruikt. Ze gedragen zich als andere variabelen in hun scopingregels. Eenmaal buiten de scope, worden ze verwijderd. Deze zijn veel gemakkelijker om mee te werken en redelijk veilig, en ze triggeren ook minder hercompilaties in de routines waarin ze worden gebruikt dan wanneer u tijdelijke tabellen zou gebruiken. Tabelvariabelen vereisen minder vergrendelingsbronnen omdat ze ‘privé’ zijn voor het proces dat ze heeft gemaakt. Transactie-terugdraaiingen hebben geen invloed op hen omdat tabelvariabelen een beperkte reikwijdte hebben en geen deel uitmaken van de persistente database, dus ze zijn handig voor het maken of opslaan van gegevens die terugdraaiingen zoals logboekvermeldingen zouden moeten overleven. Het nadeel van tabelvariabelen is dat ze vaak worden verwijderd voordat u hun inhoud kunt onderzoeken voor foutopsporing, of ze kunt gebruiken om verschillende SQL-expressies interactief uit te proberen.
Als uw toepassing conservatief is en uw datavolumes u verlichten Ik wil nooit meer iets anders. U kunt echter problemen krijgen. Een moeilijkheid is dat er alleen naar tabelvariabelen kan worden verwezen in hun lokale bereik, dus u kunt ze niet verwerken met dynamische SQL zoals u zou kunnen met een tijdelijke tabel of parameter met tabelwaarde. Dit komt doordat u niet kunt verwijzen naar een extern gedefinieerde tabelvariabele binnen dynamische SQL die u vervolgens uitvoert via de EXEC-instructie of de sp_ExecuteSQL
opgeslagen procedure, omdat de dynamische SQL buiten het bereik wordt uitgevoerd van de tafelvariabele. U kunt natuurlijk de tabelvariabele binnen de dynamische SQL maken en vervolgens gebruiken, omdat de tabelvariabele binnen het bereik valt. Als de dynamische SQL eenmaal is uitgevoerd, is er echter geen tabelvariabele.
Er zijn ook enkele anomalieën waarmee u rekening moet houden. U kunt bijvoorbeeld de tabeldefinitie niet wijzigen na de eerste DECLARE-instructie. In SQL Server 2000 kan een tabelvariabele niet de bestemming zijn van een SELECT INTO
-instructie of een INSERT EXEC
(nu opgelost); U kunt geen door de gebruiker gedefinieerde functies aanroepen vanuit CHECK-beperkingen, DEFAULT-waarden en berekende kolommen in de tabelvariabele. De enige beperkingen die u buiten de CHECK-beperkingen mag overschrijden, zijn PRIMARY KEY, UNIQUE KEY en NULL / NOT NULL
De lastigste problemen komen echter met de toenemende omvang van de tabellen, omdat vóór SQL Server 2016 , je kon een index niet expliciet declareren, en de indexen die de UNIEKE en PRIMAIRE SLEUTEL beperkingen afdwingen hadden geen distributie-indexen die erop werden bijgehouden. Nu kunt u bepaalde indextypen maken in lijn met de tabeldefinitie, maar er worden nog steeds geen distributiestatistieken voor bijgehouden. De Query Optimizer gaat ervan uit dat er maar één rij in de tabel staat. U kunt ook geen parallelle queryplannen genereren voor een SQL-expressie die de inhoud van de tabel wijzigt. Om de indexbeperking gedeeltelijk te omzeilen, kunt u beperkingen gebruiken om hetzelfde te doen. Het meest essentiële is de Primary Key-beperking waarmee u een geclusterde index kunt opleggen, maar unieke beperkingen zijn handig voor de prestaties. De Query-optimalisator zal ze graag gebruiken als ze in de buurt zijn.
Het grootste probleem met tabelvariabelen is dat er geen statistieken over de kolommen worden bijgehouden. Dit betekent dat de query-optimizer een schatting moet maken van de grootte en distributie van de gegevens en als het fout gaat, zul je slechte prestaties bij joins zien: als dit gebeurt, kun je weinig anders doen dan terug te keren naar het gebruik van klassieke lokale tijdelijke tabellen. Beginnend met SQL Server 2019 introduceerde Microsoft een nieuwe functie genaamd Table Variable Deferred Compilation die dit probleem oplost. Lees dit artikel van Greg Larsen voor meer informatie.
Als u SQL Server 2019 niet gebruikt, kunt u proberen om OPTION (RECOMPILE) toe te voegen aan de instructie waarbij de tabelvariabele wordt samengevoegd met andere tabellen. Door dit te doen, kan SQL Server het aantal rijen detecteren bij het opnieuw compileren, omdat de rijen al gevuld zijn. Dit lost het probleem niet helemaal op, aangezien de optimizer nog steeds geen distributiestatistieken heeft en, meestal wanneer de distributie scheef is, een slecht plan kan produceren. In deze demo werd de join met driekwart in de tijd verkort door simpelweg de OPTION (RECOMPILE) toe te voegen.
Als je nu kunt maken wat er in de tabellen komt uniek te maken, kun je een primaire sleutelbeperking gebruiken voor deze tafels. Hierdoor kon de optimizer een geclusterde indexzoekopdracht gebruiken in plaats van een tabelscan en de uitvoeringstijd was te snel om te meten.
Begin met tabelvariabelen, maar ga terug naar het gebruik van lokale tijdelijke tabellen als u prestatieproblemen ondervindt. Sommige mensen zijn moedig genoeg om advies te geven in termen van het aantal rijen in een tabel, en ik heb 100 of 1000 als een maximum zien aangeboden; maar ik heb gezien dat veel grotere tabelvariabelen in de loop van de tijd perfect naar tevredenheid presteren, en veel kleinere geven problemen. In kleinere tabellen is het probleem echter minder detecteerbaar!
Tabelwaardeparameters
De tabelwaardeparameter (TVP) is een speciaal type tabelvariabele die het gebruik ervan uitbreidt. Wanneer tabelvariabelen als parameters worden doorgegeven, wordt de tabel in de TempDB-systeemdatabase gematerialiseerd als een tabelvariabele en door middel van verwijzing doorgegeven, een pointer naar de tabel in de TempDB.
Sindsdien zijn tabelwaardige parameters gebruikt SQL Server 2008 om meerdere rijen gegevens naar een Transact-SQL-routine of naar een batch te sturen via sp_ExecuteSQL
.. Hun bijzondere waarde voor de programmeur is dat ze kunnen worden gebruikt binnen TSQL-code als evenals in de clienttoepassing, dus ze zijn goed voor het verzenden van clienttabellen naar de server. Vanuit TSQL kunt u variabelen met tabelwaarde declareren, gegevens erin invoegen en deze variabelen als tabelwaardeparameters doorgeven aan opgeslagen procedures en functies. Hun meer algemene bruikbaarheid wordt beperkt door het feit dat ze alleen als alleen-lezen worden doorgegeven. U kunt geen UPDATE
, DELETE
, of INSERT
-instructies uitvoeren op een tabelwaarde parameter in de body van een routine.
U moet een door de gebruiker gedefinieerd tabeltype maken en een tabelstructuur definiëren om ze te gebruiken. Hier is een eenvoudig voorbeeld van hun gebruik in TSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/ * Je moet eerst een tabel maken type. * /
CREATE TYPE Namen ALS TABEL
(naam VARCHAR (10));
GO
/ * Maak vervolgens een procedure om gegevens te ontvangen voor de parameter met tabelwaarde, de tabel met namen en selecteer een item uit de tabel * /
CREATE PROCEDURE ChooseAName
@CandidateNames Names READONLY
AS
DECLARE @candidates TABLE (NAME VARCHAR (10),
theOrder UNIQUEIDENTIFIER)
INSERT IN @candidates (name, theorder)
SELECT name, NEWID ()
FROM @CandidateNames
SELECTEER TOP 1
NAAM
VAN @Kandidaten
ORDER BY theOrder
GO
/ * Declareer een variabele die verwijst naar het type voor onze lijst met koeien. * /
DECLARE @MyFavouriteCowName AS-namen;
/ * Voeg gegevens toe aan de tabelvariabele. * /
VOEG IN @MyFavouriteCowName (naam)
SELECTEER “Bossy” UNION SELECT “Bessy” UNION SELECT “bloemblad” UNION SELECT “Daisy” UNION SELECT “Lulu” UNION SELECT ” Buttercup “UNION SELECT” Bertha “UNION SELECT” Bubba “UNION SELECT” Beauregard “UNION SELECT” Brunhilde “UNION SELECT” Lore “UNION SELEC” Lotte “UNION SELECT” Rosa “UNION SELECT” Thilde “UNION SELECT” Lisa “UNION SELECT” Peppo “UNION SELECT” Maxi “UNION SELECT” Moriz “UNION SELECT” Marla “
/ * Geef de tabel met de lijst van traditionele aartsvijanden door aan de opgeslagen procedure. * /
EXEC chooseAName @MyFavouriteCowName
GO
|
Net als bij tabelvariabelen, houdt de parameter met tabelwaarde op te bestaan zodra deze buiten het bereik valt, maar de typedefinitie blijft bestaan totdat deze expliciet wordt verwijderd.Net als tabelvariabelen verwerven ze geen vergrendelingen wanneer de gegevens worden ingevuld door een client, en worden er geen statistieken bijgehouden voor kolommen met tabelwaardeparameters. U kunt een parameter met tabelwaarde niet gebruiken als doel van een SELECT INTO
– of INSERT EXEC
-instructie. Zoals je zou verwachten, kan een parameter met tabelwaarde in de FROM
-clausule van SELECT INTO
staan of in de INSERT EXEC
string of opgeslagen procedure.
De TVP lost het veel voorkomende probleem op van het willen doorgeven van een lokale variabele aan dynamische SQL die vervolgens wordt uitgevoerd door een sp_ExecuteSQL
. Het is slecht gedocumenteerd door Microsoft, dus ik zal u een uitgewerkt voorbeeld laten zien om u op weg te helpen
Voordat we verder gaan met het beschrijven van de meer traditionele tijdelijke tabellen en het gebruik ervan, moeten we ons verdiepen in de plaats waar tijdelijke tafels worden gehouden. TempDB.
TempDB
Tijdelijke tabellen en tabelvariabelen worden gemaakt in de TempDB-database, wat eigenlijk gewoon een andere database is met eenvoudig herstel: met TempDB is er slechts voldoende minimale logboekregistratie om rollback en andere ACID-aardigheden mogelijk te maken. Het speciale verschil van TempDB is dat alle objecten, zoals tabellen, worden gewist bij het opstarten. Omdat TempDB altijd het eenvoudige herstelmodel gebruikt, wordt de voltooide transactie gewist uit het logboek op het volgende TempDB-controlepunt en worden alleen de live transacties bewaard. Dit alles betekent dat tijdelijke tabellen zich gedragen als elk ander soort basistabel in de zin dat ze worden gelogd en opgeslagen, net zoals zij. In de praktijk zullen tijdelijke tabellen waarschijnlijk in het geheugen blijven staan, maar alleen als ze vaak worden gebruikt: hetzelfde als bij een basistabel. TempDB werkt met een systeem dat tijdelijk hergebruik van objecten wordt genoemd en dat een deel van de tijdelijke objecten met het plan in de cache opslaat, als er voldoende geheugen is. Dit verklaart mogelijk de legenda dat tijdelijke objecten alleen in het geheugen bestaan. De waarheid is als altijd het hangt ervan af ….
Er gebeuren veel andere dingen in TempDB: de database-engine kan het gebruiken voor het plaatsen van werktabellen voor DBCC-controles, voor het maken of opnieuw opbouwen van indexen, cursors, bijvoorbeeld. Tussenliggende tabellen in querys die worden beschreven als ‘hashes’, ‘sorteren’ en ‘spools’ worden gematerialiseerd in TempDB, samen met de tabellen die vereist zijn voor verschillende ‘fysieke’ bewerkingen bij het uitvoeren van SQL-instructies. Het wordt ook gebruikt als een versieopslag voor Snapshot-isolatie, Multiple Active Results Sets (MARS), triggers en online-index-build.
Omdat tijdelijke tabellen net als basistabellen worden opgeslagen, zijn er een of twee dingen waar je op moet letten. U moet bijvoorbeeld CREATE TABLE
toestemming hebben in TempDB om een normale tabel te maken. Om u de moeite te besparen, wordt dit standaard toegewezen aan de DBO-rol (db-eigenaar), maar u moet dit mogelijk expliciet doen voor gebruikers aan wie de DBO-rol niet is toegewezen. Alle gebruikers hebben rechten om lokale of globale tijdelijke tabellen in TempDB te maken, omdat dit aan hen is toegewezen via de GUEST
gebruikersbeveiligingscontext.
De klassieke tijdelijke tabel komt binnen twee smaken, de globale of deelbare, tijdelijke tabel, voorafgegaan door ##, en de lokale tijdelijke tabel, waarvan de naam wordt voorafgegaan door #. De lokale tijdelijke tabellen lijken minder op normale tabellen dan de globale tijdelijke tabellen: u kan er geen weergaven van maken of er triggers aan koppelen. Het is een beetje lastig om erachter te komen welk proces, sessie of procedure ze heeft gemaakt. We zullen je daar later een beetje bij helpen. Het belangrijkste is dat ze veiliger zijn dan een globale tijdelijke tabel, omdat alleen het proces dat eigenaar is deze kan zien.
Een andere eigenaardigheid van de lokale tijdelijke tabel (en de lokale tijdelijk opgeslagen procedure) is dat deze een andere naam heeft in de metadata naar degene die je het in je routine of batch geeft. Als dezelfde routine gelijktijdig door verschillende processen wordt uitgevoerd, moet de database-engine onderscheid kunnen maken tussen de identiek genoemde lokale tijdelijke tabellen die door de verschillende processen zijn gemaakt. Het doet dit door een numerieke tekenreeks aan elke lokale tijdelijke tabelnaam toe te voegen, links opgevuld met onderstrepingstekens. Hoewel u de korte naam opgeeft, zoals #MyTempTable
, bestaat wat feitelijk in TempDB wordt opgeslagen, uit de tabelnaam die is opgegeven in de instructie CREATE TABLE
en het achtervoegsel. Vanwege dit achtervoegsel moeten lokale tijdelijke tabelnamen 116 tekens of minder zijn.
Als u geïnteresseerd bent om te zien wat er aan de hand is, kunt u de tabellen in TempDB op dezelfde manier bekijken als elke andere tafel. U kunt zelfs sp_help
alleen gebruiken om aan tijdelijke tabellen te werken als u ze vanuit TempDB aanroept.
1
2
3
|
GEBRUIK TempDB
go
voer sp_Help #mytemp
|
of u kunt ze vinden in de systeemweergaven van TempDB zonder databases te wisselen.
1
|
SELECTEER naam, create_date VAN TempDB.sys.tables WAAR name LIKE “#%”
|
Of het informatieschema
1
|
SELECTEER * FRO M TempDB.information_schema.tables
|
Nog beter, u kunt ontdek welk proces, en welke gebruiker, vasthoudt aan enorme tijdelijke tabellen in TempDB en weigert de ruimte op te geven
Je kunt geen door de gebruiker gedefinieerde datatypes in tijdelijke tabellen gebruiken, tenzij de datatypes bestaan in TempDB; dat wil zeggen, tenzij de datatypes expliciet zijn gemaakt.
Gebruikerstabellen in TempDB
Bij normaal gebruik maak je tijdelijke tabellen of tabelvariabelen zonder er al te diep over na te denken. Het is echter interessant dat TempDB er is voor elke vorm van sandbox-activiteit. U kunt gewone basistabellen, weergaven of wat u maar wilt maken. U kunt schemas, opgeslagen procedures enzovoort maken. Het is onwaarschijnlijk dat u dit wilt doen, maar het is zeker mogelijk aangezien TempDB gewoon een andere database is. Ik heb mijn ontwikkel-SQL Server opnieuw moeten starten nadat ik dit voor mezelf had bewezen door AdventureWorks erop te installeren. Dit betekent dat het mogelijk is om in TempDB een basistabel te maken, een soort ..er… tijdelijke permanente tafel. In tegenstelling tot de wereldwijde tijdelijke tafel, zou u er uw eigen huishouding op moeten doen: u staat er alleen voor. Hetzelfde geldt voor routines. Het voordeel hiervan is dat elke verwerking die u uitvoert gebruikmaakt van het eenvoudige herstel van TempDB, zodat, als u niet opruimt, SQL Server als moeder fungeert bij de volgende keer opstarten: hoewel dit erg lang kan duren. De volgende fase is om te hebben wat ik een ‘aanhoudende tijdelijke’ tafel noem. In deze tabel zijn de gegevens zelf vluchtig wanneer de server opnieuw opstart, maar de tabel zelf blijft bestaan. Waarschijnlijk de meest gebruikelijke manier om een permanente tijdelijke tabel te maken, is door bij het opstarten een globale tijdelijke tabel opnieuw te maken. Dit kan automatisch worden gedaan wanneer alle databases zijn hersteld en het bericht Herstel is voltooid is gelogd. Hoewel dit een globaal tijdelijk is, wordt het niet verwijderd wanneer alle verbindingen die er gebruik van maken verdwenen zijn, omdat het proces dat het uitvoert verdwijnt nooit. Het is ongetwijfeld beter om dit soort werktabel aan te maken in de database die er gebruik van maakt, maar als u volledig herstel gebruikt, blijft het tijdelijke werk in het logboek staan. U kunt natuurlijk gewoon een gewone tabel in TempDB. U kunt deze persistente tabellen bij het opstarten maken door een opgeslagen procedure in master te definiëren die de globale tijdelijke tabel maakt.
Waarom zou u dit soort hybride tabel gebruiken? Er zijn bijvoorbeeld een aantal van technieken voor het doorgeven van tabellen tussen procedures via persistente tabellen op een multiprocesveilige manier, om een reeks bewerkingen van de gegevens uit te voeren. Deze worden verwezen naar tabellen met processleutel (zie Gegevens delen tussen opgeslagen procedures : Process-Keyed tafel door Erland SommarskogZe zullen in eerste instantie de wenkbrauwen optrekken van elke doorgewinterde DBA, maar ze zijn een effectieve en veilige oplossing voor een eeuwigdurend probleem, als ze goed worden gedaan.
Naast tijdelijke tafels zijn er ook een aantal soorten tafels die niet direct zijn afgeleid van basistabellen, zoals nep-tabellen en afgeleide tabellen: sommige hiervan zijn zo vluchtig dat ze beter als kortstondig dan als tijdelijk kunnen worden beschouwd. De CTE gebruikt kortstondige tabellen die ‘inline’ of ‘afgeleid’ zijn en niet worden gerealiseerd. BOL verwijst ernaar als ‘tijdelijke benoemde resultaatsets’. Ze bestaan alleen binnen de reikwijdte van de uitdrukking. In een CTE hebben ze het voordeel ten opzichte van afgeleide tabellen doordat ze meer dan eens toegankelijk zijn.
Lokale tijdelijke tabel
Met lokale tijdelijke tabel (namen die beginnen met #), wat er onder de motorkap gebeurt, lijkt verrassend veel op tabelvariabelen. Net als bij tabelvariabelen, zijn lokale tijdelijke tabellen privé voor het proces dat ze heeft gemaakt. Ze kunnen daarom niet in weergaven worden gebruikt en u kunt er geen triggers aan koppelen.
Ze zijn handiger dan tabelvariabelen als je SELECT INTO
wilt gebruiken om ze te maken, maar ik ben een beetje huiverig voor het gebruik van SELECT INTO
in een systeem dat waarschijnlijk moet worden gewijzigd, zou ik veel liever mijn tijdelijke tabellen expliciet maken, samen met alle beperkingen die nodig zijn.
Je kunt niet gemakkelijk zien welke sessie of procedure heeft gemaakt deze tafels. Dit komt omdat, als dezelfde opgeslagen procedure gelijktijdig door verschillende processen wordt uitgevoerd, de database-engine in staat moet zijn om dezelfde tabellen te onderscheiden die door de verschillende processen zijn gemaakt. De Database Engine doet dit door intern een links opgevuld numeriek achtervoegsel toe te voegen aan elke lokale tijdelijke tabelnaam. De volledige naam van een tijdelijke tabel zoals opgeslagen in de sys.objects-weergave in TempDB bestaat uit de tabelnaam die is opgegeven in de instructie CREATE TABLE
en het door het systeem gegenereerde numerieke achtervoegsel. Om het achtervoegsel toe te staan, moet de tabelnaam die is gespecificeerd voor een lokale tijdelijke naam minder dan 116 tekens bevatten.
Je krijgt huishouding met lokale tijdelijke tabellen; ze worden automatisch verwijderd als ze buiten het bereik vallen, tenzij ze expliciet worden verwijderd door DROP TABLE
te gebruiken. Hun bereik is genereuzer dan die van een tabelvariabele, zodat u geen problemen ondervindt om ernaar te verwijzen in batches of in dynamische SQL. Lokale tijdelijke tabellen worden automatisch verwijderd aan het einde van de huidige sessie of procedure. Als u het laat vallen aan het einde van de procedure die het heeft gemaakt, kan dit leiden tot hoofd krabben: een lokale tijdelijke tabel die is gemaakt binnen een opgeslagen procedure of sessie wordt verwijderd wanneer deze is voltooid, zodat er niet naar kan worden verwezen door het proces dat de opgeslagen procedure noemde heeft de tafel gemaakt. Er kan echter naar worden verwezen door geneste opgeslagen procedures die worden uitgevoerd door de opgeslagen procedure waarmee de tabel is gemaakt. Als de geneste procedure verwijst naar een tijdelijke tabel en er zijn op dat moment twee tijdelijke tabellen met dezelfde naam, tegen welke tabel is de vraag dan opgelost?
Als curiositeit kunt u ook lokale tijdelijke opgeslagen procedures maken met hetzelfde bereik en dezelfde levensduur als een lokale tijdelijke tabel. U kunt niet hetzelfde doen voor andere routines.
Globale tijdelijke tabellen.
Net als lokale tijdelijke tabellen, worden globale tijdelijke tabellen (ze beginnen met ##) automatisch verwijderd wanneer de sessie die de tabel heeft gemaakt, eindigt: Echter, omdat globale tabellen zijn niet privé voor het proces dat het heeft gemaakt, ze moeten daarna worden voortgezet tot de laatste Transact-SQL-instructie die actief naar de tabel verwijst op het moment dat de aanmaaksessie is beëindigd, is voltooid en de vergrendelingen zijn verwijderd. Iedereen die toegang heeft tot TempDB op het moment dat deze globale tijdelijke tabellen bestaan, kan deze tijdelijke objecten rechtstreeks opvragen, wijzigen of verwijderen.
U kunt regels, standaardwaarden en indexen aan tijdelijke tabellen koppelen, maar u kunt geen weergaven maken op tijdelijke tabellen of daaraan gekoppelde triggers. U kunt een door de gebruiker gedefinieerd datatype alleen gebruiken bij het maken van een tijdelijke tabel als het datatype bestaat in TempDB.
Opgeslagen procedures kunnen verwijzen naar tijdelijke tabellen die tijdens de huidige sessie zijn gemaakt. Binnen een opgeslagen procedure kun je geen tijdelijke tabel maken, deze laten vallen en dan een nieuwe tijdelijke tabel met dezelfde naam maken.
Hoewel dit werkt….
… dit werkt niet t
1
2
3
4
5
6
7
8
9
10
11
12
|
CREËER PROCEDURE MisbehaviourWithT TemporaryTables AS
CREATE tabel #Color (
Kleur varchar (10) PRIMAIRE sleutel)
INVOEGEN IN #color SELECT “Red” UNION SELECT “White”
UNION SELECT “groen “UNION SELECT” Geel “UNION SELECT” blue “
DROP TABLE #color
CREATE table #Color (
Color varchar (10) PRIMARY key)
VOEG IN #color SELECT “Red” UNION SELECT “White”
UNION SELECT “groen “UNION SELECT” Geel “UNION SELECT” blue “
DROP TABLE #color
go
|
U kunt, door lokale tijdelijke tabellen te gebruiken, onbedoeld hercompilatie afdwingen op de opgeslagen procedure telkens wanneer deze wordt gebruikt. Dit is niet goed, omdat het onwaarschijnlijk is dat de opgeslagen procedure goed werkt. Om hercompilatie te voorkomen, moet u voorkomen dat u verwijst naar een tijdelijke tabel die is gemaakt in een aanroepende of aangeroepen opgeslagen procedure: als u dit niet kunt doen, plaatst u de verwijzing in een tekenreeks die vervolgens wordt uitgevoerd met de EXECUTE
instructie of sp_ExecuteSQL
opgeslagen procedure. Zorg er ook voor dat de tijdelijke tabel wordt gemaakt in de opgeslagen procedure of trigger voordat er naar wordt verwezen en dat deze na deze verwijzingen wordt verwijderd.Maak geen tijdelijke tabel binnen een control-of-flow-statement zoals IF... ELSE
of WHILE
.
U mag globale tijdelijke opgeslagen procedures maken, maar ik moet er nog een gebruik voor vinden. Globale tijdelijke functies zijn niet toegestaan.
Conclusies
Wees in een gedeelde speeltuin heel voorzichtig hoe je met die vleermuis zwaait. Tijdens het lezen van dit zul je je realiseren dat er veel activiteit plaatsvindt in TempDB, en dat je de hele SQL Server kunt verwoesten door langlopende processen te gebruiken die tijdelijke tabellen vullen, van welk type dan ook, met onnodige hoeveelheden gegevens. In feite heb ik je in dit artikel aanwijzingen gegeven hoe je je DBA echt van streek kunt maken door onattent gebruik te maken van die kostbare gedeelde bron, de TempDB. (Vroeger voor S2005 was het gebruik van SELECT INTO
met een enorme tafel het grote V-wapen (Vergeltungswaffe).
Ik ben altijd op mijn hoede voor over- algemeen advies, maar ik geef er altijd de voorkeur aan dat mijn databases waar mogelijk tabelvariabelen en TVPs gebruiken. Ze hebben minder middelen nodig en u zult ze minder snel vasthouden als u klaar bent. Ik gebruik ze graag maximaal , met kolom- en tabelcontroles en beperkingen. Het kan voorkomen dat ze zonder stoom komen te zitten, vooral wanneer de tafelgroottes groter worden. In dit soort gevallen, of waar het niet praktisch is om tabelvariabelen te gebruiken vanwege hun beperkte bereik, Ik gebruik lokale tijdelijke tafels. Er zijn veel samengeknepen lippen en hoofdschudden voor nodig voordat ik instem met een globale tijdelijke tafel of aanhoudende tijdelijke tafel. Ze hebben een paar geldige en volkomen redelijke toepassingen, maar ze vertrouwen op de programmeur om de nodige huishouding te doen