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
该过程是在tempdbdbo
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拒绝让我使用这个程序,因为我没有把#放在前面。“它”是谁或什么?如果你不把#放进去会有什么错误?您有权在此数据库上创建存储过程吗?