2017-08-01 134 views
0

我正在編寫一個QA過程,該過程記錄數據庫中違反某些業務規則的記錄,並向用戶發送電子郵件,通知他們他們有一些清理操作。我們的業務要求不包括「垃圾郵件」我們的用戶,所以我必須在發送之前將所有違規事件累積到一封電子郵件中。使用ORDER BY子句在varchar變量中累積數據集

這個特定的QA標識重複的WPGC。

-- variables already declared 
DECLARE @th VARCHAR(MAX) SET @th = ''; 
DECLARE @tb VARCHAR(MAX) SET @tb = ''; 
DECLARE @tr VARCHAR(MAX) SET @tr = ''; 
DECLARE @tf VARCHAR(MAX) SET @tf = ''; 
-- yes the URL is munged. org_name is probably not a valid CRM organization. 
DECLARE @url VARCHAR(MAX) SET @url = 'https://org_name.crm.dynamics.com/[email protected]&id={@guid}&pagetype=entityrecord'; 

DECLARE @rc INT SET @rc = 0 ; 

-------------------------------------------------------- 

    SELECT @th='<tr><th>Capyr</th><th>WPGC Name</th><th>Account Name</th></tr>' 
, @tr='<tr><td>@3</td><td>@4</td><td><a href="@url">@5</a></td></tr>' 
, @tb='', @tf='', @rc=0; 

WITH d AS ( 
    SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@tr 
    , '@url' , @url) 
    , '@etc' , '10021') 
    , '@guid', ISNULL(CAST(account  AS VARCHAR(50)),'')) 
    , '@3', isnull(CAST(campaignyear AS VARCHAR(50)),'')) 
    , '@4', isnull(CAST(name   AS VARCHAR(50)),'')) 
    , '@5', isnull(CAST(accountname AS VARCHAR(50)),'')) d 
    , 1 n 
    , campaignyear f1d, accountname f2a 
FROM QA.dupeWPGC 
) 
SELECT @tb += d, @rc += n 
FROM d 
--ORDER BY f1d DESC, f2a ASC 

如果我按照書面形式運行此查詢,170行將按預期顯示。

問題1:數據沒有特定的順序。 (2010年,2011年,2012年,2009年,2009年,2016年,2011 ......)
解決方案1:添加(去掉註釋)ORDER BY條款

問題2:如果我運行此查詢與ORDER BY條款激活(取消註釋)只包含一條記錄。 (它似乎是正確的ORDER ed數據集的最後一個記錄。)
解決方案2:

如果我將ORDER BY子句添加到最外層的查詢中,則只返回一行。
如果我添加了ORDER BY條款其他地方(如在視圖QA.dupeWPGC,在CTE d,或在另一個CTE(例如,, d2 AS (SELECT * FROM d ORDER BY f1d DESC, f2a ASC)),那麼最終的結果仍然未分類的(即沒有差異便可以看出)。

我該如何使這個數據集呈現a)完全的,b)正確排序?

最後,在其上運行:

SELECT @@VERSION; 
-------------------------------------------------------------------------------------------------- 
Microsoft SQL Server 2014 (SP2-GDR) (KB3194714) - 12.0.5203.0 (X64) 
    Sep 23 2016 18:13:56 
    Copyright (c) Microsoft Corporation 
    Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600:) 

回答

1

用於解決方案1:

更新:解決方法1不工作

您可以嘗試在你的ORDER BY的末尾添加OPTION(MAXDOP 1)

ORDER BY f1d DESC, f2a ASC 
OPTION(MAXDOP 1) 

我不知道,但我的猜測是,ORDER BY導致並行計劃,這可能會導致問題。

我提出解決方案3:

它使用內置的FOR XML功能

CREATE TABLE #Data(ID INT, campaignyear VARCHAR(20), name VARCHAR(20), account VARCHAR(20), accountname VARCHAR(20)) 
INSERT INTO #Data 
SELECT 4, '2017', 'John', '123456', 'AccountName1' UNION ALL 
SELECT 7, '2017', 'Paul', '654321', 'AccountName2' UNION ALL 
SELECT 3, '2016', 'Jack', '123', 'AccountName3' 

DECLARE @tb XML 
SELECT @tb = (
SELECT 
    (SELECT ISNULL(CONVERT(NVARCHAR(50), campaignyear), '') FOR XML PATH('td'), TYPE), 
    (SELECT ISNULL(CONVERT(NVARCHAR(50), name), '') FOR XML PATH('td'), TYPE), 
    (SELECT 
     (SELECT CONVERT(NVARCHAR(255), 
       N'https://org_name.crm.dynamics.com/main.aspx?etc=10021&id={' + ISNULL(CONVERT(NVARCHAR(50), account), '') + '}&pagetype=entityrecord') AS [@href], 
      ISNULL(CONVERT(NVARCHAR(50), accountname), '') 
     FOR XML PATH('a'), TYPE) 
    FOR XML PATH('td'), TYPE) 
FROM #Data 
ORDER BY ID -- !!!!!!!!!!! Note ORDER BY here 
FOR XML PATH('tr') 
) 
SELECT @tb 

輸出的SQL Server:

<tr> 
    <td>2016</td> 
    <td>Jack</td> 
    <td> 
    <a href="https://org_name.crm.dynamics.com/main.aspx?etc=10021&amp;id={123}&amp;pagetype=entityrecord">AccountName3</a> 
    </td> 
</tr> 
<tr> 
    <td>2017</td> 
    <td>John</td> 
    <td> 
    <a href="https://org_name.crm.dynamics.com/main.aspx?etc=10021&amp;id={123456}&amp;pagetype=entityrecord">AccountName1</a> 
    </td> 
</tr> 
<tr> 
    <td>2017</td> 
    <td>Paul</td> 
    <td> 
    <a href="https://org_name.crm.dynamics.com/main.aspx?etc=10021&amp;id={654321}&amp;pagetype=entityrecord">AccountName2</a> 
    </td> 
</tr> 
+1

謝謝了! Option(MaxDOp)並沒有改變任何東西,但是XML語句取得了訣竅! –