是可能的:在oracle中连接表时将char转换为varchar

mas*_*ojo 1 oracle casting join

我可以投出B1 char(2)哪些联接A1 varchar2(2):

SELECT * FROM A 
  LEFT JOIN B 
    ON CAST(B.B1 AS VARCHAR2(2)) = A.A1  
Run Code Online (Sandbox Code Playgroud)

结果没有错误,但没有显示数据.

以上查询可能吗?

Ale*_*ole 5

你可以施展它,但它不是你想的那样,或者似乎是依赖它.假设您在加入的字段中有一个单字符值,则无论是否有强制转换,您都无法获得匹配:

create table a (a1 varchar2(2));
create table b (b1 char(2));

insert into a values ('X');
insert into b values ('X');

select * from a left join b on b.b1 = a.a1;

A1 B1
-- --
X     

select * from a left join b on cast(b.b1 as varchar2(2)) = a.a1;

A1 B1
-- --
X     
Run Code Online (Sandbox Code Playgroud)

演员正在追逐数据类型,而不是数据; 它仍然是空白的.唯一的区别是它是在值中明确地完成的,而非隐含的,就像你看到的那样char.您可以验证该值与dump()函数的值是否相同:

select dump(b.b1) dump_char,
  dump(cast(b.b1 as varchar2(2))) dump_varchar2
from b;

DUMP_CHAR            DUMP_VARCHAR2      
-------------------- --------------------
Typ=96 Len=2: 88,32  Typ=1 Len=2: 88,32   
Run Code Online (Sandbox Code Playgroud)

所以类型已经改变,从96(char)到1(varchar2),但值是相同的.将其与表A中的值进行比较,您会发现它们不相同:

select dump(a.a1) dump_varchar2 from a;

DUMP_VARCHAR2      
--------------------
Typ=1 Len=1: 88      
Run Code Online (Sandbox Code Playgroud)

您的演员B值仍然具有尾随空格,A值不具有,因此它们不匹配.您可以删除该尾随空格以与trim()or 进行比较rtrim():

select * from a left join b on rtrim(b.b1) = a.a1;

A1 B1
-- --
X  X  
Run Code Online (Sandbox Code Playgroud)

有一个从隐式转换charvarchar2了内rtrim()通话,所以你仍然可以施展明确的清晰度.

请注意,这假设您从未在A中使用尾随空格.以其他方式进行转换可能更安全:

select * from a left join b on b.b1 = cast(a.a1 as char(2));

A1 B1
-- --
X  X  
Run Code Online (Sandbox Code Playgroud)

...但是您投射/修剪哪一侧也会影响可以使用哪些索引.