Отрицает ли динамически сформированный SQL в хранимых процедурах саму цель хранимых процедур? - PullRequest
5 голосов
/ 08 апреля 2011

У нас старый проект 10-12 лет.Он использовал SQL2000, который мы теперь перешли на SQL2008.

Во время выполнения этой задачи я обнаружил, что хранимые процедуры принимают параметры и затем строят запрос в виде строки, а затем используют EXEC для выполнения команды.

CREATE PROCEDURE MyProc
  (@TableName varchar(255),
   @FirstName varchar(50),
   @LastName varchar(50))
AS

    -- Create a variable @SQLStatement
    DECLARE @SQLStatement varchar(255)

    -- Enter the dynamic SQL statement into the
    -- variable @SQLStatement
    SELECT @SQLStatement = "SELECT * FROM " +
                   @TableName + "WHERE FirstName = '"
                   + @FirstName + "' AND LastName = '"
                   + @LastName + "'"

    -- Execute the SQL statement
    EXEC(@SQLStatement)

Это плохой подход.Убивает ли это преимущества хранимой процедуры (преимущества предварительно скомпилированного запроса)?

Ответы [ 4 ]

7 голосов
/ 08 апреля 2011

Нет, и я бы сказал, что основным преимуществом хранимых процедур больше не является то, что они «предварительно скомпилированы» (с 2005 года или ранее, возможно, никогда, за исключением вызовов с очень большим объемом).

Существует кэш плана, который также доступен для специальных операторов.

В этом конкретном примере вновь появилась уязвимость к внедрению, которая будет автоматически:

CREATE PROCEDURE MyProc
  (@FirstName varchar(50),
   @LastName varchar(50))
AS
BEGIN
    SELECT * FROM TABLENAME
    WHERE FirstName = @FirstName
        AND LastName = @LastName
END

Все радипараметризации по имени таблицы.

Преимущества хранимых процедур включают:

  • Управление безопасностью (возможность управления правами EXEC независимо от SELECT / INSERT / UPDATE)

  • Координация доступа (обеспечение выполнения всех операций определенными способами)

  • Организация (возможность организации интерфейса с базой данных согласованным образом)

  • Предотвращение инъекций (хранимые процедуры всегда параметризованы, это гарантирует, что вызывающие абоненты не могут создавать случаи базы данных, которые являютсяНельзя внедрять - обратите внимание, что сами SP должны быть написаны правильно, но программисты-клиенты не смогут вводить инъекции, если они имеют доступ только к SP, а не к таблицам)

  • Инвентаризация системы(возможность профилировать и оптимизировать определенные процедуры по именам, иметь всесторонний и хорошо документированный интерфейсный слой, состоящий из хранимых процедур)

Динамический SQL в SP имеет свое местои это может отрицать некоторые вещи - например, безопасность (она запускает новую цепочку, поэтому здесь необходимо предоставить разрешения SELECT) и внедрение.Кэширование плана выполнения - это не то, что я бы высоко оценил в списке.

1 голос
/ 08 апреля 2011

Зависит от того, что вы считаете «целью» хранимых процедур. Я бы сказал, что существуют хранимые процедуры, чтобы предоставить защищаемый API для базы данных и изолировать приложения от реализации базы данных, не допуская SQL вне базы кода.

Это делает базу данных отдельным компонентом, который можно изменять и создавать версии независимо от кода приложения, на который она ссылается (до тех пор, пока сигнатура API не изменится).

Если весь доступ к вашей базе данных осуществляется с помощью хранимых процедур, если аргументы и наборы хранимых процедур не изменяются, администраторы баз данных могут свободно настраивать запросы и переделывать базу данных в свое сердце, если они этого не делают. Не нарушайте допущений, которые делает код в отношении модели данных: [теоретически] можно полностью изменить базовую схему, не требуя изменений кода.

Это истинное преимущество хранимых процедур.

1 голос
/ 08 апреля 2011

Вместо EXEC (@SQL) попробуйте sp_execute (@SQL).

sp_execute (@SQL) способствует повторному использованию плана запросов. При использовании sp_executesql пользователь или приложение явно идентифицируют параметры. Прочитайте о проблемах кэширования плана здесь в этой статье, см. # 3.

0 голосов
/ 08 апреля 2011

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

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