Entschuldigung für die lange Frage, aber das enthält alle SQL, die ich verwendet habe, um das Szenario zu testen, um hoffentlich klar zu machen, was ich mache.SQL Server - Dynamische PIVOT Tabelle - SQL Injection
Ich bin aufbauen einige dynamischen SQL eine Pivot-Tabelle in SQL Server 2005
Im Folgenden Code, dies zu tun, ist zu produzieren. Mit verschiedenen Auswahlmöglichkeiten zeigen die Rohdaten die Werte mit GROUP BY und die Werte in einem PIVOT wie ich sie haben möchte.
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
Immer wenn ich irgendeine dynamische SQL erzeuge, bin ich immer auf SQL Injection Attacken aufmerksam. Daher habe ich die folgende Zeile mit den anderen INSERT-Anweisungen hinzugefügt.
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'FOO])) PVT; DROP TABLE #PivotTest;SELECT ((GETDATE()--', 1)
Wenn ich jetzt die SQL laufen, und siehe da, fällt der EXEC Teil damit die #PivotTest Tabelle der letzte SELECT nicht machen.
Meine Frage ist also, weiß jemand eine Möglichkeit, eine dynamische PIVOT durchzuführen, ohne SQL Injection-Angriffe zu riskieren?
1) ist My Testprobe einfach. Die tatsächlichen Spalten sind nvarchar (max). Wir haben derzeit keine Daten dieser Größe, und die Daten, die für den PIVOT verwendet werden würden, wären selten so groß wie 100, daher kann ich in diesem Fall eine erzwungene Kürzung durchführen! Großartige Idee. 2) Ich dachte an 'und'. Ich bin versucht, alle eckigen Klammern aus den Daten zu streichen und nur als Einschränkung dieser Funktionalität. 3) Die einzigen Leute, die diese Daten hinzufügen können, sind sogenannte "Super User", dies ist jedoch nicht genug, um mir ein Gefühl der Sicherheit zu geben. –
QUOTENAME! Das erste Mal habe ich es gesehen! Perfekt! Dies löst das Problem vollständig. Ich habe die QUOTES manuell hinzugefügt.Wenn ich dies entferne und es mit QUOTENAME mache, wird jedes SQL in diesem Feld deaktiviert! DANKE! –