Oracle SQL按其ascii值搜索或查找字符

时间:2013-03-13 08:22:15

标签: sql oracle

我的挑战是在多个表中找到某些字符。

在我的工作中,数据库设置为将所有日期值保存在名为d_date,d_inserteby_id,d_valid_to等的列中。 但是下划线是SQL中的保留字符,所以像'%D_%'这样的直接字符不会起作用。

因此,当我在寻找包含对日期的引用的行时,我必须更有创意,然后'%D_%'

我知道我可以: select * from table t where Upper(T.column) like '%D_%' escape '\'

但是如何使用ascii值搜索d和下划线?

3 个答案:

答案 0 :(得分:3)

您不能在其所属的表中搜索列名,如果您的架构经常更改,则必须查看数据字典并使用动态SQL。

你可以......

select table_name,
       column_name
from   all_tab_columns
where  owner = ? -- insert name of table owner
and    upper(column_name) like 'D\_%' escape '\'

在搜索中使用D的ASCII值没有任何优势 - 它只会混淆代码。 LIKE和ESCAPE是正确的方法。

顺便说一句,使用混合大小写的对象名称在Oracle中被认为是一种不好的做法。

编辑:当然如果您真的想通过ASCII字符搜索字符串,那么您可以执行以下操作:

where ascii(substr('D_123',1,1))=68 and
      ascii(substr('D_123',2,1))=95

where ascii(substr('D_123',1,1))||ascii(substr('D_123',2,1))='6895'

where substr(dump(substr('D_123',1,2)),-6) = ' 68,95'

与往常一样,有很多方法以错误的方式做事。

答案 1 :(得分:0)

我仍然不确定你为什么要使用ASCII值而不是文字下划线,但也许这就是你想要的(95是'_'的ASCII代码):

  select * 
  from t 
  where upper(t.column1) like '%D\' || chr(95) || '%' escape '\'

请注意,如果您尝试将95替换为例如95,则会引发错误。 65(对于'A'),因为你无法逃脱普通人物。

要处理这个问题,你需要某种逻辑来区分普通字符和你必须逃脱的字符。

答案 2 :(得分:0)

@Shogoot:如果我理解正确,您希望能够搜索任何具有任何列的搜索字符串值为任何列的表格。

如果以上是正确的假设,我认为您唯一的解决方案是使用PL / SQL块,如下所示:

DECLARE

    -- Find tables that have the right type of columns
    CURSOR cur IS
        SELECT  atc.owner
                ,atc.table_name
                ,atc.column_name
        FROM    all_tab_columns atc
        WHERE   atc.data_type IN ('VARCHAR2', 'CHAR', 'DATE')
        AND     owner IN ('OE')
        ;

    vTestString VARCHAR2(250) := CHR(45); -- CHR(45) = '-'      
    iCount      INTEGER := 0;
    vStatement  VARCHAR2(2000) := '';
BEGIN

    -- Loop through tables and columns 
    FOR rec IN cur LOOP
        BEGIN
            -- Find tables that have the right type of columns
            vStatement  :=  'SELECT COUNT(*) '
                            || 'FROM ' || rec.owner || '.' || rec.table_name || ' '
                            || 'WHERE ' || rec.column_name || ' LIKE ''%' || vTestString || '%'' '
                            ;

            --dbms_output.put_line(vStatement);
            EXECUTE IMMEDIATE vStatement
            INTO iCount
            ;

            IF (iCount > 0) THEN
                dbms_output.put_line('Found ' || iCount || ' matches in: ' || rec.owner || '.' || rec.table_name || '.' ||  rec.column_name);
            END IF;     
        EXCEPTION
            -- Oops, we might end here if there is an error
            WHEN OTHERS THEN
                dbms_output.put_line('Something messed up with: ' || rec.owner || '.' || rec.table_name || '.' ||  rec.column_name || '(' || SQLERRM || ')');
        END;
    END LOOP;
END;

您必须将搜索字符串更改为您需要的任何内容。上面的查询基于Oracle的OE架构,您必须调整“cur”查询以满足您的需求。

另外,请记住,您可能会搜索大量数据,因此请根据自己的喜好使用它。

希望这有帮助。

~TJ