2016-12-29 3 views
0

Я пишу скрипты для генерации хранимых процедур в базе данных, чья текущая нотация схемы будет неизвестна (подумайте об общем хостинге).SQL Server 2012 динамическая SQL - хранимая процедура - получение синтаксической ошибки

Я решил использовать динамический SQL в хранимых процедурах, чтобы веб-приложение могло передавать схему базы данных на основе заданного пользователем параметра на SQL Server, чтобы она срабатывала должным образом.

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

Неправильный синтаксис около ключевого слова «WHERE»

Я считаю, что это связано с параметром схемы, но я не понимаю, почему это не работает? Я вводил значение dbo для схемы.

/* 
    Name   : usp_GetTestTicker 

    Description  : returns test ticker 

*/ 

if not exists (select * from dbo.sysobjects 
       where id = object_id(N'usp_GetTestTicker') 
    and OBJECTPROPERTY(id, N'IsProcedure') = 1) 
BEGIN 
    DECLARE @sql as nvarchar(150) 
    SET @sql = 'CREATE procedure usp_GetTestTicker AS' 

    EXEC(@sql) 
END 
GO 

ALTER PROCEDURE usp_GetTestTicker 
    @schema VARCHAR(25), 
    @TickerItemId INT 
AS 
    SET NOCOUNT ON 
BEGIN 
    DECLARE @sql_cmd NVARCHAR(MAX) 
    DECLARE @sql_params NVARCHAR(MAX) 

    SET @sql_cmd = N'SELECT * FROM @schema.TickerItem WHERE TickerItemId = @TickerItemId' 

    SET @sql_params = N'@schema VARCHAR(25), @TickerItemId INT' 

    EXEC sp_executesql @sql_cmd, @sql_params, @schema, @TickerItemId 
END 
GO 
+0

Что делать, если вы измените команду EXEC для этого 'EXEC sp_executesql @stmt = @sql_cmd, @params = @sql_params, @schema = @schema, @TickerItemId = @TickerItemId;' – DVT

+2

вы не можете передать схему как параметр. Вам нужно будет построить строку. – Jeremy

+0

У Джереми есть причина. Подумайте, что произойдет, если вы написали инструкцию SELECT, например 'SELECT * From @ schema.MyTable'. Это не работает, поскольку вы не можете иметь переменную как идентификатор схемы. –

ответ

1

Чтобы предотвратить инъекции SQL, вам нужно будет проверить схему против sys.schemas таблицы, например,

ALTER PROCEDURE usp_GetTestTicker 
    @schema NVARCHAR(25), 
    @TickerItemId INT 
AS 
BEGIN 
    SET NOCOUNT ON 

    IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = @schema) 
    BEGIN 
     -- throw an error here. Your web code will have to handle the error and report an invalid schema 

    END 
    ELSE 
    BEGIN 
     DECLARE @sql_cmd NVARCHAR(MAX), @sql_params NVARCHAR(MAX) 

     SET @sql_cmd = N'SELECT * FROM ' + @schema + '.TickerItem WHERE TickerItemId = @TickerItemId' 

     SET @sql_params = N'@TickerItemId INT' 

     EXEC sp_executesql @sql_cmd, @sql_params, @TickerItemId 
    END 
END 
Смежные вопросы