sql >> Databasteknik >  >> RDS >> Sqlserver

Dynamisk SQL vs lagrad procedur

Dynamisk SQL och lagrade procedurer är två av de viktigaste komponenterna i SQL Server. I den här artikeln kommer vi att titta på fördelarna och nackdelarna med var och en av dem och när de ska användas.

Prestanda

Alla vet svaret på denna fråga. Lagrade procedurer slår dynamisk SQL när det gäller prestanda. En lagrad procedur cachelagras i serverminnet och dess exekvering är mycket snabbare än dynamisk SQL. Om alla återstående variabler hålls konstanta överträffar den lagrade proceduren dynamisk SQL.

Separation of concerns

När det gäller åtskillnad av bekymmer slår lagrade procedurer dynamisk SQL i handen.

Med lagrade procedurer kan du hålla din databaslogik åtskild från din affärslogik. Därför, om ett fel uppstår i din affärslogik, behöver du bara ändra din applikationskod. Omvänt, om det finns ett problem med din databaslogik, behöver bara din lagrade procedur ändras. Dessutom, om en lagrad procedur uppdateras, behöver applikationskoden inte kompileras om och distribueras.

Om du använder dynamiska SQL-frågor i din klientkod måste du uppdatera applikationskoden om ett fel uppstår i SQL-frågan. Det betyder att du måste kompilera om och distribuera programkoden.

Nätverkstrafik

Lagrade procedurer producerar mindre nätverkstrafik än dynamisk SQL eftersom exekvering av en lagrad procedur kräver att endast procedurens namn och parametrar (om några) skickas över nätverket.

Att köra dynamisk SQL kräver att hela frågan skickas över nätverket, vilket ökar nätverkstrafiken, särskilt om frågan är mycket stor.

SQL-injektionsattacker

Lagrade procedurer är inte sårbara för SQL Injection-attacker.

Dynamiska SQL-frågor är sårbara för SQL-injektionsattacker om parametriserade frågor inte används, och parameteriserade frågor kan inte användas med dynamisk SQL om ett tabell- eller kolumnnamn skickas som en parameter.

I det här fallet är lösningen att kodnamnsfunktionen kan användas för att förhindra SQL-injektionsattacker.

Återanvändbarhet av cachelagrade frågeplaner

Lagrade procedurer förbättrar databasprestanda eftersom de tillåter att cachade frågeplaner återanvänds. I fallet med dynamisk SQL måste du använda parametriserade frågor för att öka cachad frågeplans återanvändbarhet. I avsaknad av parametriserade frågeplaner upptäcker SQL-servern automatiskt parametrar och genererar cachade frågeplaner vilket resulterar i förbättrad prestanda.

Det är relevant att nämna här att endast OLTP-system drar nytta av cachad frågeplans återanvändbarhet. När det gäller OLAP-system, valet av optimeraren ändras, OLAP-systemet drar nytta av den unika planen.

Underhåll

Lagrade procedurer med statisk SQL är lättare att underhålla. Till exempel, i fallet med statisk SQL i en lagrad procedur, kan syntaxfel fångas upp innan de körs. I fallet med dynamisk SQL i lagrade procedurer kan syntaxfel inte fångas upp innan frågan körs.

Dessutom är lagrade procedurer mer som funktioner, de definieras en gång och kan sedan anropas var som helst i skriptet. Därför, om du vill uppdatera en lagrad procedur, behöver du bara uppdatera den på ett ställe. Alla applikationsdelar som anropar den lagrade proceduren kommer att ha tillgång till den uppdaterade versionen. En nackdel är dock att de applikationsdelarna också kan påverkas där du inte vill ha den uppdaterade lagrade proceduren. I händelse av dynamisk SQL kan du behöva skriva SQL-skript på flera ställen, men i sådana fall påverkar uppdatering av skript på en plats inte den andra. Ett beslut mellan att använda en lagrad procedur och dynamisk SQL beror på applikationens funktionalitet.

Säkerhet

Om flera applikationer får tillgång till databasen är det säkrare att använda lagrade procedurer än dynamisk SQL.

Lagrade procedurer ger ett extra lager av säkerhet, medan användarkontexten är det enda sättet att kontrollera behörigheter på dynamiska SQL-skript. Allt som allt är det mödosamt att säkra dynamisk SQL jämfört med lagrade procedurer.

Identifiera beroenden

I en relationsdatabas har tabeller beroenden av andra tabeller i databasen.

Tänk på ett scenario där du vill ta bort en tabell men innan du gör det vill du ta reda på alla tabellberoenden. Eller enkelt uttryckt, du vill hitta de frågor som kommer åt tabellen som du vill ta bort. I dessa fall kan du använda den lagrade proceduren sp_depends.

Men sp_depends kan bara upptäcka de beroenden där statisk SQL används i en lagrad procedur. Om dynamisk SQL är beroende av en tabell, kan detta beroende inte upptäckas av den lagrade proceduren sp_depends. Låt oss se detta i praktiken med hjälp av ett enkelt exempel.

Förbereder dummydata

Låt oss skapa lite dummydata för att förklara konceptet med beroenden i statisk och dynamisk SQL.

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 har vi en testdatabas som innehåller en tabell och lite testdata. Låt oss nu skapa två lagrade procedurer som kommer åt elevtabellen.

Den första lagrade proceduren använder statisk SQL för att hämta alla poster från elevtabellen:

USE deptest
GO
CREATE PROC spStatProc
AS
BEGIN
	SELECT * FROM student
END

Kör skriptet ovan. Det här skriptet skapar en lagrad procedur "spStatProc" i den depteste databasen.

Låt oss skapa en annan lagrad procedur som innehåller dynamisk SQL som hämtar alla poster från elevtabellen.

USE deptest
GO
CREATE PROC spDynProc
AS
BEGIN
	DECLARE @query NVARCHAR(100)
	SET @query = 'SELECT * FROM student'
	EXECUTE sp_execute @query
	
END

Det här skriptet skapar en lagrad procedur "spDynProc" i den depteste databasen. Denna lagrade procedur använder en dynamisk SQL-sats för att hämta alla poster från elevtabellen.

Nu har vi två lagrade procedurer som är beroende av elevtabell. En av dem innehåller statisk SQL och den andra innehåller dynamisk SQL.

Men om du kör den lagrade sp_depends-proceduren och skickar den till elevtabellen som en parameter, kommer du att se att den bara kommer att hämta den lagrade "spStatProc"-proceduren. Detta beror på att den innehåller statisk SQL. Den lagrade "spDynProc"-proceduren kommer att ignoreras eftersom den innehåller dynamisk SQL.

Kör följande skript.

USE deptest
GO
EXECUTE sp_depends student

Den kommer att få följande utdata:

[tabell id=40 /]

Du kan se att sp_depends inte kunde rapportera "spDynProc"-beroendet och bara rapporterade "spStatProc".

Komplexitet

Lagrade procedurer kan bli extremt komplexa om du använder ett stort antal filter och det finns flera OCH- och ELLER-satser mellan filtren. Å andra sidan, med hjälp av dynamisk SQL kan du dynamiskt generera WHERE-satser beroende på typen av filter. Detta gör dynamisk SQL till de bättre valen om du vill implementera extremt komplex logik.

Slutsats

Sammantaget överträffar lagrad procedur dynamisk SQL i nästan alla aspekter. De är snabbare, säkrare och enkla att underhålla och kräver mindre nätverkstrafik. Som en tumregel bör lagrade procedurer användas i scenarier där du inte behöver ändra dina frågor och dina frågor inte är särskilt komplexa. Men om du ofta ändrar tabellnamn, kolumnnamn eller antalet parametrar i din fråga, är Dynamic SQL det bättre valet på grund av dess enklare implementeringsstrategi.

Användbara länkar

  • Dynamisk SQL kontra lagrade procedurer
  • Var inte rädd för Dynamic SQL
  • Bygga högpresterande lagrade procedurer
  • Kurser om lagrade procedurer

  1. PostgreSQL-funktion / lagrad procedur CURRENT_TIMESTAMP ändras inte

  2. Åtgärda "Aritmetiskt spillfel vid konvertering av IDENTITY till datatyp..." i SQL Server

  3. Hur man vadderar en sträng med ledande/släpande tecken i MySQL – LPAD(), RPAD()

  4. Hur infogar man en post med bara standardvärden?