Хранимая процедура для нескольких схем - PullRequest
2 голосов
/ 16 марта 2019

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

CREATE PROCEDURE AucklandPark.#add_student
     (@studentNum INT, 
      @firstName NVARCHAR(60), 
      @lastName NVARCHAR(60), 
      @address NVARCHAR(60))
AS
    INSERT INTO AucklandPark.StudentInfo
    VALUES (@studentNum, @firstName, @lastName, @address);

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

Ответы [ 3 ]

0 голосов
/ 16 марта 2019

Альтернативой является один процесс для обновления всех кампусов / схем.

CREATE PROCEDURE dbo.[#add_student]
     (@studentNum INT, 
      @firstName NVARCHAR(60), 
      @lastName NVARCHAR(60), 
      @address NVARCHAR(60),
      @campus NVARCHAR(128)
)
AS
    select -- if ' then '' to escape. string now, not parameter
         @firstName = replace(@firstName,nchar(39),nchar(39)+nchar(39)) 
        ,@lastName = replace(@lastName,nchar(39),nchar(39)+nchar(39))
        ,@address = replace(@address,nchar(39),nchar(39)+nchar(39))
        ,@campus = replace(@campus,nchar(39),nchar(39)+nchar(39));
    declare @s nvarchar(max) = '
    INSERT INTO ' + quotename(@campus) + '.StudentInfo
    VALUES (' + rtrim(@studentNum) + ',''' + @firstName + ''',''' + @lastName + ''',''' + @address + ''');';
    exec(@s);
GO
0 голосов
/ 16 марта 2019

Вы создаете временную хранимую процедуру из-за префикса имени #. Временные хранимые процедуры создаются в схеме tempdb dbo. Имя схемы, указанное в CREATE PROCEDURE, игнорируется как в этом случае, так и при выполнении. Для остроумия:

USE YourDatabase;
GO
CREATE PROC SomeArbirarySchema.#example
AS SELECT 1;
GO

Процедура создается в схеме tempdb dbo, как показано в запросе ниже.

SELECT OBJECT_SCHEMA_NAME(OBJECT_ID(N'tempdb.SomeArbirarySchema.#example'), DB_ID(N'tempdb'));

Этот процесс можно вызывать с любой из следующих конструкций:

EXECUTE #example;
EXECUTE SomeArbirarySchema.#example;
EXECUTE ThisCanBeAnyString.#example;

Собственно имя схемы объектов, на которые есть ссылки в теле proc.

Если вы намереваетесь создать временные процессы, которые ссылаются на объекты, отличающиеся только по имени схемы, вам нужно будет использовать разные временные имена процедур, а не использовать имя схемы в качестве пространства имен.

0 голосов
/ 16 марта 2019

Попробуйте что-то вроде этого:

CREATE PROCEDURE AucklandPark.#add_student(@studentNum INT, @firstName NVARCHAR(60), @lastName NVARCHAR(60), @address NVARCHAR(60))
AS
    DECLARE @SchemaName VARCHAR(100) = OBJECT_SCHEMA_NAME(@@PROCID)

    DECLARE @Query NVARCHAR(MAX) = CONCAT('INSERT INTO ', QUOTENAME(@SchemaName), '.StudentInfo VALUES (@studentNum, @firstName, @lastName, @address);')

    EXEC sp_ExecuteSQL @Query,
        N'@studentNum INT, @firstName NVARCHAR(60), @lastName NVARCHAR(60), @address NVARCHAR(60)',
        @studentNum,
        @firstName,
        @lastName,
        @address
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...