Dynamische SQL en opgeslagen procedures zijn twee van de belangrijkste onderdelen van SQL Server. In dit artikel zullen we kijken naar de voor- en nadelen van elk van hen en wanneer we ze moeten gebruiken.
Prestaties
Iedereen kent het antwoord op deze vraag. Opgeslagen procedures verslaan dynamische SQL in termen van prestaties. Een opgeslagen procedure wordt in het geheugen van de server opgeslagen en de uitvoering ervan is veel sneller dan dynamische SQL. Als alle overige variabelen constant worden gehouden, presteert de opgeslagen procedure beter dan dynamische SQL.
Scheiding van zorgen
Wat betreft het scheiden van zorgen, verslaan opgeslagen procedures dynamische SQL zonder twijfel.
Met opgeslagen procedures kunt u uw databaselogica gescheiden houden van uw bedrijfslogica. Als er dus een fout optreedt in uw bedrijfslogica, hoeft u alleen uw applicatiecode te wijzigen. Omgekeerd, als er een probleem is met uw databaselogica, hoeft alleen uw opgeslagen procedure te worden gewijzigd. Als een opgeslagen procedure wordt bijgewerkt, hoeft de toepassingscode bovendien niet opnieuw te worden gecompileerd en geïmplementeerd.
Als u dynamische SQL-query's in uw clientcode gebruikt, moet u de applicatiecode bijwerken als er een fout optreedt in de SQL-query. Dit betekent dat u de applicatiecode opnieuw moet compileren en implementeren.
Netwerkverkeer
Opgeslagen procedures produceren minder netwerkverkeer dan dynamische SQL omdat voor het uitvoeren van een opgeslagen procedure alleen de procedurenaam en parameters (indien aanwezig) over het netwerk hoeven te worden verzonden.
Voor het uitvoeren van dynamische SQL moet de volledige query over het netwerk worden verzonden, waardoor het netwerkverkeer toeneemt, vooral als de query erg groot is.
SQL-injectie-aanvallen
Opgeslagen procedures zijn niet kwetsbaar voor SQL Injection-aanvallen.
Dynamische SQL-query's zijn kwetsbaar voor SQL-injectie-aanvallen als query's met parameters niet worden gebruikt, en query's met parameters kunnen niet worden gebruikt met dynamische SQL als een tabel- of kolomnaam als parameter wordt doorgegeven.
In dit geval is de tijdelijke oplossing dat de codenaamfunctie kan worden gebruikt om SQL-injectieaanvallen te voorkomen.
Herbruikbaarheid van cachequeryplannen
Opgeslagen procedures verbeteren de databaseprestaties omdat ze het mogelijk maken om in de cache opgeslagen queryplannen opnieuw te gebruiken. In het geval van dynamische SQL moet u geparametriseerde query's gebruiken om de herbruikbaarheid van het queryplan in de cache te vergroten. Bij afwezigheid van queryplannen met parameters, detecteert SQL Server automatisch parameters en genereert het queryplannen in de cache, wat resulteert in verbeterde prestaties.
Het is relevant om hier te vermelden dat alleen OLTP-systemen profiteren van herbruikbaarheid van queryplannen in de cache. In het geval van OLAP-systemen, verandert de keuze van de optimizer, het OLAP-systeem profiteert van het unieke plan.
Onderhoud
Opgeslagen procedures met statische SQL zijn gemakkelijker te onderhouden. In het geval van statische SQL in een opgeslagen procedure kunnen syntaxisfouten bijvoorbeeld worden opgevangen voordat ze worden uitgevoerd. In het geval van dynamische SQL binnen opgeslagen procedures, kunnen syntaxisfouten niet worden gedetecteerd voordat de query wordt uitgevoerd.
Bovendien lijken opgeslagen procedures meer op functies, ze worden eenmaal gedefinieerd en kunnen vervolgens overal in het script worden aangeroepen. Als u een opgeslagen procedure wilt bijwerken, hoeft u deze daarom maar op één plek bij te werken. Alle toepassingsonderdelen die de opgeslagen procedure aanroepen, hebben toegang tot de bijgewerkte versie. Een nadeel is echter dat die toepassingsonderdelen ook kunnen worden beïnvloed waar u de bijgewerkte opgeslagen procedure niet wilt. In het geval van dynamische SQL moet u mogelijk op meerdere plaatsen een SQL-script schrijven, maar in dergelijke gevallen heeft het bijwerken van het script op de ene plaats geen invloed op de andere. Een beslissing tussen het gebruik van een opgeslagen procedure en dynamische SQL hangt af van de functionaliteit van de applicatie.
Beveiliging
Als meerdere toepassingen toegang hebben tot de database, is het veiliger om opgeslagen procedures te gebruiken dan dynamische SQL.
Opgeslagen procedures bieden een extra beveiligingslaag, terwijl de gebruikerscontext de enige manier is om machtigingen voor dynamische SQL-scripts te beheren. Al met al is het beveiligen van dynamische SQL omslachtig in vergelijking met opgeslagen procedures.
Afhankelijkheden identificeren
In een relationele database zijn tabellen afhankelijk van andere tabellen in de database.
Overweeg een scenario waarin u een tabel wilt verwijderen, maar voordat u dat doet, wilt u alle tabelafhankelijkheden weten. Of in eenvoudige bewoordingen, u wilt de query's vinden die toegang hebben tot de tabel die u wilt verwijderen. In deze gevallen kunt u de opgeslagen procedure sp_depends gebruiken.
Sp_depends kan echter alleen die afhankelijkheden detecteren waarbij statische SQL wordt gebruikt in een opgeslagen procedure. In het geval dat dynamische SQL afhankelijk is van een tabel, kan die afhankelijkheid niet worden gedetecteerd door de sp_depends opgeslagen procedure. Laten we dit in actie zien aan de hand van een eenvoudig voorbeeld.
Dummy-gegevens voorbereiden
Laten we wat dummy-gegevens maken om het concept van afhankelijkheden in statische en dynamische SQL uit te leggen.
CREATE DATABASE deptest; USE deptest CREATE TABLE student ( Id int identity primary key, Name VARCHAR(50) NOT NULL, Gender VARCHAR(50) NOT NULL, Age int ) INSERT INTO student VALUES ('James', 'Male', 20), ('Helene', 'Female', 20), ('Sofia', 'Female', 20), ('Ed', 'Male', 20), ('Ron', 'Female', 20)
Nu hebben we een testdatabase met daarin een tabel en enkele testgegevens. Laten we nu twee opgeslagen procedures maken die toegang hebben tot de studententabel.
De eerste opgeslagen procedure gebruikt statische SQL om alle records uit de studententabel op te halen:
USE deptest GO CREATE PROC spStatProc AS BEGIN SELECT * FROM student END
Voer het bovenstaande script uit. Dit script creëert een opgeslagen procedure "spStatProc" in de diepste database.
Laten we een andere opgeslagen procedure maken die dynamische SQL bevat die alle records uit de studententabel ophaalt.
USE deptest GO CREATE PROC spDynProc AS BEGIN DECLARE @query NVARCHAR(100) SET @query = 'SELECT * FROM student' EXECUTE sp_execute @query END
Dit script creëert een opgeslagen procedure "spDynProc" in de diepste database. Deze opgeslagen procedure gebruikt een dynamische SQL-instructie om alle records uit de studententabel op te halen.
Nu hebben we twee opgeslagen procedures die afhankelijk zijn van de studententabel. Een ervan bevat statische SQL en de andere bevat dynamische SQL.
Als u echter de opgeslagen procedure sp_depends uitvoert en deze als parameter doorgeeft aan de studententabel, zult u zien dat alleen de opgeslagen procedure "spStatProc" wordt opgehaald. Dit komt omdat het statische SQL bevat. De opgeslagen procedure "spDynProc" wordt genegeerd omdat deze dynamische SQL bevat.
Voer het volgende script uit.
USE deptest GO EXECUTE sp_depends student
Het zal de volgende output krijgen:
[tabel id=40 /]
U kunt zien dat sp_depends de afhankelijkheid "spDynProc" niet kon rapporteren en alleen "spStatProc" rapporteerde.
Complexiteit
Opgeslagen procedures kunnen extreem ingewikkeld worden als u grote aantallen filters gebruikt en er meerdere AND- en OR-clausules tussen de filters zijn. Aan de andere kant kunt u met dynamische SQL dynamisch WHERE-clausules genereren, afhankelijk van het type filters. Dit maakt dynamische SQL de betere keuze als je extreem complexe logica wilt implementeren.
Conclusie
Over het algemeen presteert de opgeslagen procedure in bijna alle opzichten beter dan dynamische SQL. Ze zijn sneller, veilig en gemakkelijk te onderhouden en vereisen minder netwerkverkeer. Als vuistregel geldt dat opgeslagen procedures moeten worden gebruikt in scenario's waarin u uw query's niet hoeft aan te passen en uw query's niet erg complex zijn. Als u echter regelmatig tabelnamen, kolomnamen of het aantal parameters in uw query wijzigt, is dynamische SQL de betere keuze vanwege de eenvoudigere implementatiestrategie.
Nuttige links
- Dynamische SQL versus opgeslagen procedures
- Wees niet bang voor dynamische SQL
- Opgeslagen procedures met hoge prestaties bouwen
- Klassen over opgeslagen procedures