我不是开发人员,所以我很抱歉这个问题。我是一名只有BASH脚本背景知识的系统管理员。
我正在尝试完成以下任务:
1)从一些SQL Server DMV中选择一些列
2)在以前的输出中添加一个名为“ OperState”的列
3)此“ OperState”列必须是步骤1中特定SELECTED列的存储过程的输出(在shell中,它类似于while读取var; do; $ OperState = some command
; echo $ var1 $ var2 ... $ OperState)
想法是1)使用此tsql列出我所有的链接服务器:
SELECT ss.server_id
,ss.name
,'Server ' = Case ss.Server_id
when 0 then 'Current Server'
else 'Remote Server'
end
,ss.product
,ss.provider
,ss.catalog
,'Local Login ' = case sl.uses_self_credential
when 1 then 'Uses Self Credentials'
else ssp.name
end
,'Remote Login Name' = sl.remote_name
,'RPC Out Enabled' = case ss.is_rpc_out_enabled
when 1 then 'True'
else 'False'
end
,'Data Access Enabled' = case ss.is_data_access_enabled
when 1 then 'True'
else 'False'
end
,ss.modify_date
FROM sys.Servers ss
LEFT JOIN sys.linked_logins sl
ON ss.server_id = sl.server_id
LEFT JOIN sys.server_principals ssp
ON ssp.principal_id = sl.local_principal_id
并添加2)名为“ OperState”的附加列,在该列中,我将执行以下其他tsql 3)为先前选择的每个“ ss.name”:
declare @srvr nvarchar(128), @retval int;
set @srvr = 'my_linked_srvr';
begin try
exec @retval = sys.sp_testlinkedserver @srvr;
end try
begin catch
set @retval = sign(@@error);
end catch;
if @retval <> 0
raiserror('Unable to connect to server. This operation will be tried later!', 16, 2 );
我知道我可以在执行循环中使用游标,但是我不知道如何正确地将第一个选择中的变量重用到循环中,以及如何从该循环中产生新的输出到新的列中。
答案 0 :(得分:0)
您不能从查询内部调用存储过程。
您将需要一个游标,一个临时表和一些奇特的错误处理,因此这是TSQL编程的重要内容。
类似这样的东西:
create or alter procedure TestLinkedServers
as
begin
/*
exec TestLinkedServers
*/
set nocount on;
SELECT ss.server_id
,ss.name
,'Server ' = Case ss.Server_id
when 0 then 'Current Server'
else 'Remote Server'
end
,ss.product
,ss.provider
,ss.catalog
,'Local Login ' = case sl.uses_self_credential
when 1 then 'Uses Self Credentials'
else ssp.name
end
,'Remote Login Name' = sl.remote_name
,'RPC Out Enabled' = case ss.is_rpc_out_enabled
when 1 then 'True'
else 'False'
end
,'Data Access Enabled' = case ss.is_data_access_enabled
when 1 then 'True'
else 'False'
end
,ss.modify_date
, cast(null as bit) OperState
, cast(null as nvarchar(2000)) StateMessage
into #linkedServers
FROM sys.Servers ss
LEFT JOIN sys.linked_logins sl
ON ss.server_id = sl.server_id
LEFT JOIN sys.server_principals ssp
ON ssp.principal_id = sl.local_principal_id
declare c cursor local for
select name from #linkedServers
for update of OperState, StateMessage
declare @name sysname
open c
fetch next from c into @name
while @@FETCH_STATUS = 0
begin
declare @retval int = 1;
declare @em nvarchar(2000) = null;
begin try
exec sys.sp_testlinkedserver @name;
end try
begin catch
set @em = error_message();
set @retval = 0;
end catch;
update #linkedServers set OperState = @retval, StateMessage = @em
where current of c
fetch next from c into @name
end
close c
deallocate c
select * from #linkedServers
end