Sql server 在文本字段中查找服务器名,将其存储在数组中,为每个条目运行sp
我在描述栏中记录了以下内容: “发现服务器aaa已损坏,并在晚上8点用服务器bbb bbb替换” 我想做一些类似这样的事情:Sql server 在文本字段中查找服务器名,将其存储在数组中,为每个条目运行sp,sql-server,tsql,sql-server-2012,Sql Server,Tsql,Sql Server 2012,我在描述栏中记录了以下内容: “发现服务器aaa已损坏,并在晚上8点用服务器bbb bbb替换” 我想做一些类似这样的事情: SET @serverArray = empty SELECT Description into @serverArray WHERE Description like '%-%-%' FROM Operations ForEach ROW in @serverArray { sp_HardwareScan (ROW) } 因此,我的例子将实现:
SET @serverArray = empty
SELECT Description into @serverArray
WHERE Description like '%-%-%'
FROM Operations
ForEach ROW in @serverArray
{
sp_HardwareScan (ROW)
}
因此,我的例子将实现:
EXEC sp_HardwareScan (aaa-aaa-aaa)
EXEC sp_HardwareScan (bbb-bbb-bbb)
SQL Server中没有数组这类东西,通常在考虑在循环中处理事情时,应该停下来思考它。也就是说,这并不总是可能的,这取决于您在循环的每个迭代中需要做什么。下面是一种每行调用存储过程的简单方法,无需创建混乱的while循环或游标构造。但是,这并没有解析出描述中的部分,即
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。。。这一点一开始并不清楚。为什么这些不存储为单独的列,而不是在一个大字符串中组合在一起?为什么要从SQLServer内部进行“硬件扫描”?听起来更像是PowerShell、C#等的工作
既然我现在了解到每行需要多个过程调用,那么首先创建一个拆分函数如何:
CREATE FUNCTION [dbo].[SplitString]
(
@List NVARCHAR(MAX),
@Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(@List)
AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim
) AS y
);
结果:
EXEC sp_HardwareScan 'c-4-5h';
EXEC sp_HardwareScan 'R2-D2-C3P0';
EXEC sp_HardwareScan 'aaa-aaa-aaa';
EXEC sp_HardwareScan 'bbb-bbb-bbb';
只需将@x
替换为dbo.Operations
,即可对实际表进行测试()
更多关于拆分函数的信息,循环和递归CTE不可伸缩的原因(以及证明),以及更好的选择,如果拆分来自应用层的字符串:
不过,在SQL Server 2016或更高版本上,您应该查看和:
还有,.TSQL中的foreach,多么奇怪。为什么有人想要一个系统管理员作为DBA?@Deluctantba是吗?我现在是:)我想知道以“a”开头的前缀是否比“proc”运行得更快。对于这个系统来说,这个字段中的每个单词不可能有一列,他们想要整个混乱。@DeluctantRBA前缀并不重要(问问你自己前缀的作用是什么),除非前缀是sp.
。非常感谢Bertrand先生,除了第11行的“.”之外,我遵循了你所做的大部分工作,你能解释一下它的用途吗?放一个回车符,这样它的每一个命令都在自己的行中。使其比命令更易于阅读;指挥部;指挥部;指挥部代码>
SET NOCOUNT ON;
DECLARE @x TABLE(Description VARCHAR(MAX));
INSERT @x VALUES('Server c-4-5h was offline & replaced with R2-D2-C3P0 at 5AM'),
('Server aaa-aaa-aaa was broken & replaced with server bbb-bbb-bbb at 8pm');
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'EXEC sp_HardwareScan ''' + REPLACE(Value, '''', '''''') + ''';
'
FROM @x AS x OUTER APPLY dbo.SplitString(REPLACE(x.Description,' ',';'), ';') AS y
WHERE y.Value LIKE '%-%-%';
PRINT @sql;
-- EXEC sp_executesql @sql;
EXEC sp_HardwareScan 'c-4-5h';
EXEC sp_HardwareScan 'R2-D2-C3P0';
EXEC sp_HardwareScan 'aaa-aaa-aaa';
EXEC sp_HardwareScan 'bbb-bbb-bbb';