2014-07-17 62 views
1

我在Oracle 11g上。我正在嘗試在CLOB字段上執行查找和替換功能(使用REPLACE)。Oracle 11g - 使用回車換行在CLOB中查找記錄

現在我的CLOB中的數據在其中有CRLF,替換工作得很好,直到我想找到包含CRLF的字符串。

So say the text in my field is: 
---------------------------------- 
Hi there this is some text 
that has CRLFS in it. 
Some other text that 
is there also. 
Have a nice day 

現在我想做的是替換所有這一切的發生,包括CRLFs:

Search Text 
-------------------------------------------------------------------------------- 
Some other text that 
is there also. 

有了這個文本INCLUING的CRLFs:

Replace Text 
------------------------------------ 
Some other text that 
has some new text that is there also. 
也許這將通過例子來最好的解釋

所以這可能會出現:

---------------------------------- 
Hi there this is some text 
that has CRLFS in it. 
Some other text that 
has some new text that is there also. 
Have a nice day 

現在我在存儲過程中執行此操作,搜索文本和替換文本作爲變量進入,但當我嘗試說出%|| ReplaceText || '%'它返回0行。

有沒有人有一個想法如何做到這一點?

這裏是我的存儲過程(iOldResponsibilities是搜索文本,iNewResponsibilities是替換文本:

PROCEDURE FindReplaceResponsibilities (
    iOldResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE, 
    iNewResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE, 
    oNumRowsUpdated   OUT INTEGER 
) 
IS 

    BEGIN 
     oNumRowsUpdated := 0; 


     SAVEPOINT sp_jf_findrepresp; 

     -- If there is no old text to search for then, 
     -- append the new text to the end of every row. 
     -- Else replace all occurrences of the old text with the new text 
     IF iOldResponsibilities IS NULL THEN 
      UPDATE JP_JOB_FAMILIES 
      SET RESPONSIBILITIES = RESPONSIBILITIES || iNewResponsibilities; 

      oNumRowsUpdated := SQL%ROWCOUNT; 

     ELSE 
      UPDATE JP_JOB_FAMILIES 
      SET RESPONSIBILITIES = REPLACE(RESPONSIBILITIES, iOldResponsibilities, iNewResponsibilities) 
      WHERE RESPONSIBILITIES like '%' || iOldResponsibilities || '%'; 

      -- I have also tried this: 
      --WHERE dbms_lob.instr(RESPONSIBILITIES, TO_CLOB(iOldResponsibilities)) > 0; -- This is a LIKE for CLOBS 

      oNumRowsUpdated := SQL%ROWCOUNT; 

     END IF; 

     RETURN; 

     EXCEPTION 

      WHEN OTHERS THEN 
       BEGIN 
        oNumRowsUpdated := -1; 
        ROLLBACK TO sp_jf_findrepresp; 
        dbms_output.put_line('error: ' || sqlerrm); 
        RETURN; 
       END; 

END FindReplaceResponsibilities; 

文本從一個asp.net應用程序(C#)作爲字符串值來:

public int FindReplaceJobFamilyResponsibilities(String oldResponsibilities, String newResponsibilities, IDbTransaction transaction = null) 
    { 
     using (IDbCommand cmd = this._dataHelper.GetStoredProcedure(_connectionString, 
      "JP_JOBFAM_PKG.FindReplaceResponsibilities", true)) 
     { 
      _dataHelper.SetParameterValue(cmd, "iOldResponsibilities", oldResponsibilities); 
      _dataHelper.SetParameterValue(cmd, "iNewResponsibilities", newResponsibilities); 
      DataHelperBase.VerifyParameters(cmd.Parameters, false); 
      base.SetExecuteConnection(cmd, transaction); 
      _dataHelper.ExecuteNonQuery(cmd); 

      return Convert.ToInt32(_dataHelper.GetParameterValue(cmd, "oNumRowsUpdated")); 
     } 
    } 
+1

通常CRLF不應該是一個問題。我能想到的兩件事:其中一行在crlf之前有一個額外的空間,這很容易被忽略。或者,也許其中一個值只有cr或者只有lf而不是crlf。 – GolezTrol

+0

這也是我的想法。爲了安全起見,我複製並粘貼了我想要搜索的字段中的原始文本以避免這種情況。 –

+0

這聽起來很安全,但是如果您複製Linux文本(僅限於lf),並將其粘貼到Windows的某處,可能會奇蹟般地爲您插入crs。爲了排除此問題,我將首先檢查該字段的十六進制轉儲因爲一味地去掉這段代碼。 – GolezTrol

回答

0

真可謂是壞數據的情況。在我的測試數據庫中的數據已損壞,只有而非CRLFs的LF。

GIGO :-)

感謝您的全力幫助

哦,順便說一句在我的代碼示例中,我使用了INSTR函數而不是類似的函數。如果用戶在文本中輸入%來搜索可能已經搞亂了類似聲明的內容。 (不能過濾出那些因爲%可能是我的數據是有效的字符)

下面是最終代碼:

PROCEDURE FindReplaceResponsibilities (
iOldResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE, 
iNewResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE, 
oNumRowsUpdated   OUT INTEGER 

) IS

BEGIN oNumRowsUpdated:= 0;

SAVEPOINT sp_jf_findrepresp; 

    -- If there is no old text to search for then, 
    -- append the new text to the end of every row. 
    -- Else replace all occurrences of the old text with the new text 
    IF iOldResponsibilities IS NULL THEN 
     UPDATE JP_JOB_FAMILIES 
     SET RESPONSIBILITIES = RESPONSIBILITIES || iNewResponsibilities; 

     oNumRowsUpdated := SQL%ROWCOUNT; 

    ELSE 
     UPDATE JP_JOB_FAMILIES 
     SET RESPONSIBILITIES = REPLACE(RESPONSIBILITIES, iOldResponsibilities, iNewResponsibilities) 
     WHERE dbms_lob.instr(RESPONSIBILITIES, iOldResponsibilities) > 0; 

     oNumRowsUpdated := SQL%ROWCOUNT; 

    END IF; 

    RETURN; 

    EXCEPTION 

     WHEN OTHERS THEN 
      BEGIN 
       oNumRowsUpdated := -1; 
       ROLLBACK TO sp_jf_findrepresp; 
       dbms_output.put_line('error: ' || sqlerrm); 
       RETURN; 
      END; 

END FindReplaceResponsibilities;

從我的應用程序的代碼是罰款:

public int FindReplaceJobFamilyResponsibilities(String oldResponsibilities, String newResponsibilities, IDbTransaction transaction = null) 
{ 
    using (IDbCommand cmd = this._dataHelper.GetStoredProcedure(_connectionString, 
     "JP_JOBFAM_PKG.FindReplaceResponsibilities", true)) 
    { 
     _dataHelper.SetParameterValue(cmd, "iOldResponsibilities", oldResponsibilities); 
     _dataHelper.SetParameterValue(cmd, "iNewResponsibilities", newResponsibilities); 
     DataHelperBase.VerifyParameters(cmd.Parameters, false); 
     base.SetExecuteConnection(cmd, transaction); 
     _dataHelper.ExecuteNonQuery(cmd); 

     return Convert.ToInt32(_dataHelper.GetParameterValue(cmd, "oNumRowsUpdated")); 
    } 
}