Sql server 在文本字段中查找服务器名,将其存储在数组中,为每个条目运行sp

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) } 因此,我的例子将实现:

我在描述栏中记录了以下内容:

“发现服务器aaa已损坏,并在晚上8点用服务器bbb bbb替换”

我想做一些类似这样的事情:

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';