2014-01-15 27 views
2

我已經繼承了需要調整的報表規範子系統。任務是在tReports表中添加一個日期列,並使用XML代碼規範中包含的(應該是)的CreateDate填充它。問題在於一些較舊的報告沒有CREATEDATE屬性,或者如下面的一個示例所示,XML有效但結構不良,並且無法使用適用於大多數其他報告的xQuery檢索CREATEDATE。由於我沒有包含在規範中的明確創建日期,所以我使用插值來估計合理的日期。插值的一個要素是查看報告規範中包含的日期字符串 - 有些會很有用,有些則不會。從單個varchar(MAX)列中提取多個日期字符串SQL Server

有太多的報告(超過1,200)來直觀地瀏覽日期字符串的每個報告規範。這些日期字符串可以出現在報告規範中的任何位置,並且可以包含大量可以包含日期字符串的元素和屬性組合。

理想的解決方案是在UPDATE中準備使用的reportID和日期字符串列表,但因爲日期格式不同(m/d/yy,mm/dd/yy,m/dd/yy .. )我會很感激得到一些虛假的字符,這些字符可以在日後清理。

所有日期字符串將從2000年或更晚,所以我使用的搜索字符串是'/ 20',它提供了很好的結果。

我看過很多討論這類問題的網站,只發現了一個Mikael Eriksson的解決方案,就像我所描述的那樣,但是我在玩了幾個小時後卻無法工作它。 How to extract multiple strings from single rows in SQL Server

有沒有一種方法,而不使用遊標或WHILE循環來提取這些嵌入日期?

-- Some representative data: (I'm using SQL Server 2008 R2) 
CREATE TABLE #ReportSpecs (ReportID INT, ReportSpec VARCHAR(MAX)) 
INSERT INTO #ReportSpecs 
     (ReportID, ReportSpec) 
VALUES 
(136,   
'<ReportID>136</ReportID> 
<EmpIDCreator>23816</EmpIDCreator> 
<EmpName>Blanc, Melvin J</EmpName> 
<ReportType>0</ReportType> 
<ReportName>PSST Sys Spec</ReportName> 
<ReportData> 
    <REPORT> 
     <COLUMNS> 
     <Column Name="JobNumber" Position="1" /> 
     <Column Name="TaskType" Position="2" /> 
     <Column Name="Assignees" Position="3" /> 
     <Column NAME="JobDueDate" Position="4" /> 
     <Column Name="ReferenceNumber" Position="5" /> 
     <Column Name="Deliverable" Position="6" /> 
     <Column Name="Priority" Position="7" /> 
     </COLUMNS> 
     <FILTERS> 
     <FILTER NAME="TYPE" VALUE="To_Me" /> 
     <FILTER NAME="Status" VALUE="All" /> 
     <FILTER NAME="DateOptions" VALUE="DateRange" From="8/16/2002" To="8/23/2002" /> 
     <FILTER NAME="FromDate" VALUE="8/16/2002" /> 
     <FILTER NAME="ToDate" VALUE="8/23/2002" /> 
     <FILTER NAME="Role" VALUE="All" /> 
     </FILTERS> 
     <parameters> 
     <PARAMETER NAME="@Cascading" TYPE="integer" VALUE="0" /> 
     <PARAMETER NAME="@EmpID" SYSTEM="true" TYPE="integer" VALUE="#Request.EmployeeIDAlias#" /> 
     <PARAMETER NAME="@FromOrgs" TYPE="varchar(250)" VALUE="" /> 
     <PARAMETER NAME="@ToOrgs" TYPE="varchar(250)" VALUE="" /> 
     </parameters> 
     <NAME>PSST Sys Spec</NAME> 
     <OWNER> 
     <ID>23816</ID> 
     </OWNER> 
     <source id="8" useinternalid="True" /> 
    </REPORT> 
</ReportData>'), 

(311, 
'<ReportID>311</ReportID> 
<EmpIDCreator>7162</EmpIDCreator> 
<EmpName>Potter, Harry J</EmpName> 
<ReportType>0</ReportType> 
<ReportName>CPVC Synch Test</ReportName> 
<ReportData> 
    <REPORT> 
     <COLUMNS> 
     <Column Name="JobNumber" Position="1" /> 
     <Column Name="TaskType" Position="2" /> 
     <Column Name="Subject" Position="3" /> 
     <Column Name="CurrentAssignee" Position="4" /> 
     <Column NAME="JobDueDate" Position="5" /> 
     <Column Name="Deliverable" Position="6" /> 
     <Column Name="Category" Position="7" /> 
     <Column Name="Priority" Position="8" /> 
     </COLUMNS> 
     <FILTERS> 
     <FILTER NAME="TYPE" VALUE="By_Orgs_6098,By_Orgs_6123" /> 
     <FILTER NAME="Status" VALUE="Open" /> 
     <FILTER NAME="DateOptions" VALUE="DateRange" From="3/25/2002" To="4/4/2002" /> 
     <FILTER NAME="ReviewFromDate" VALUE="3/25/2002" /> 
     <FILTER NAME="ReviewToDate" VALUE="4/4/2002" /> 
     <FILTER NAME="Role" VALUE="All" /> 
     </FILTERS> 
     <parameters> 
     <PARAMETER NAME="@Act" TYPE="integer" VALUE="0" /> 
     <PARAMETER NAME="@MgrID" SYSTEM="true" TYPE="integer" VALUE="#Request.EmployeeIDAlias#" /> 
     <PARAMETER NAME="@MgrIDActing" TYPE="integer" VALUE="" /> 
     <PARAMETER NAME="@FromDept" TYPE="varchar(250)" VALUE="" /> 
     <PARAMETER NAME="@FromEmp" TYPE="varchar(250)" VALUE="" /> 
     <PARAMETER NAME="@ToDept" TYPE="varchar(250)" VALUE="" /> 
     </parameters> 
     <NAME>CPVC Synch Test</NAME> 
     <OWNER> 
     <ID>7162</ID> 
     </OWNER> 
     <source id="17" useinternalid="True" /> 
    </REPORT> 
</ReportData>'), 

(1131, 
'<ReportID>1131</ReportID> 
<EmpIDCreator>13185</EmpIDCreator> 
<EmpName>Reed, Alan</EmpName> 
<ReportType>0</ReportType> 
<ReportName> 
    ''"><script>alert(''hello'')</script> 
</ReportName> 
<ReportData> 
    <Report NAME="''"> 
     <script>alert(''hello'')</script>" CREATEDATE="12/7/2009"> 
     <DESCRIPTION>sfasf</DESCRIPTION> 
     <OWNER ID="13185"/> 
     <SOURCE ID="1" USEINTERNALID="TRUE"/> 
     <COLUMNS> 
     <COLUMN NAME="JobNumber" POSITION="1" SORTORDER="asc"/> 
     </COLUMNS> 
     <FILTERS> 
     <FILTER NAME="TYPE" VALUE="By_Me,To_Me" /> 
     <FILTER NAME="ASGSTATUS" VALUE="Open" /> 
     <FILTER NAME="DATEOPTIONS" VALUE="All" /> 
     <FILTER NAME="STATUS" VALUE="Open" /> 
     <FILTER NAME="ASGDATEOPTIONS" VALUE="All" /> 
     <FILTER NAME="ROLE" VALUE="All" /> 
     </FILTERS> 
     <PARAMETERS> 
     <PARAMETER NAME="@Me" TYPE="integer" VALUE="3" /> 
     <PARAMETER NAME="@FromCost" TYPE="varchar(250)" VALUE=""/> 
     <PARAMETER NAME="@ToCost" TYPE="varchar(250)" VALUE="" /> 
     </PARAMETERS> 
     <ADVANCEDSORT SortByA="JobNumber" SortOrderA="asc" SortByB="" SortOrderB="" SortByC="" SortOrderC="" /> 
    </Report> 
</ReportData>'); 

/* 
Desired Output (A DISTINCT list would be better, but just getting this output would be GREAT.) 
ReportID DateString 
-------- ---------- 
    136 8/16/2002 
    136 8/23/2002 
    136 8/16/2002 
    136 8/23/2002 
    311 3/25/2002 
    311 4/4/2002 
    311 3/25/2002 
    311 4/4/2002 
    1131 12/7/2009 
*/ 

DROP TABLE #ReportSpecs 

謝謝你的時間。

回答

0
select R.ReportID, 
     D.V as DateString 
from #ReportSpecs as R 
    cross apply (select cast(R.ReportSpec as xml)) as X(R) 
    cross apply X.R.nodes('//@*, //*/text()') as T(X) 
    cross apply (select T.X.value('.', 'varchar(max)')) as D(V) 
where charindex('/20', D.V) > 0 

結果:

ReportID DateString 
----------- -------------------------- 
136   8/16/2002 
136   8/23/2002 
136   8/16/2002 
136   8/23/2002 
311   3/25/2002 
311   4/4/2002 
311   3/25/2002 
311   4/4/2002 
1131  " CREATEDATE="12/7/2009"> 
+0

這是特殊的工作,的Mikael,謝謝。你的第一個版本,有一些小小的mods,將這個列表從1200到468個報告中刪除。如上面報告的1131報告中那樣,有166個具有「棘手」日期的報告被確定爲編輯版本。其餘的302必須以文本搜索爲基礎,因爲XML是無效的(通常是由於嵌入式SQL),並且「CAST as XML」失敗。再次感謝。 –