尝试在作为函数参数传递的UDT列中使用Oracle TABLE()函数时,ORA-00904

时间:2017-11-01 15:04:46

标签: sql oracle plsql user-defined-types

给定以下类型层次结构:

CREATE OR REPLACE TYPE VC_MNumber AS Object (   
  idno NUMBER,
  MEMBER FUNCTION   typeDimension   RETURN NUMBER ,
  MEMBER FUNCTION typeName RETURN VARCHAR2) NOT INSTANTIABLE NOT FINAL;
/

CREATE OR REPLACE TYPE VC_MReal UNDER VC_MNumber(   
  YDCCoeff NUMBER,
  CbDCCoeff NUMBER,
  CrDCCoeff NUMBER,
  OVERRIDING MEMBER FUNCTION  typeDimension   RETURN NUMBER, 
  OVERRIDING MEMBER FUNCTION typeName RETURN VARCHAR2) FINAL;
/

CREATE OR REPLACE TYPE BODY VC_MReal AS
  OVERRIDING MEMBER FUNCTION typeDimension RETURN NUMBER IS
    var_dimension       number :=  10;
    BEGIN
        RETURN var_dimension;
    END;
   OVERRIDING MEMBER FUNCTION typeName RETURN VARCHAR2 IS
    var_typeName        VARCHAR2(400) :=  'VC_MREAL';
    BEGIN
        RETURN var_typeName;
    END;
END;
/

表格:

CREATE TABLE cophirfv_int( 身份证号码, fv VC_MReal );

我正在尝试执行该功能:

create or replace function sum_MNumber
(
    inn_FV VC_MNumber,
    out_FV VC_MNumber
) return NUMBER is
   sql_stmt1 varchar2(400);
   total_sum number := 0;
   inn_val number;
   cur_type varchar2(400);
   var_cur_type_name varchar2(400);
BEGIN
    FOR cur_type IN (select attr_name from user_type_attrs where type_name='VC_MREAL')
        LOOP    


        var_cur_type_name := cur_type.attr_name;

        dbms_output.put_line(var_cur_type_name);

        sql_stmt1 := 'SELECT ifv.' || var_cur_type_name ||' FROM TABLE(inn_FV.'|| var_cur_type_name ||') ifv';

        dbms_output.put_line(sql_stmt1);

        EXECUTE IMMEDIATE sql_stmt1 INTO inn_val;

        --total_sum := total_sum + inn_val;
    END LOOP;
    return 2;
END;
/

通过查询:

select sum_MNumber(fv,fv) from cophirfv_int;

但我收到错误ORA-00904:" INN_FV"。" CRDCCOEFF"该行上的标识符无效:

EXECUTE IMMEDIATE sql_stmt1 INTO inn_val;

有人知道出了什么问题吗?我该如何解决?

2 个答案:

答案 0 :(得分:1)

您不需要动态SQL,而是可以使用class Model(nn.Module): def __init__(self, inputs_vocab_size, embedding_dim, out_units=128, hidden_size=128, nlayers=1, num_directions=1, dropout=0.1): super(Model, self).__init__() ... self.encoder = nn.Embedding(inputs_vocab_size, embedding_dim).cuda() self.rnn = nn.RNN(embedding_dim, hidden_size, nlayers, dropout=0.5) self.decoder = nn.Linear(hidden_size * num_directions, inputs_vocab_size) ... 运算符和IS OF( type )函数:

SQL Fiddle

Oracle 11g R2架构设置

TREAT

查询1

create function sum_MNumber
(
    inn_FV VC_MNumber,
    out_FV VC_MNumber
) return NUMBER
IS
  total NUMBER := 0;
BEGIN
  IF inn_FV IS OF( VC_MReal ) THEN
    total := total + TREAT( inn_FV AS VC_Mreal ).YDCCoeff
                   + TREAT( inn_FV AS VC_Mreal ).CbDCCoeff
                   + TREAT( inn_FV AS VC_Mreal ).CrDCCoeff;
  END IF;
  IF out_FV IS OF( VC_MReal ) THEN
    total := total + TREAT( out_FV AS VC_Mreal ).YDCCoeff
                   + TREAT( out_FV AS VC_Mreal ).CbDCCoeff
                   + TREAT( out_FV AS VC_Mreal ).CrDCCoeff;
  END IF;
  RETURN total;
END;
/

INSERT INTO cophirfv_int VALUES ( 1, VC_MReal( 1, 3, 4, 5 ) )
/

INSERT INTO cophirfv_int VALUES ( 2, VC_MReal( 2, 1, 3, 4 ) )
/

<强> Results

select sum_MNumber(fv,fv) from cophirfv_int

替代

或者你可以在类型中定义一个approriate成员函数:

SQL Fiddle

Oracle 11g R2架构设置

| SUM_MNUMBER(FV,FV) |
|--------------------|
|                 24 |
|                 16 |

查询1

CREATE OR REPLACE TYPE VC_MNumber AS Object (   
  idno NUMBER,
  MEMBER FUNCTION total RETURN NUMBER
) NOT INSTANTIABLE NOT FINAL;
/

CREATE OR REPLACE TYPE VC_MReal UNDER VC_MNumber(   
  YDCCoeff NUMBER,
  CbDCCoeff NUMBER,
  CrDCCoeff NUMBER,
  OVERRIDING MEMBER FUNCTION total RETURN NUMBER
) FINAL;
/

CREATE OR REPLACE TYPE BODY VC_MReal AS
  OVERRIDING MEMBER FUNCTION total RETURN NUMBER IS
  BEGIN
    RETURN self.YDCCoeff + self.CbDCCoeff + self.CrDCCoeff;
  END;
END;
/

CREATE TABLE cophirfv_int ( id NUMBER, fv VC_MReal )
/

INSERT INTO cophirfv_int VALUES ( 1, VC_MReal( 1, 3, 4, 5 ) )
/

INSERT INTO cophirfv_int VALUES ( 2, VC_MReal( 2, 1, 3, 4 ) )
/

create or replace function sum_MNumber
(
    inn_FV VC_MNumber,
    out_FV VC_MNumber
) return NUMBER
IS
  total NUMBER := 0;
BEGIN
  RETURN inn_Fv.total() + out_FV.total();
END;
/

<强> Results

select sum_MNumber(fv,fv) from cophirfv_int

答案 1 :(得分:0)

使用动态SQL:

(我不相信使用它是一个好主意,我只是将其作为概念验证发布。相反,你应该在每个子类型上定义OVERRIDING MEMBER FUNCTION,在我的另一个答案中,并呼吁那些)

SQL Fiddle

Oracle 11g R2架构设置

CREATE FUNCTION sum_MNumber
(
  i_FV VC_MNumber
) RETURN NUMBER
IS
  value NUMBER;
  total NUMBER := 0;
  type_names SYS.ODCIVARCHAR2LIST;
  attr_names SYS.ODCIVARCHAR2LIST;
BEGIN
  SELECT t.type_name,
         attr_name
  BULK COLLECT INTO
         type_names,
         attr_names
  FROM   USER_TYPE_ATTRS a
         INNER JOIN
         USER_TYPES t
         ON ( a.type_name = t.type_name )
  WHERE  t.TYPEID = SYS_TYPEID( i_FV );

  FOR i IN 1 .. type_names.COUNT LOOP
    EXECUTE IMMEDIATE
      'BEGIN :1 := TREAT(:2 AS "' || type_names(i) || '")."' || attr_names(i) || '"; END;'
      USING OUT value, i_FV;
    total := total + value;
  END LOOP;

  RETURN total;
END;
/

INSERT INTO cophirfv_int VALUES ( 1, VC_MReal( 1, 3, 4, 5 ) )
/

INSERT INTO cophirfv_int VALUES ( 2, VC_MReal( 2, 1, 3, 4 ) )
/

查询1

select sum_MNumber(fv) from cophirfv_int

<强> Results

| SUM_MNUMBER(FV) |
|-----------------|
|              13 |
|              10 |