Oracle 11g - Find Records in a CLOB with Carriage Return Line Feed

主宰稳场 提交于 2019-12-11 13:20:01

问题


I am on Oracle 11g. I am trying to do a Find and Replace functionality on a CLOB field (using REPLACE).

Now the data in my CLOB has CRLFs in them, the replace works just fine until I want to find a string that contains CRLFs. Perhaps this would be best explained by example:

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

Now what I want to do is replace all occurrences of this INCLUDING the CRLFs:

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

With this text INCLUING the CRLFs:

Replace Text
------------------------------------
Some other text that
has some new text that is there also.

So That could come out to be:

 ----------------------------------
 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

Now I am doing this in a stored procedure and the Search Text and Replace Text come in as variables, but When I try and say where like % || ReplaceText || '%' it returns 0 rows.

Does anyone have an idea how to do this?

Here is my stored procedure (iOldResponsibilities is the Search Text, iNewResponsibilities is the replace text:

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;

The Text is coming from an asp.net application (c#) as String values:

 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:


Turns out to be a case of bad data. The data in my Test DB was corrupted and only had LFs instead of CRLFs.

GIGO :-)

Thanks for all your help

Oh and by the way In my code example I went with the INSTR function instead of the like function. If the user entered a % in the text to search through that might have messed up the like statement. (Can't filter those out because % might be a valid character in my data)

Here is the Final Code:

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;

The code from my application was fine:

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"));
    }
}


来源:https://stackoverflow.com/questions/24804468/oracle-11g-find-records-in-a-clob-with-carriage-return-line-feed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!