动态更改 SQL Server 2019 中调用的过程的顺序
Dynamically change the order of procedures called in SQL Server 2019
我在 SQL 服务器中有一个程序调用了 6 个其他程序(部门名称)。
在 table 中,我保留了带有编号的部门列表(总共 6 个部门)。部门数量每天更新,可以彻底改变我需要的顺序。
是否可以遍历 table 的值并更改调用的过程的顺序,其中第一个过程的编号最小,最后一个调用的过程的编号最大数.
示例:当前过程调用的顺序是:
EXECUTE InsertDep1Plan
EXECUTE InsertDep2Plan
EXECUTE InsertDep3Plan
EXECUTE InsertDep4Plan
EXECUTE InsertDep5Plan
EXECUTE InsertDep6Plan
table暂时保持这个数字
DepName | DepNumber
---------+-----------
Dep1 | 123
Dep2 | 567
Dep3 | 413
Dep4 | 112
Dep5 | 76
Dep6 | 94
现在,是否可以遍历按 DepNumber
从小到大排序的 table 个数字,并以此为基础按此顺序调用上述过程?
我不必实际循环遍历 table,我也可以将数字保留为 @parameters,然后比较数字并按顺序执行过程。
您可以构建一个 SQL 字符串来以正确的顺序动态执行您的过程。
您可以如何执行此操作的示例如下:
create procedure proc1 as print 'proc1';
go
create procedure proc2 as print 'proc2';
go
create procedure proc3 as print 'proc3';
go
create table Departments(name varchar(5), seq int)
insert into departments select 'c1',10
insert into departments select 'c2',20
insert into departments select 'c3',30
declare @sql nvarchar(max)
select @sql=String_Agg(Concat('exec pro',name),';') within group(order by seq)
from Departments
exec sys.sp_executesql @sql
执行上面构建一个字符串'exec proc1;exec proc2;exec proc3'然后执行;输出是
proc1
proc2
proc3
现在更改要求排序:
update departments set seq=40 where name='c2'
并重新运行,现在的输出是
proc1
proc3
proc2
另一种选择是将过程名称存储在变量中(@p1 总是最先执行的,@p6 总是最后执行的),将相应的 depnames 分配给@p1…@p6 和 exec @p1;…exec @p6; fiddle
exec('create procedure procdep1 as select object_name(@@procid)');
exec('create procedure procdep2 as select object_name(@@procid)');
exec('create procedure procdep3 as select object_name(@@procid)');
exec('create procedure procdep4 as select object_name(@@procid)');
create table dep(depname varchar(20), depnumber int);
insert into dep(depname,depnumber)
values('dep1', 10),('dep2', 5),('dep3', 8),('dep4', 2);
select *
from dep
order by depnumber;
declare
@p1 nvarchar(150),
@p2 nvarchar(150),
@p3 nvarchar(150),
@p4 nvarchar(150),
@p5 nvarchar(150);
rexec:
select @p1=[1], @p2=[2], @p3=[3], @p4=[4]
from
(
select depname,row_number() over(order by depnumber) as rn
from dep
) as d
pivot
(
max(depname) for rn in([1], [2], [3], [4])
) as p;
select @p1 = 'proc'+@p1, @p2 = 'proc'+@p2, @p3 = 'proc'+@p3, @p4 = 'proc'+@p4;
select concat(@p1,'->',@p2,'->',@p3,'->',@p4);
exec @p1;
exec @p2;
exec @p3;
exec @p4;
if not exists(select * from dep where depnumber < 0)
begin
update dep
set depnumber = depnumber - checksum(concat(depnumber,newid(),rand(depnumber)))%15 - 20;
goto rexec
end
我在 SQL 服务器中有一个程序调用了 6 个其他程序(部门名称)。
在 table 中,我保留了带有编号的部门列表(总共 6 个部门)。部门数量每天更新,可以彻底改变我需要的顺序。
是否可以遍历 table 的值并更改调用的过程的顺序,其中第一个过程的编号最小,最后一个调用的过程的编号最大数.
示例:当前过程调用的顺序是:
EXECUTE InsertDep1Plan
EXECUTE InsertDep2Plan
EXECUTE InsertDep3Plan
EXECUTE InsertDep4Plan
EXECUTE InsertDep5Plan
EXECUTE InsertDep6Plan
table暂时保持这个数字
DepName | DepNumber
---------+-----------
Dep1 | 123
Dep2 | 567
Dep3 | 413
Dep4 | 112
Dep5 | 76
Dep6 | 94
现在,是否可以遍历按 DepNumber
从小到大排序的 table 个数字,并以此为基础按此顺序调用上述过程?
我不必实际循环遍历 table,我也可以将数字保留为 @parameters,然后比较数字并按顺序执行过程。
您可以构建一个 SQL 字符串来以正确的顺序动态执行您的过程。
您可以如何执行此操作的示例如下:
create procedure proc1 as print 'proc1';
go
create procedure proc2 as print 'proc2';
go
create procedure proc3 as print 'proc3';
go
create table Departments(name varchar(5), seq int)
insert into departments select 'c1',10
insert into departments select 'c2',20
insert into departments select 'c3',30
declare @sql nvarchar(max)
select @sql=String_Agg(Concat('exec pro',name),';') within group(order by seq)
from Departments
exec sys.sp_executesql @sql
执行上面构建一个字符串'exec proc1;exec proc2;exec proc3'然后执行;输出是
proc1
proc2
proc3
现在更改要求排序:
update departments set seq=40 where name='c2'
并重新运行,现在的输出是
proc1
proc3
proc2
另一种选择是将过程名称存储在变量中(@p1 总是最先执行的,@p6 总是最后执行的),将相应的 depnames 分配给@p1…@p6 和 exec @p1;…exec @p6; fiddle
exec('create procedure procdep1 as select object_name(@@procid)');
exec('create procedure procdep2 as select object_name(@@procid)');
exec('create procedure procdep3 as select object_name(@@procid)');
exec('create procedure procdep4 as select object_name(@@procid)');
create table dep(depname varchar(20), depnumber int);
insert into dep(depname,depnumber)
values('dep1', 10),('dep2', 5),('dep3', 8),('dep4', 2);
select *
from dep
order by depnumber;
declare
@p1 nvarchar(150),
@p2 nvarchar(150),
@p3 nvarchar(150),
@p4 nvarchar(150),
@p5 nvarchar(150);
rexec:
select @p1=[1], @p2=[2], @p3=[3], @p4=[4]
from
(
select depname,row_number() over(order by depnumber) as rn
from dep
) as d
pivot
(
max(depname) for rn in([1], [2], [3], [4])
) as p;
select @p1 = 'proc'+@p1, @p2 = 'proc'+@p2, @p3 = 'proc'+@p3, @p4 = 'proc'+@p4;
select concat(@p1,'->',@p2,'->',@p3,'->',@p4);
exec @p1;
exec @p2;
exec @p3;
exec @p4;
if not exists(select * from dep where depnumber < 0)
begin
update dep
set depnumber = depnumber - checksum(concat(depnumber,newid(),rand(depnumber)))%15 - 20;
goto rexec
end