2013-08-19 4 views
0

지금은 쿼리를 실행하여 문서의 동적 단어를 찾아 링크로 바꿉니다. 그것은 잘 작동하지만 일부 특수 문자가있는 경우 null을 반환합니다. 동적 단어가 여기에 ampersand '&'동적 SQL 쿼리 및 특수 문자 문제

들어있는 내용의 일부와 현재 내가 문제가 오전 : 그것은 NULL 아래 'Cease & Desist'

에 대한 반환

<p>STEPS:</p> 
    <p> 
    <p>Please refer to &lt;|Cease &amp; Desist|&gt; policy.</p> 

내가 사용하고있는 코드가, 무엇을 앰퍼샌드가 포함되어 있어도 전체 동적 단어를 반환해야합니다. 위의 질의 가장 안쪽 쿼리 query 'a'InnerText column name [text] 동적 단어를 포함하고 무엇에

SET NOCOUNT ON; 

DECLARE @MyTable TABLE 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    PolicyName NVARCHAR(200) NULL, 
    DocumentID int not null, 
    OldContent NVARCHAR(MAX) NOT NULL, 
    NewContent NVARCHAR(MAX) NULL 
); 
INSERT INTO @MyTable (documentid,OldContent) 
select documentid, html from IPACS_Document where PATINDEX('%Please refer to &lt;|%', html) > 0 and PATINDEX('%|&gt; Policy%', html) > 0 and documentid = 147; 
--select html, PATINDEX('%Please refer to &lt;|%', html), PATINDEX('%|&gt; Policy%', html) from IPACS_Document where PATINDEX('%Please refer to &lt;|%', html) > 0; 



WITH UpdateCTE 
AS 
(
    SELECT b.PolicyName, b.[text], b.NewContent,STUFF(b.InnerText,b.StartIndex-5,b.EndIndex-b.StartIndex+10,'<a href="~/Document/Details/'+ CAST(d.[documentid] as VARCHAR(200))+'">'+b.[Text]+'</a>') AS ChangedText 
    FROM 
    (
     SELECT a.*,SUBSTRING(a.InnerText,a.StartIndex,a.EndIndex-a.StartIndex) AS [Text] 
     FROM 
     (
      SELECT PATINDEX('%Please refer to &lt;|%',t.OldContent)+21 AS StartIndex, 
        PATINDEX('%|&gt; Policy%',t.OldContent) AS EndIndex, 
        t.OldContent AS InnerText, 
        t.NewContent, 
        t.PolicyName 
      FROM @MyTable t 
     ) a 
    ) b 
    inner join IPACS_Document d on d.filename like '%' + b.[text] + '%' 
    where d.categoryid = 3 
) 
--select * from UpdateCTE 
UPDATE UpdateCTE 
SET  NewContent = ChangedText, PolicyName = [text]; 

SELECT * 
FROM @MyTable x; 

. 이것은 table 'b'으로 [text]으로 전달됩니다. 결국 @Mytable에서 동적 단어는 PolicyName에 입력됩니다.

동적 단어에 앰퍼샌드 또는 특수 문자가 포함 된 경우 어떻게 작동합니까?

+0

하여 입력 HTML을 XHTML을 준수하는 경우, 당신은 XML로 임시 테이블에 삽입 고려하고 XQuery를 사용할 수 있습니다. PATINDEX 비교가 xpath로 변경되고 특수 문자가 처리됩니다. – Jim

+0

@ 짐 슬프게도 아니다. 온라인 XHTML 직접 입력에서이를 테스트하면 150 개 이상의 오류가 발생합니다. 그것은 변환 된 단어 문서에서 파생 된 html입니다. 다른 방법이 있기를 바래요? –

답변

1
SET NOCOUNT ON; 

DECLARE @MyTable TABLE 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    PolicyName NVARCHAR(200) NULL, 
    DocumentID int not null, 
    OldContent NVARCHAR(MAX) NOT NULL, 
    NewContent NVARCHAR(MAX) NULL 
); 
INSERT INTO @MyTable (PolicyName,OldContent,DocumentID) 
VALUES (NULL,N'<p>STEPS:</p> 
    <p> 
    <p>Please refer to &lt;|Cease &amp; Desist|&gt; policy.</p>',123); 

;WITH UpdateCTE 
AS 
(
    SELECT b.PolicyName, b.[text], b.NewContent,STUFF(b.InnerText,b.StartIndex-5,b.EndIndex-b.StartIndex+10,'<a href="~/Document/Details/'+ CAST(b.[documentid] as VARCHAR(200))+'">'+b.[Text]+'</a>') AS ChangedText 
    FROM 
    (
     SELECT a.*,SUBSTRING(a.InnerText,a.StartIndex,a.EndIndex-a.StartIndex) AS [Text] 
     FROM 
     (
      SELECT PATINDEX('%Please refer to &lt;|%',t.OldContent)+21 AS StartIndex, 
        PATINDEX('%|&gt; Policy%',t.OldContent) AS EndIndex, 
        t.OldContent AS InnerText, 
        t.NewContent, 
        t.PolicyName, 
        t.DocumentID 
      FROM @MyTable t 
     ) a 
    ) b 
    --inner join IPACS_Document d on d.filename like '%' + b.[text] + '%' 
    --where d.categoryid = 3 
) 
--select * from UpdateCTE 
UPDATE UpdateCTE 
SET  NewContent = ChangedText, PolicyName = [text]; 

SELECT * FROM @MyTable x; 

결과 :

ID PolicyName   DocumentID OldContent                 NewContent 
-- ------------------- ----------- ----------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
1 Cease &amp; Desist 123   <p>STEPS:</p> <p> <p>Please refer to &lt;|Cease &amp; Desist|&gt; policy.</p> <p>STEPS:</p> <p> <p>Please refer to <a href="~/Document/Details/123">Cease &amp; Desist</a> policy.</p> 
+0

그리고이 행'SELECT a. *, SUBSTRING (a.InnerText, a.StartIndex, a.EndIndex-a.StartIndex)을이 [텍스트]'로 바꾸면 SELECT a. *, CONVERT (XML, SUBSTRING ('(.) [1]', 'NVARCHAR (MAX)') AS [텍스트]'값이 'PolicyName'의 값이됩니다. 또한 해독 될 수 있습니다 (예 :'Cease & Desist' 대신에'Cease & Desist'). –

+0

이제'PolicyName'을 표시 할 수 있습니다. 그러나'PolicyName'에'ipacs_document' 테이블을 추가하지 않고 올바른'documentid'를 얻는 방법을 모르겠습니다. 텍스트가 들어있는 문서가 다른 문서의 이름과 다른 ID로 연결됩니다. 예를 들어이 문서는'147'이지만'PolicyName Cease & Desist' 문서는'265'입니다. 이제는'Document/Details/265' 대신에'Document/Details/147'에 대한 링크를 만들고 있습니다. –

+0

CONVERT를 사용할 때 오류가 발생합니다. 유효한 XML이 아니기 때문에 단어 문서에서 잘못 변환되었습니다. –

0

나는 당신의 문제가있을 수 있습니다, 테이블에 html 요소로 나타납니다 및 테이블 변수 veruss 영구 또는 임시 테이블 (#temp)를 사용하여 변환 것 같아요. 인덱스를 평가하는 하위 문자열을 가져 와서 임시 테이블에 전달할 수 있습니다. 테이블 변수를 사용할 수 없습니다. 이것은 내 버전으로 SQL 2012를 사용하고 있습니다.

부분 문자열을 사용할 때 잠재적 인 문제가 있습니다. 즉, 올바른 형식의 XHTML에 대해 유효성 검사를하지 않습니다. xml을 XML로 변환 한 후 xml 쿼리 및/또는 값 파싱을 개인적으로 사용합니다. 그러나 이것은 궁극적으로 나타나는 값을 보여 주며 원하는 것이 아닙니다. 그러나 나는 하위 문자열 메서드도 제공했으며 데이터를 마크 업된 상태로 유지하려는 경우 여전히 작동합니다. 아래의 자동 추출 예 :

declare @X varchar(256) = ' <p>STEPS:</p> 
    <p> 
    <p>Please refer to &lt;|Cease &amp; Desist|&gt; policy.</p> 
    <p>Just extra stuff ;lkasdlkjasdlfkjasdf;lasdjfl;asdjf;lsadjkf;dsaljfas;dljfsdalfjsadlkfjasd;lfk</p> 
    </p>' 


if object_id('tempdb..#Temp') is not null 
    drop table #temp 
; 

With a as 
    (
    Select 
     @X as AsIS 
    , cast(@X as varchar(128)) as Truncated 
    , PATINDEX('%Please refer to &lt;|%', @X)+21 AS St 
    , PATINDEX('%|&gt; Policy%', @X) as Ed 
    --, cast(cast(@X as varchar(128)) as xml) -- WILL BREAK ELEMENTS 
    , cast(@X as xml) as AsXml 
    ) 
Select 
    Substring(AsIs, St, Ed - St) as SubStringMethod 
, AsXml.query('p/p').value('p[1]/.', 'varchar(256)') as xmlqueryvalue 
into #temp 
from a 

declare @temp table (submethod varchar(256), xmlmethod xml) 
; 

--insert into @temp -- WILL BLOW UP with 
--XML parsing: line 1, character 18, illegal qualified name character 
Select * 
from #temp