我有一个 SQL 数据库,里面装满了各种日志信息,包括 Windows 事件日志的完整描述。此说明是一个 nvarchar 列,其中包含如下所示的信息:
An account failed to log on.
Subject:
Security ID: S-1-5-18
Account Name: XXX-XXX01$
Account Domain: XXX
Logon ID: 0x3E7
Logon Type: 8
Account For Which Logon Failed:
Security ID: S-1-0-0
Account Name: username
Account Domain: domain
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xC000006D
Sub Status: 0xC0000064
Process Information:
Caller Process ID: 0x1111
Caller Process Name: C:\Windows\System32\inetsrv\w3wp.exe
Network Information:
Workstation Name: XXX-XXX04
Source Network Address: XXX.XXX.XXX.XXX
我只想使用 select 语句检索“登录失败的帐户:”下“帐户名称:”和“帐户域:”之后的值,以便我可以在 Excel 和/或 Power BI 中使用它。< /p>
这可能吗?
答案 0 :(得分:0)
我猜提供的示例是一列/一个字符串的内容。在这种情况下,我建议使用 charindex
和 xml.nodes
的组合。
举个例子:
DECLARE @x NVARCHAR(max) = 'An account failed to log on.
Subject:
Security ID: S-1-5-18
Account Name: XXX-XXX01$
Account Domain: XXX
Logon ID: 0x3E7
Logon Type: 8
Account For Which Logon Failed:
Security ID: S-1-0-0
Account Name: username
Account Domain: domain
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xC000006D
Sub Status: 0xC0000064
Process Information:
Caller Process ID: 0x1111
Caller Process Name: C:\Windows\System32\inetsrv\w3wp.exe
Network Information:
Workstation Name: XXX-XXX04
Source Network Address: XXX.XXX.XXX.XXX';
DECLARE @idxLogonFailed bigint = charindex('Account For Which Logon Failed:'+char(13)+char(10), @x);
DECLARE @idxFailureInfo bigint = charindex('Failure Information:'+char(13)+char(10), @x);
DECLARE @logonFailedLen int = @idxFailureInfo-@idxLogonFailed;
DECLARE @logonFailedSubstr NVARCHAR(1000) = SUBSTRING(@x, @idxLogonFailed, @logonFailedLen);
DECLARE @newLineIdx INT = charindex(char(13)+char(10), @logonFailedSubstr);
DECLARE @xXml xml = CAST(REPLACE('<a><b>' + REPLACE(@logonFailedSubstr, char(13)+char(10), '</b><b>') + '</b></a>', '<b></b>', '') AS XML);
WITH cte AS(
SELECT TRIM(T.r.value('.', 'VARCHAR(1000)')) AS x
FROM @xXml.nodes('/a/b') as T(r)
),
cteSplit AS(
SELECT *, TRIM(LEFT(x, CHARINDEX(':', x)-1)) AS description, TRIM(RIGHT(x, LEN(x)-CHARINDEX(':', x))) AS val
FROM cte
WHERE CHARINDEX(':', x) > -1
)
SELECT description, val
FROM cteSplit
WHERE description IN ('Account Name','Account Domain')