Richard Deeming
Эти процедуры общего назначения всегда доставляют больше хлопот, чем пользы.
Чтобы предотвратить SQL-инъекция[^] уязвимость, вам необходимо проверить как имя таблицы, так и имя столбца" order by". Это относительно легко, когда у вас есть одно имя столбца, без модификатора" ASC "или" DESC". Если вы хотите упорядочить по нескольким столбцам или контролировать последовательность сортировки, это становится намного сложнее.
Вам также нужно будет изменить @rowval
параметр к целому числу и использовать процедуры sp_executesql[^] чтобы передать это в ваш динамический запрос в качестве параметра. (Этот TOP
оператор может принимать переменную, поэтому для этого вам не нужен динамический SQL.)
Предполагая, @oby
содержит только одно имя столбца, без модификатора, тогда что-то вроде этого должно работать:
ALTER PROCEDURE [dbo].[GetDataFromTable]
(
@rowval int,
@tablename varchar(50),
@oby varchar(50)
)
As
BEGIN
DECLARE @ObjectID int, @RealTableName sysname, @RealSchemaName sysname, @RealColumnName;
DECLARE @Query nvarchar(max), @Parameters nvarchar(max);
SET NOCOUNT ON;
SET @ObjectID = OBJECT_ID(@tablename);
If @ObjectID Is Null RAISERROR('The table "%s" was not found.', 16, 1, @tablename);
SELECT
@RealTableName = QUOTENAME(T.name),
@RealSchemaName = QUOTENAME(S.name)
FROM
sys.tables As T
INNER JOIN sys.schemas As S
ON S.schema_id = T.schema_id
WHERE
T.object_id = @ObjectID
And
T.type = 'U'
;
If @@ROWCOUNT = 0 RAISERROR('The table "%s" was not found.', 16, 1, @tablename);
SELECT
@RealColumnName = QUOTENAME(name)
FROM
sys.columns
WHERE
object_id = @ObjectID
And
name = @oby
;
If @@ROWCOUNT = 0 RAISERROR('The column "%s" was not found in the table "%s".', 16, 1, @oby, @tablename);
SET @Query = N'SELECT TOP (@rowval) * FROM ' + @RealSchemaName + N'.' + @RealTableName + N' ORDER BY ' + @RealColumnName + N' DESC';
SET @Parameters = N'@rowval int';
EXEC sp_executesql @Query, @Parameters, @rowvalue = @rowval;
END
Однако было бы гораздо лучше создать отдельную процедуру для каждой таблицы, к которой вам нужно получить доступ.