如何使用 JDBC 接收器连接器将表名转换为大写

Posted

技术标签:

【中文标题】如何使用 JDBC 接收器连接器将表名转换为大写【英文标题】:How to convert table name to uppercase using JDBC sink connector 【发布时间】:2021-06-28 04:45:25 【问题描述】:

我正在 Postgres 和 Oracle 数据库之间实现基于 CDC 的复制。对于源连接器,我使用 Debezium 的 Postgres 连接器,而对于接收器连接器,我使用 Confluent 的 JDBC Sink 连接器。

在 Postgres 数据库中,所有的表都是小写的,但在 Oracle 数据库中,表都是大写的。如何在 JDBC 接收器连接器中动态设置配置,这样我就不需要在 transforms.route.replacement 中设置硬编码的大写表名?目前,如果我没有在配置中手动将目标表名称设置为大写,则连接器会添加双引号。然后,我收到以下错误:

原因:org.apache.kafka.connect.errors.ConnectException:表“TEST”.“dummy_table”丢失并且自动创建被禁用

我已禁用自动创建,因为我不需要它。

以下是我的 JDBC 接收器连接器配置示例。我省略了一些字段,如连接 url 等。如果我像这样离开配置,每次我需要添加一个新表时,我都需要创建一个新的 JDBC 接收器连接器。


    "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
    "tasks.max": "1",
    "topics": "test.public.dummy_table",
    "transforms": "route,unwrap",
    "transforms.route.type": "org.apache.kafka.connect.transforms.RegexRouter",
    "transforms.route.regex": "([^.]+)\\.([^.]+)\\.([^.]+)",
    "transforms.route.replacement": "TEST.DUMMY_TABLE", // I want to use TEST.$3 here, but apply uppercase. Is it possible?
    "transforms.unwrap.drop.tombstones": "false",
    "transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState",
    "value.converter": "io.confluent.connect.avro.AvroConverter",
    "pk.mode": "record_key",
    "key.converter": "io.confluent.connect.avro.AvroConverter",
    "pk.fields": "id",
    "quote.sql.identifiers": "never"

是否可以使用 transforms.route.replacement 实现表名大写转换或告诉 sink 连接器不要添加双引号?如果没有,您能否建议如何实施?提前谢谢你。

【问题讨论】:

我认为quote.sql.identifiers 修复了报价问题...?但是不,正则表达式不能应用大小写格式 @OneCricketeer 出于某种原因,它从字段名称(列)中删除了引号,而不是表名。我是否缺少任何设置? 该设置的描述是何时引用表名、列名和SQL语句中的其他标识符。听起来可能是一个错误 【参考方案1】:

我对你所描述的几乎一无所知。

然而:就 Oracle 而言,表名以大写形式存储在数据字典中,但 Oracle 允许您使用任何您想要的字母大小写(大写、小写、混合)来访问它们:

SQL> select count(*) from emp union all       --> lower
  2  select count(*) from EMP union all       --> upper
  3  select count(*) from EmP;                --> mixed

  COUNT(*)
----------
        14
        14
        14

SQL>

只要您在创建表格时不使用双引号即可;在这种情况下,每次访问时都必须使用相同的字母大小写并将表名括在双引号中:

SQL> create table "teST" (id number);

Table created.

SQL> select * from test;
select * from test
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select * from TEST;
select * from TEST
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select * from teST;
select * from teST
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select * from "teST";

no rows selected

SQL>

所以:如果您不那么不幸地使用双引号,也许您不必费心(正如我的第一个示例所示)。只是在引用表格时不要使用双引号就可以了。

【讨论】:

问题是 JDBC 接收器连接器在表名以小写形式出现时会在表名周围添加双引号,我不知道如何告诉不要这样做。 啊哈;哦,好吧,对 JDBC 接收器连接器(不管它是什么)感到羞耻。不幸的是,我对此一无所知,因此无法提供帮助,但我希望其他人能够提供帮助。祝你好运! 是的,我希望有人能提供帮助。谢谢!【参考方案2】:

为避免 kafka 连接接收器中的引号问题,请尝试将 quote_sql_identifiers 设置为从不。

https://docs.confluent.io/kafka-connect-jdbc/current/sink-connector/index.html#jdbc-sink-identifier-quoting

【讨论】:

嗨@wolvery,由于某种原因,quote.sql.identifiers 没有应用于表名。在我的配置中,它设置为从不。

以上是关于如何使用 JDBC 接收器连接器将表名转换为大写的主要内容,如果未能解决你的问题,请参考以下文章

存储过程:将表名转换为表变量

Kafka Connect JDBC 接收器连接器

如何即时将表名解析为 Parquet?

Oracle函数:如何将表名作为参数传递,并使用游标结果作为表名?

为啥 PostgreSQL 不喜欢大写的表名?

多对一公式将表名附加到 SQL 关键字