我继承了需要调整的报告规范子系统。任务是在tReports表中添加一个日期列,并使用XML代码规范中包含的(应该是)CreateDate填充它。问题是某些较旧的报告没有CREATEDATE属性,或者在下面的一个示例中,XML有效但形成不良,并且无法使用适用于大多数其他报告的xQuery检索CREATEDATE。由于我没有在规范中包含明确的创建日期,我使用插值来估计合理的日期。插值的一个因素是查看报告规范中包含的日期字符串 - 一些将是有用的,另一些则不是。
有太多报告(超过1,200个)可视化地浏览日期字符串的每个报告规范。这些日期字符串可以出现在报表规范中的任何位置,并且可以包含日期字符串的元素和属性的组合非常多。
理想的解决方案是reportID的列表和准备在UPDATE中使用的日期字符串,但因为日期格式不同(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 :(得分:1)
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">