使用 select 语句仅从 nvarchar 列输出某些值

时间:2021-07-29 13:52:49

标签: sql sql-server select nvarchar

我有一个 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>

这可能吗?

1 个答案:

答案 0 :(得分:0)

我猜提供的示例是一列/一个字符串的内容。在这种情况下,我建议使用 charindexxml.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')
相关问题