我已經繼承了需要調整的報表規範子系統。任務是在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
謝謝你的時間。
這是特殊的工作,的Mikael,謝謝。你的第一個版本,有一些小小的mods,將這個列表從1200到468個報告中刪除。如上面報告的1131報告中那樣,有166個具有「棘手」日期的報告被確定爲編輯版本。其餘的302必須以文本搜索爲基礎,因爲XML是無效的(通常是由於嵌入式SQL),並且「CAST as XML」失敗。再次感謝。 –