Использование динамического sql в процедуре для вставки данных в таблицы схемы - PullRequest
0 голосов
/ 18 марта 2019

Я надеюсь, что у вас все хорошо.

Я работал над проектом, в котором мне нужно хранить данные о моем колледже, которые включают идентификационные номера, имена, контактные данные и т. Д.

У меня возникли некоторые трудности при создании хранимой процедуры, которая сможет вставлять данные в указанное имя_стали_таблицы.Процедура должна позволять команде EXEC указывать, в какую схему вы хотите вставить данные.Имя_таблицы останется неизменным для всех 14 схем.Следующий пример кода - это то, что я придумал, но он не работает:

CREATE PROCEDURE AddStudent_proc(@campus varchar(50), @StudentID numeric(4,0), @Name varchar(50), @Surname varchar(50), @ID_numeric numeric(13,0), @Address varchar(100))
AS
BEGIN
    DECLARE @dynamic varchar(MAX)
    SET @dynamic = 'INSERT INTO ['+quotename(@campus)+'].Student_tbl(
    StudentID,
    Name,
    Surname,
    ID_numeric,
    Address
    )
    VALUES('+quotename(@StudentID)+','+quotename(@Name)+','+quotename(@Surname)+','+quotename(@ID_numeric)+','+quotename(@Address)+');'
    EXEC (@dynamic);
END
GO

Вся моя структура может быть найдена здесь

I 'Буду признателен за любую помощь по этой теме, поскольку я все еще довольно плохо знаком с SQL в целом.

Заранее спасибо.

1 Ответ

3 голосов
/ 18 марта 2019

Вам не нужно использовать quotename для данных - как следует из названия функции, ее следует использовать с именами (идентификаторы A.K.A).
Кроме того, когда вы используете quotename, он добавляет [ и ] к полученному значению, поэтому нет смысла добавлять их снова (['+quotename(@campus)+'] в вашем коде).

Я бы порекомендовал три улучшения для вашей процедуры:

  1. Измените тип данных @campus на sysname - это специальный синоним типа данных на nvarchar(128) not null, используемый SQL Server для всех идентификаторов.
  2. белый список имен схем.
    Это критическое изменение для защиты от атак SQL-инъекций.
    Все, что не может быть параметризовано, должно быть занесено в белый список.
  3. используйте sp_ExecuteSql вместо EXEC

Это приведет к лучшей хранимой процедуре, поскольку устраняет угрозу SQL-инъекция :

CREATE PROCEDURE AddStudent_proc(
    @campus sysname, 
    @StudentID numeric(4,0), 
    @Name varchar(50), 
    @Surname varchar(50), 
    @ID_numeric numeric(13,0), 
    @Address varchar(100)
)
AS
BEGIN

    IF EXISTS(
        SELECT 1
        FROM Sys.Schemas
        WHERE name = @campus
    )
    BEGIN

    DECLARE @dynamic nvarchar(4000), 
            @paramDefinition nvarchar(4000)


        SELECT @dynamic = N'INSERT INTO '+ quotename(@campus) + N'.Student_tbl (
            StudentID,
            Name,
            Surname,
            ID_numeric,
            Address
        )
        VALUES(@StudentID, @Name, @Surname, @ID_numeric, @Address)',
        @paramDefinition = 
          N'@StudentID numeric(4,0), 
            @Name varchar(50), 
            @Surname varchar(50), 
            @ID_numeric numeric(13,0), 
            @Address varchar(100)'

        EXEC sp_executeSql @dynamic, @paramDefinition, @StudentID, @Name, @Surname, @ID_numeric, @Address;
    END
END
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...