多个架构的存储过程

时间:2019-03-16 08:46:21

标签: sql-server tsql

我正在尝试创建一个存储过程,该过程将一个学生记录添加到一个表中,并且可以被多个模式使用,但只会影响属于特定模式的表。到目前为止,我的情况是:

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 :(得分:0)

尝试这样的事情:

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

答案 1 :(得分:0)

另一种方法是更新所有校园/方案的proc。

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

答案 2 :(得分:0)

您正在创建临时存储过程,因为#名称前缀。临时存储过程在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'));

可以使用以下任何一种结构调用此proc:

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

在proc主体内引用的对象的架构名称被接受。

如果您打算创建临时过程,以引用仅因架构名称不同的对象,则需要使用不同的临时过程名称,而不是将架构名称用作命名空间。