Sql server 多模式的存储过程

Sql server 多模式的存储过程,sql-server,tsql,Sql Server,Tsql,我试图创建一个存储过程,将一个学生记录添加到一个表中,并可由多个模式使用,但只应影响属于特定模式的表。到目前为止,我得到的是: CREATE PROCEDURE AucklandPark.#add_student (@studentNum INT, @firstName NVARCHAR(60), @lastName NVARCHAR(60), @address NVARCHAR(60)) AS INSERT INTO Auckland

我试图创建一个存储过程,将一个学生记录添加到一个表中,并可由多个模式使用,但只应影响属于特定模式的表。到目前为止,我得到的是:

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
schema。如果我尝试创建一个执行相同操作的存储过程,但用其他内容替换了
AucklandPark
,则会出现一个错误,表明该存储过程已经存在。

请尝试以下操作:

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

另一种方法是一个过程来更新所有校园/架构

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

您正在创建一个临时存储过程,因为
#
名称前缀。临时存储过程是在tempdb dbo模式中创建的。在本例中以及在执行时,将忽略
CREATE PROCEDURE
中指定的架构名称。也就是说:

USE YourDatabase;
GO
CREATE PROC SomeArbirarySchema.#example
AS SELECT 1;
GO
该过程是在tempdb
dbo
schema中创建的,如下查询所示

SELECT OBJECT_SCHEMA_NAME(OBJECT_ID(N'tempdb.SomeArbirarySchema.#example'), DB_ID(N'tempdb'));
可以使用以下任何构造调用此过程:

EXECUTE #example;
EXECUTE SomeArbirarySchema.#example;
EXECUTE ThisCanBeAnyString.#example;
proc正文中引用的对象的架构名称将被引用


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

必须使用动态SQL。使用OBJECT_SCHEM_NAME(@@PROCID)获取存储过程的架构。@NițuAlexandru我不明白你的意思。在何处以及如何使用对象\u架构\u名称(@@PROCID)?虽然您为过程指定了架构名称,但该过程是临时的(#在名称之前),它将在tempdb中创建,但不需要调用架构名称。首先,你为什么要临时创建这个程序?@NițuAlexandru It拒绝让我使用这个程序,因为我没有把#放在前面。“它”是谁或什么?如果你不把#放进去会有什么错误?您有权在此数据库上创建存储过程吗?