ORACLE 迁移到 MogDB 之存储过程改造:@dblink(2)更新远程表
在上一篇详细写了 MogDB dblink 使用遇到的几个问题及解决方案,今天又遇到 MogDB dblink 在更新远程表的问题,记录如下:
在更新 dblink 表的时候报:ERROR: t field dose not exist in table testdata. 其中t 是dblink 远程表的别名,但是他这里报错是 field 不存在,也就是他把 别名识别为 字段了,具体报错如下,时间环境的update的sql较长,还有多表关联,我在本地精简如下:
1 | Mogdb# update testdblink.testdata@testDBLink_mogdb1 t set t.id=100; |
也就是在更新我上次文章中创建的 testdblink.testdat
表,源环境是多表关联,这个表使用了别名 t。
为了解决这个问题,我进行了如下改造、测试:
在本地创建远程的表,然后进行更新,
1 | MoDB=# create table mgemp as select * from testdblink.testdata@testDBLink_mogdb1; |
这很显然,更新本地表是没问题的,问题出在 dblink的远程表。
既然报错 t field 不存在,那就把别名 t去掉,惊奇的发现,竟然可以。
1 | MoDB=# update testdblink.testdata@testDBLink_mogdb1 set id=100; |
本次实际改造,就是去掉别名。不过如果在复杂SQL 中,多个表之间有字段相同的,必须要制定是那个表的字段,比如如下的sql。
1 | testdb=# create table f(id int); |
也就是 t表和 testdata表都有 id这个字段,在关联查询的时候,如果没有写明是哪个表的id,会报错的:ERROR: column reference “id” is ambiguous
1 | testdb=# update testdata set id=1000 where id=(select distinct id from f,testdata where f.id=testdata.id); |
1 | testdb=# update testdata set t.id=1000 where id=(select distinct f.id from f,testdata where f.id=testdata.id); |
更新远程表:
1 | liups=# update testdblink.testdata@testDBLink_mogdb1 t set id=1000 where id=(select distinct f.id from f,testdblink.testdata@testDBLink_mogdb1 where f.id=testdata.id); |
这里经过测试,where 条件可以写别名,但是 在set的时候不能写别名。
1 | liups=# update testdblink.testdata@testDBLink_mogdb1 t set t.id=1000 where id=(select distinct f.id from f,testdblink.testdata@testDBLink_mogdb1 where f.id=testdata.id); |
1 | liups=# update testdblink.testdata@testDBLink_mogdb1 t set id=1000 where id=(select distinct f.id from f,testdblink.testdata@testDBLink_mogdb1 where f.id=testdata.id); |
可以看到 在where 条件中,是可以写别名的,唯一报错的就是在 set 更新字段的时候,不能写表的别名。
这应该属于bug,本次改造的解决方案,就是 去掉 set 更新的时候的表的别名,由于是更新一个表,即使where 关联条件的多个表有字段重复,也不影响。
原文作者: Hi.MogDB
原文链接: https://hi.mogdb.org/posts/26b5bb83/
许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议