我的挑战是在多个表中找到某些字符。
在我的工作中,数据库设置为将所有日期值保存在名为d_date,d_inserteby_id,d_valid_to等的列中。 但是下划线是SQL中的保留字符,所以像'%D_%'这样的直接字符不会起作用。
因此,当我在寻找包含对日期的引用的行时,我必须更有创意,然后'%D_%'
我知道我可以:
select * from table t where Upper(T.column) like '%D_%' escape '\'
但是如何使用ascii值搜索d和下划线?
答案 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