Disculpe la larga pregunta, pero contiene todos los SQL que he usado para probar el escenario y espero que aclare lo que estoy haciendo.SQL Server - Dynamic PIVOT Table - SQL Injection
estoy acumular algunos SQL dinámico para producir una tabla dinámica en SQL Server 2005.
A continuación se muestra el código para hacer esto. Con varias selecciones que muestran los datos sin procesar los valores usando GROUP BY y los valores en un PIVOT como los quiero.
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
Cada vez que produzco un SQL dinámico siempre estoy al tanto de los ataques de inyección SQL. Por lo tanto, he agregado la siguiente línea con las otras instrucciones INSERT.
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'FOO])) PVT; DROP TABLE #PivotTest;SELECT ((GETDATE()--', 1)
Cuando ahora corro el SQL, bajo y he aquí, la parte EXEC gotas de la tabla #PivotTest con lo que la última SELECT falle.
Así que mi pregunta es, ¿alguien sabe de una manera de realizar un PIVOT dinámico sin riesgo de ataques de inyección SQL?
1) Mi muestra de prueba es muy simple. Las columnas reales son nvarchar (max). No tenemos datos de ese tamaño en la actualidad y los datos que se usarían para PIVOT raramente serían de 100, ¡así que puedo realizar un truncamiento forzado en este caso! Gran idea. 2) Estaba pensando en '[' y ']'. Estoy tentado de quitar todos los corchetes de los datos y simplemente tener eso como una limitación de esta funcionalidad. 3) Las únicas personas que pueden agregar estos datos son los llamados "Súper usuarios", sin embargo, esto no es suficiente para darme tranquilidad. –
CUOTENAME! ¡La primera vez que lo he visto! ¡Perfecto! Esto resuelve completamente el problema. Estaba agregando las CITAS manualmente.¡Si elimino esto y lo hago usando QUOTENAME, deshabilitará cualquier SQL dentro de ese campo! ¡GRACIAS! –