如何最好地编写 TSQL 脚本来创建或更改以表值类型作为参数的存储过程,并保留 GRANT

问题描述 投票:0回答:1

我有一组 SQL 脚本来管理数据库中存储过程的定义。 (这将托管在 SQL Azure 数据库上)我的目标之一是使这些脚本能够安全地重复执行。 如果 SP 已存在,则更新它,否则创建它。 我需要保留 DBA 申请的所有 GRANT。 SP 的实施独立于谁可以执行它的决定。 拨款会根据数据模型的发布位置而变化,因此拨款不能成为创建脚本的一部分。 通常很容易:

create or alter procedure sch.activity as
  @parm int
begin
  select 'yada yada...';
end;

赠款得以生存。 当 SP 使用可能更改的表值参数时,此策略会失败。 CREATE OR ALTER 不适用于我作为策略,因为在这种情况下它会生成错误。 我需要删除并创建程序。 当我这样做时,补助金就会丢失。

我可能会将授权保留在变量中,然后删除并创建 SP 并键入,然后重新应用授权。 但是,由于我必须删除并创建 SP,因此存在分隔操作的“go”,并且变量范围丢失了。

我可以将权限保留在临时表中。 我不能使用单个 #,因为它们在 'go' 之间丢失,所以我必须使用 ##tables,并且要小心管理临时表的生命周期,以防 DBA 需要连续运行 24 次几秒钟之类的。

现在我有一个更复杂的脚本

declare @grant nvarchar(max);
select @grant = 'insert gnarly query of sys.procedures and sys.premissions with object_id()s and stuff here'
insert @grants g into ##grants;
drop procedure if exists ...
go
drop type if exists ...
go
create type tvp as ...
go
create or alter procedure sch.activity as
  @parm tvp
begin
  select 'yada yada...';
end;
go
if object_id('tempdb..##grants') is not null
begin
    declare @g nvarchar(max);
    select @g=g from ##grants;
    if @g is not null
    begin
        exec @g;
    end
    drop table ##grants;
end

我还可以做更多的事情来完善脚本。 这看起来工作量很大,而且出错的机会也很多。 新代码与 SP 的意图关系不大。 有更好的办法吗?

sql-server t-sql sql-server-2022
1个回答
0
投票

您可以通过添加一个空主体的额外 CREATE/ALTER 来保留权限。

CREATE OR ALTER PROCEDURE dbo.proc1 as ; -- removes dependency on tvp type
GO

DROP TYPE tvp ...
GO

CREATE TYPE tvp ...
GO

ALTER PROCEDURE dbo.proc1 
(
@p1 tvp READONLY
) AS
BEGIN 
...
END
GO
© www.soinside.com 2019 - 2024. All rights reserved.