Ci scusiamo per la lunga domanda, ma questa contiene tutto l'SQL che ho usato per testare lo scenario per rendere sperabilmente chiaro ciò che sto facendo.SQL Server - Tabella PIVOT dinamica - SQL Injection
Sono costruire un po 'di SQL dinamico per produrre una tabella pivot in SQL Server 2005.
Qui di seguito è il codice per fare questo. Con varie selezioni che mostrano i dati grezzi i valori utilizzando GROUP BY e i valori in un PIVOT come li voglio.
BEGIN TRAN
--Create the table
CREATE TABLE #PivotTest
(
ColumnA nvarchar(500),
ColumnB nvarchar(500),
ColumnC int
)
--Populate the data
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'X', 1)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Y', 2)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Z', 3)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'X', 4)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Y', 5)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Z', 6)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'X', 7)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Y', 8)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Z', 9)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'X', 10)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'Y', 11)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'Z', 12)
--The data
SELECT * FROM #PivotTest
--Group BY
SELECT
ColumnA,
ColumnB,
SUM(ColumnC)
FROM
#PivotTest
GROUP BY
ColumnA,
ColumnB
--Manual PIVOT
SELECT
*
FROM
(
SELECT
ColumnA,
ColumnB,
ColumnC
FROM
#PivotTest
) DATA
PIVOT
(
SUM(DATA.ColumnC)
FOR
ColumnB
IN
(
[X],[Y],[Z]
)
) PVT
--Dynamic PIVOT
DECLARE @columns nvarchar(max)
SELECT
@columns =
STUFF
(
(
SELECT DISTINCT
', [' + ColumnB + ']'
FROM
#PivotTest
FOR XML PATH('')
), 1, 1, ''
)
EXEC
('
SELECT
*
FROM
(
SELECT
ColumnA,
ColumnB,
ColumnC
FROM
#PivotTest
) DATA
PIVOT
(
SUM(DATA.ColumnC)
FOR
ColumnB
IN
(
' + @columns + '
)
) PVT
')
--The data again
SELECT * FROM #PivotTest
ROLLBACK
Ogni volta che produco qualsiasi SQL dinamico sono sempre a conoscenza degli attacchi SQL Injection. Pertanto ho aggiunto la seguente riga con le altre istruzioni INSERT.
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'FOO])) PVT; DROP TABLE #PivotTest;SELECT ((GETDATE()--', 1)
Quando oggi ho eseguito lo SQL, bassa ed ecco, la parte EXEC gocce tavolo #PivotTest rendendo così l'ultimo SELEZIONA sicuro.
Quindi la mia domanda è, qualcuno sa di un modo per eseguire un PIVOT dinamico senza rischiare attacchi SQL Injection?
1) Il mio campione è semplice. Le colonne effettive sono nvarchar (max). Al momento non disponiamo di dati di dimensioni e i dati che verrebbero utilizzati per il PIVOT saranno raramente pari a 100, quindi in questo caso potrei eseguire un troncamento forzato! Grande idea. 2) Stavo pensando al '[' e ']'. Sono tentato di togliere tutte le parentesi quadre dai dati e limitarmi a questa funzionalità. 3) Le uniche persone che possono aggiungere questi dati sono i cosiddetti "Super utenti", tuttavia, questo non è sufficiente per darmi tranquillità. –
QUOTENAME! La prima volta che l'ho visto! Perfezionare! Questo risolve completamente il problema. Stavo aggiungendo le QUOTE manualmente.Se rimuovo questo e lo faccio usando QUOTENAME, disabiliterà qualsiasi SQL all'interno di quel campo! GRAZIE! –