RACLE数据库中WM_CONCAT函数失效问题及重建

ORACLE数据库中WM_CONCAT函数失效问题及重建

1、原因

​ WM_CONCAT函数是Oracle的非公开函数,不支持使用该函数,可以使用listagg函数进行替代,Oracle10g之后有些版本已不包含WMSYS.WM_CONCAT函数,若用到此函数, 系统会提示异常:ORA-00904: “WM_CONCAT”: invalid identifier

2、重建

2.1 存在WMSYS用户但无WM_CONCAT处理方法

2.1.1 dba账号登录oracle
sqlplus / as sysdba
2.1.2 解锁wmsys用户
alter user wmsys account unlock;
2.1.3 创建包、包体和函数
CREATE OR REPLACE TYPE WM_CONCAT_IMPL AS OBJECT
(
  CURR_STR VARCHAR2(32767),
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
    RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
                                       P1   IN VARCHAR2) RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF        IN WM_CONCAT_IMPL,
                                         RETURNVALUE OUT VARCHAR2,
                                         FLAGS       IN NUMBER)
    RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF  IN OUT WM_CONCAT_IMPL,
                                     SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
);
2.1.4 定义类型body
CREATE OR REPLACE TYPE BODY WM_CONCAT_IMPL IS
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
    RETURN NUMBER IS
  BEGIN
    SCTX := WM_CONCAT_IMPL(NULL);
    RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
                                       P1   IN VARCHAR2) RETURN NUMBER IS
  BEGIN
    IF (CURR_STR IS NOT NULL) THEN
      CURR_STR := CURR_STR || ',' || P1;
    ELSE
      CURR_STR := P1;
    END IF;
    RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF        IN WM_CONCAT_IMPL,
                                         RETURNVALUE OUT VARCHAR2,
                                         FLAGS       IN NUMBER) RETURN NUMBER IS
  BEGIN
    RETURNVALUE := CURR_STR;
    RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF  IN OUT WM_CONCAT_IMPL,
                                     SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER IS
  BEGIN
    IF (SCTX2.CURR_STR IS NOT NULL) THEN
      SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR;
    END IF;
    RETURN ODCICONST.SUCCESS;
  END;
END;

2.1.5 自定义行变列函数
CREATE OR REPLACE FUNCTION wm_concat(P1 VARCHAR2) RETURN VARCHAR2
  AGGREGATE USING WM_CONCAT_IMPL;
2.1.6 创建同义词并赋权
create public synonym WM_CONCAT_IMPL for wmsys.WM_CONCAT_IMPL
/
create public synonym wm_concat for wmsys.wm_concat
/
grant execute on WM_CONCAT_IMPL to public
/
grant execute on wm_concat to public
/

2.2 无WMSYS用户处理方法

2.2.1文件检查

​ 查看数据库服务器上的$ORACLE_HOME/rdbms/admin目录下是否存在owmctab.plb、

owmaggrs.plb、owmaggrb.plb三个文件,如果存在直接进行2.2.2,如果不存在下载owmctab.plb、

owmaggrs.plb、owmaggrb.plb三个文件到数据库服务器上的$ORACLE_HOME/rdbms/admin目录下。

2.2.2执行plb文件
sqlplus / as sysdba
--执行plb文件
@/$ORACLE_HOME/rdbms/admin/owmctab.plb
@/$ORACLE_HOME/rdbms/admin/owmaggrs.plb
@/$ORACLE_HOME/rdbms/admin/owmaggrb.plb
--ORACLE_HOME未配置的可以使用绝对路径进行执行,该路径根据自身实际情况进行修改
@/u01/app/oracle/11.2.0.4/dbhome_1/rdbms/admin/owmctab.plb
@/u01/app/oracle/11.2.0.4/dbhome_1/rdbms/admin/owmaggrs.plb
@/u01/app/oracle/11.2.0.4/dbhome_1/rdbms/admin/owmaggrb.plb
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
可以使用Java编写一个程序,通过JDBC连接Oracle数据库,读取其的表和数据,然后将其转换为MySQL语法,并通过JDBC连接MySQL数据库,将数据写入其。 下面是一个简单的代码示例: ```java import java.sql.*; public class OracleToMySQL { public static void main(String[] args) { String oracleUrl = "jdbc:oracle:thin:@localhost:1521:ORCL"; String oracleUser = "username"; String oraclePassword = "password"; String mysqlUrl = "jdbc:mysql://localhost:3306/mysql"; String mysqlUser = "root"; String mysqlPassword = "password"; try { // Connect to Oracle database Connection oracleConnection = DriverManager.getConnection(oracleUrl, oracleUser, oraclePassword); Statement oracleStatement = oracleConnection.createStatement(); // Connect to MySQL database Connection mysqlConnection = DriverManager.getConnection(mysqlUrl, mysqlUser, mysqlPassword); Statement mysqlStatement = mysqlConnection.createStatement(); // Read tables from Oracle ResultSet tables = oracleStatement.executeQuery("SELECT table_name FROM user_tables"); while (tables.next()) { String tableName = tables.getString(1); // Read columns from Oracle ResultSet columns = oracleStatement.executeQuery("SELECT column_name, data_type FROM user_tab_columns WHERE table_name = '" + tableName + "'"); StringBuilder createTableSql = new StringBuilder("CREATE TABLE " + tableName + " ("); while (columns.next()) { String columnName = columns.getString(1); String dataType = columns.getString(2); createTableSql.append(columnName + " " + dataType + ","); } createTableSql.setLength(createTableSql.length() - 1); createTableSql.append(")"); mysqlStatement.execute(createTableSql.toString()); // Read data from Oracle and insert into MySQL ResultSet data = oracleStatement.executeQuery("SELECT * FROM " + tableName); while (data.next()) { StringBuilder insertSql = new StringBuilder("INSERT INTO " + tableName + " VALUES ("); ResultSetMetaData metaData = data.getMetaData(); for (int i = 1; i <= metaData.getColumnCount(); i++) { String value = data.getString(i); insertSql.append("'" + value + "',"); } insertSql.setLength(insertSql.length() - 1); insertSql.append(")"); mysqlStatement.execute(insertSql.toString()); } } // Close connections mysqlStatement.close(); mysqlConnection.close(); oracleStatement.close(); oracleConnection.close(); } catch (SQLException e) { e.printStackTrace(); } } } ``` 需要注意的是,该代码仅供参考,实际应用需要考虑更多的细节和异常情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40714023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值