首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Oracle PLSQL调用java时如何将参数传递给java

从Oracle PLSQL调用java时如何将参数传递给java
EN

Stack Overflow用户
提问于 2017-10-10 13:02:10
回答 2查看 2.5K关注 0票数 1

我试图从plsql调用一个java函数,以返回csv字符串中某个索引处的csv项。csv字符串还可以在引号中包含分隔符(基于这个堆栈溢出问题)。

密码

代码语言:javascript
运行
复制
set serverout on size 100000

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "XxpayCsv" AS
import java.io.ByteArrayInputStream;
public class XxpayCsv
{
    public static String csv(String line, Integer idx)
    {
        String otherThanQuote = " [^\"] ";
        String quotedString = String.format(" \" %s* \" ", otherThanQuote);
        String regex = String.format("(?x) "+ // enable comments, ignore white spaces
                ",                         "+ // match a comma
                "(?=                       "+ // start positive look ahead
                "  (?:                     "+ //   start non-capturing group 1
                "    %s*                   "+ //     match 'otherThanQuote' zero or more times
                "    %s                    "+ //     match 'quotedString'
                "  )*                      "+ //   end group 1 and repeat it zero or more times
                "  %s*                     "+ //   match 'otherThanQuote'
                "  $                       "+ // match the end of the string
                ")                         ", // stop positive look ahead
                otherThanQuote, quotedString, otherThanQuote);

        String[] tokens = line.split(regex, -1);
        //for(String t : tokens) {
        //    System.out.println("> "+t);
        //}
        return tokens[idx];
    }
};
/

CREATE OR REPLACE
FUNCTION xxpay_csv_at(s varchar2, i number) RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'XxpayCsv.csv (s, i) return java.lang.String';
/

DECLARE
   my_string clob;   -- VARCHAR2(400 CHAR);
BEGIN
   my_string := xxpay_csv_at('a,"b,c",d', 1);
   dbms_output.put_line('The value of the string is: ' || my_string);
END;
/

给了我错误

代码语言:javascript
运行
复制
DECLARE
*
ERROR at line 1:
ORA-29531: no method csv in class XxpayCsv
ORA-06512: at "APPS.XXPAY_CSV_AT", line 1
ORA-06512: at line 4

因为我不知道如何将字符串和整数作为参数传递(我不是Java程序员)。我做错了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-10 13:37:12

您需要给函数规范中的数据类型(而不是参数名称)提供完整的java路径:

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION xxpay_csv_at(s varchar2, i number) RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'XxpayCsv.csv ( java.lang.String, java.lang.Integer ) return java.lang.String';
/

(注意:java.lang.Integer而不是int与您的规范在Java代码中匹配)

但是,您可能想要的只是在Oracle中实现所有这些:

SQL Fiddle

Oracle 11g R2架构设置

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION xxpay_csv_at(
  s varchar2,
  i number
) RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
  RETURN REGEXP_SUBSTR(
    s,
    '(^|,)(([^,"]*".*?")*[^,"]*)',
    1,
    i,
    NULL,
    2
  );
END;
/

查询1

代码语言:javascript
运行
复制
WITH table_name ( csv ) AS (
  SELECT 'foo,bar,c;qual="baz,b""lurb",d;junk="quux,syzygy"' FROM DUAL
)
SELECT csv,
       xxpay_csv_at( csv, 1 ) AS value1,
       xxpay_csv_at( csv, 2 ) AS value2,
       xxpay_csv_at( csv, 3 ) AS value3,
       xxpay_csv_at( csv, 4 ) AS value4
FROM   table_name

结果

代码语言:javascript
运行
复制
|                                               CSV | VALUE1 | VALUE2 |               VALUE3 |               VALUE4 |
|---------------------------------------------------|--------|--------|----------------------|----------------------|
| foo,bar,c;qual="baz,b""lurb",d;junk="quux,syzygy" |    foo |    bar | c;qual="baz,b""lurb" | d;junk="quux,syzygy" |

更新

是否有任何方法从regexp_substr中获取匹配值的位置,这样我不仅可以在某个索引上返回csv项,而且还可以返回原始csv字符串中开始和结束的字符位置?

使用REGEXP_INSTR而不是REGEXP_SUBSTR编写另一个函数。

或者使用下面的函数,分别返回CURRDPOS作为开始和结束。

(注意: SQL中使用的函数只能返回一个值,因此您需要返回一个带有值、开始和结束属性的对象类型,或者为子字符串、start和end有三个单独的函数。)

还希望能够添加分隔符和quoted_by作为参数,并支持“,”(在逗号后面有一个空格)。

是的,但不容易使用正则表达式。类似的情况(部分测试,但没有通过所有的边缘案例):

SQL Fiddle

Oracle 11g R2架构设置

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION xxpay_csv_at(
  s varchar2,
  i number,
  delim VARCHAR2 DEFAULT ','
) RETURN VARCHAR2 DETERMINISTIC
IS
  j    PLS_INTEGER := 1;
  curr PLS_INTEGER := 1;
  dpos PLS_INTEGER;
  qpos PLS_INTEGER;
BEGIN
  WHILE TRUE LOOP
    dpos := INSTR( s, delim, curr );
    qpos := INSTR( s, '"', curr ); -- Start quote
    WHILE qpos BETWEEN curr AND dpos LOOP
      qpos := INSTR( s, '"', qpos + 1 ); -- End quote
      IF qpos = 0 THEN
        RAISE_APPLICATION_ERROR( -20000, 'Invalid String - No matching end-quote' );
      END IF;
      dpos := INSTR( s, delim, qpos + 1 );
      qpos := INSTR( s, '"', qpos + 1 );
    END LOOP;

    IF dpos = 0 THEN
      IF i = j THEN
        RETURN SUBSTR( s, curr );
      ELSE
        RETURN NULL;
      END IF;
    ELSE
      IF i = j THEN
        RETURN SUBSTR( s, curr, dpos - curr );
      ELSE
        j := j + 1;
        curr := dpos + LENGTH( delim );
      END IF;
    END IF;
  END LOOP;
END;
/

查询2

代码语言:javascript
运行
复制
WITH table_name ( csv ) AS (
  SELECT ', foo,bar, c;qual="baz, b""lurb", d;junk="quux, syzygy", , ' FROM DUAL
)
SELECT csv,
       xxpay_csv_at( csv, 1, ', ' ) AS value1,
       xxpay_csv_at( csv, 2, ', ' ) AS value2,
       xxpay_csv_at( csv, 3, ', ' ) AS value3,
       xxpay_csv_at( csv, 4, ', ' ) AS value4,
       xxpay_csv_at( csv, 5, ', ' ) AS value5,
       xxpay_csv_at( csv, 6, ', ' ) AS value6
FROM   table_name

结果

代码语言:javascript
运行
复制
|                                                         CSV | VALUE1 |  VALUE2 |                VALUE3 |                VALUE4 | VALUE5 | VALUE6 |
|-------------------------------------------------------------|--------|---------|-----------------------|-----------------------|--------|--------|
| , foo,bar, c;qual="baz, b""lurb", d;junk="quux, syzygy", ,  | (null) | foo,bar | c;qual="baz, b""lurb" | d;junk="quux, syzygy" | (null) | (null) |
票数 3
EN

Stack Overflow用户

发布于 2017-10-10 13:06:33

答案是:

代码语言:javascript
运行
复制
CREATE OR REPLACE
FUNCTION xxpay_csv_at(s varchar2, i number) RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'XxpayCsv.csv (java.lang.String, int) return java.lang.String';
/
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46667489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档