我想通過將它連接到一個條件表來找到一種方法來對XML字符串進行接受/拒絕。我現在有一個「過濾器」正在工作,但是要編寫它以便可以過濾2個或更多。t-sql:在多個條件下動態過濾XML?
下面是與兩者中的一個匹配的代碼。如果兩者匹配,則會過濾字符串。 我想要做的就是它,所以它必須同時匹配,同時還留下了選擇單條件
CREATE TABLE #filter (exclusion_type CHAR(1), excluded_value varchar(10))
INSERT INTO #filter VALUES ('B','boy')
INSERT INTO #filter VALUES ('C','cat')
DECLARE @data XML
SELECT @data = '<A><B>boy</B><C>cat</C></A>'
SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValue
FROM @data.nodes(N'//*') T(node))xml_shred
IF NOT EXISTS
(SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValue
FROM @data.nodes(N'//*') T(node)) xml_shred
INNER JOIN #filter
ON (nodename = exclusion_type AND nodevalue LIKE excluded_value)
)
select 'record would be inserted '
ELSE select 'record was filtered'
這裏是我現在怎麼把它過濾兩種。醜陋,不可擴展。
IF NOT EXISTS
(SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValue
FROM @data.nodes(N'//*') T(node)) xml_shred
INNER JOIN #filter
ON (nodename = exclusion_type AND nodevalue LIKE excluded_value)
)
--combination filters don't easily work within that xml_shred
and not(
@data.value('(/A/B)[1]', 'varchar(128)') = 'boy'
AND
@data.value('(/A/C)[1]', 'varchar(128)')='cat'
)
select 'record would be inserted '
ELSE select 'record was filtered'
我唯一的其他想法:
- 某種GUID的,將在#filter錶鏈接記錄在一起,然後內部聯接上的#filtertable一個GROUP BY,由GUID和分組使用SUM來匹配記錄的數量。
- 使用分號分割#filter行,然後使用CTE或某物來僞造層次結構並從那裏開始工作。
通過的Mikael的建議
CREATE TABLE #filter
(
exclusion_set SMALLINT,
exclusion_type CHAR(1) ,
excluded_value VARCHAR(10)
)
INSERT INTO #filter
VALUES (1, 'B', 'boy')
INSERT INTO #filter
VALUES (1, 'C', 'cat')
INSERT INTO #filter
VALUES (2, 'D', 'dog')
DECLARE @data XML
SELECT @data = '<A><B>boy</B><C>cat</C></A>'
IF NOT EXISTS(
SELECT * FROM
(
select COUNT(*) AS match_count, exclusion_set
from #filter as F
where exists (
select *
from (
select X.N.value('local-name(.)', 'varchar(128)') as NodeName,
X.N.value('./text()[1]', 'varchar(max)') as NodeValue
from @data.nodes('//*') as X(N)
) T
where T.NodeName = F.exclusion_type and
T.NodeValue like F.excluded_value
)
GROUP BY exclusion_set
) matches_per_set
INNER JOIN
(SELECT COUNT(*) AS total_count, exclusion_set FROM #filter GROUP BY exclusion_set) grouped_set
ON match_count = total_count
AND grouped_set.exclusion_set = matches_per_set.exclusion_set
)
權,但是,只有當有永遠只能匹配的記錄工作。第二個我添加了一組不同的條件(通過向#filter添加行),它失敗了。但是,這段代碼與我的GUID想法相吻合...... – mbourgon
我在做的node.query與你正在做的X.N.value之間的性能有很大的區別嗎?我不知道XML查詢足夠了解。猜猜我可以對付我的A/B。 – mbourgon
如何從另一組過濾器中指出一組過濾器? –