Как я уже говорил в комментариях, инъекция - это огромная проблема, и вы должны рассмотреть ее.Сказать «Давайте рассмотрим, я не против инъекции» наивно, и вам нужно изменить это отношение.Всегда делайте ваш SQL безопасным;тогда нет никаких оправданий и шансов на то, что ваше приложение будет скомпрометировано.
То, что вы ищете, я подозреваю это достигает цели.Нет необходимости для подзапроса сканировать вашу таблицу с помощью IN
здесь, вы можете использовать COUNT
и предложение OVER
в CTE.
CREATE PROCEDURE [dbo].[FindDuplicates] --I've removed te sp prefix, as sp_ is reserved by MS
@tableName sysname,
@field1 sysname,
@field2 sysname = NULL,
@field3 sysname = NULL,
@field4 sysname = NULL,
@field5 sysname = NULL
AS BEGIN
DECLARE @query AS nvarchar(MAX);
SET @query = N'WITH CTE AS(' + NCHAR(10) +
N' SELECT *' + NCHAR(10) +
N' COUNT(*) OVER (PARTITION BY ' + STUFF(CONCAT(N',' + QUOTENAME(@field1),N',' + QUOTENAME(@field2),N',' + QUOTENAME(@field3),N',' + QUOTENAME(@field4),N',' + QUOTENAME(@field5)),1,1,N'') + N' AS RowCount' + NCHAR(10) +
N' FROM ' + QUOTENAME(@tableName) + N')' + NCHAR(10) +
N'SELECT *' + NCHAR(10) +
N'FROM CTE' + NCHAR(10) +
N'WHERE RowCount > 1' + NCHAR(10) +
N'ORDER BY ' + STUFF(CONCAT(N',' + QUOTENAME(@field1),N',' + QUOTENAME(@field2),N',' + QUOTENAME(@field3),N',' + QUOTENAME(@field4),N',' + QUOTENAME(@field5)),1,1,N'') + N';';
PRINT @query;
--EXEC sys.sp_executesql @query; --Uncomment to rrun the actual query
END
GO
Для команды, которую вы дали намEXEC dbo.FindDuplicates @tableName = 'someRandomTable', @field1 = 'firstField', @field2 = 'secondField', @field3 = 'thirdField';
, это возвращает SQL:
WITH CTE AS(
SELECT *
COUNT(*) OVER (PARTITION BY [firstField],[secondField],[thirdField] AS RowCount
FROM [someRandomTable])
SELECT *
FROM CTE
WHERE RowCount > 1
ORDER BY [firstField],[secondField],[thirdField];
Что, я считаю, дает вам поведение, за которым вы следите.