我正在尝试创建一个存储过程,该过程将一个学生记录添加到一个表中,并且可以被多个模式使用,但只会影响属于特定模式的表。到目前为止,我的情况是:
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
,则会收到一条错误消息,提示该存储过程已经存在。
答案 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主体内引用的对象的架构名称被接受。
如果您打算创建临时过程,以引用仅因架构名称不同的对象,则需要使用不同的临时过程名称,而不是将架构名称用作命名空间。