SQL Server - извлечение пользовательских данных с использованием динамического запроса в хранимой процедуре - PullRequest
0 голосов
/ 12 октября 2018

У меня проблема, у меня проблемы с просмотром информации пользователя с помощью хранимой процедуры.Процедура принимает три параметра: table, column и searchBySomething.Каждый раз, когда я хочу найти пользователя по другому столбцу, переменная column получает столбец id, а переменная searchBySomething получает конкретный id, процедура работает, но когда я отправляю другой столбец, я получаю ошибкусообщение

Неверное имя столбца (данные)

Процедура выглядит следующим образом:

ALTER PROCEDURE [dbo].[userDetailsDisplay] 
    @table NVARCHAR(30),
    @column NVARCHAR(30),
    @searchBySomething NVARCHAR(30)

    DECLARE @sql NVARCHAR(100)

    SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' + @column + ' = ' + @searchBySomething 
    EXECUTE sp_executesql @sql

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' + @column + ' = ' +''' @searchBySomething +''''

Пример: select * from table where column ='value'

0 голосов
/ 12 октября 2018

Итак, конкретная ошибка, которую вы получаете, заключается в том, что вы не проверяете ввод, чтобы увидеть, существует ли на самом деле строка, переданная в @column.Вы можете проверить его существование по представлению каталога метаданных sys.columns, сделав что-то вроде этого:

if not exists
(
    select 1
    from sys.columns
    where object_id = object_id(@table)
        and name = @column
)
begin
    raiserror('Column %s does not exist in table %t', 16, 1, @column, @table)
    return
end

Однако я был бы упущен, если бы не указал на две вещи.

Во-первых, это динамическая таблица динамических, где шаблон предложения очень плохая практика.Если это для тех, кто уже имеет доступ к базе данных, они могут просто запросить таблицы сами.И если это для внешнего пользователя, вы в основном дали им полный доступ для чтения базы данных с помощью этой процедуры.Конечно, есть некоторые редкие случаи, когда этот шаблон необходим, так что, если вы не можете использовать динамический sql, это подводит меня к следующему пункту.

Код, который вы используетенаписанный уязвим для атаки SQL-инъекцией.Каждый раз, когда вы используете динамический SQL, вы должны быть ОЧЕНЬ осторожны с его конструкцией.Скажем, я передал имя столбца ; drop database [admin]-- Предполагая, что у вас есть такая база данных, моя команда могла бы успешно выполниться, и ваша база данных исчезла бы.

Как обеспечить безопасность динамического SQL - сложная тема, но если выЕсли вы хотите узнать больше об этом, это, вероятно, одна из лучших статей, которые вы можете найти.http://www.sommarskog.se/dynamic_sql.html

Путем параметризации вашего запроса и использования quotename() для таблицы и столбца я изменил его так, чтобы он выглядел следующим образом.Это все равно выдаст странные ошибки, если кто-то попытается сделать инъекционную атаку, но, по крайней мере, он не выполнит свой код.

create procedure [dbo].[userDetailsDisplay] 
    @table nvarchar(30),
    @column nvarchar(30),
    @searchBySomething nvarchar(30)
as
begin
    declare 
        @sql nvarchar(max),
        @params nvarchar(1000)

    if not exists
    (
        select 1
        from sys.columns
        where object_id = object_id(@table)
            and name = @column
    )
    begin
        raiserror('Column %s does not exist in table %t', 16, 1, @column, @table)
        return
    end

    select @sql = '
        select * 
        from ' + quotename(@table) + ' WHERE ' + quotename(@column) + ' = @searchBySomething'

    execute sp_executesql 
        @stmt = @sql,
        @params = '@searchBySomething nvarchar(30)',
        @searchBySomething = @searchBySomething
end
0 голосов
/ 12 октября 2018

Просто убедитесь, что столбец существует в таблице.

для каждого вызванного @table, проверьте, что переменная @column находится в этой таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...