Oracle PL/SQL:SQL语句被忽略,PL/SQL:ORA-00911:无效字符

Oracle PL/SQL:SQL语句被忽略,PL/SQL:ORA-00911:无效字符,oracle,plsql,Oracle,Plsql,下面的pl/sql函数用于从表“TESTER”中获取默认值,并从所有3种不同的默认数据类型中仅返回一个NOTNULL值 CREATE OR REPLACE TYPE mdvs AS OBJECT ( l_default_number NUMBER, l_default_text VARCHAR2(200), l_default_date DATE ); CREATE OR REPLACE FUNCTION DEF_VALUE (f_table_name IN VARCHAR2,f_column

下面的pl/sql函数用于从表“TESTER”中获取默认值,并从所有3种不同的默认数据类型中仅返回一个NOTNULL值

CREATE OR REPLACE TYPE mdvs AS OBJECT
(
l_default_number NUMBER,
l_default_text VARCHAR2(200),
l_default_date DATE
);

CREATE OR REPLACE FUNCTION DEF_VALUE (f_table_name IN VARCHAR2,f_column_name IN VARCHAR2)
RETURN v_mdvs 
IS 
obj_mdvs v_mdvs:=mdvs(0,NULL,NULL);
BEGIN
SELECT Def_NUMBER_Value,Def_TEXT_Value,Def_DATE_Value
INTO obj_mdvs.*,obj_mdvs.*,obj_mdvs.*
FROM    TESTER 
WHERE   Table_Name=f_table_Name
AND     Column_Name=f_column_Name;

IF (l_default_number != 0 ) THEN
obj_mdvs := mdvs(l_default_number);
ELSIF (l_default_text IS NOT NULL) THEN
obj_mdvs := mdvs(l_default_text);
ELSIF (l_default_date IS NOT NULL) THEN
obj_mdvs := mdvs(l_default_date);
ELSE
obj_mdvs :=mdvs('NULL');
END IF;
RETURN obj_mdvs;
END;
o/p: 类型MDV已编译

行/列错误 6/1 PL/SQL:忽略SQL语句 7/5 PL/SQL:ORA-00911:无效 字符错误:检查编译器日志

不确定如何处理此错误

编辑:我也面临下面代码中的错误。错误如下所述:

    create or replace function defaulttest
        ( f_table_name  in varchar2
        , f_column_name in varchar2 )
        return mdva
    is
        obj_mdva mdva;
    begin
        begin
            select mdva(defaultnumber), mdva(defaulttext), mdva(defaultdate)
            into   obj_mdva
            from   tester
            where  tablename = f_table_name
            and    columnname = f_column_name;
        exception
            when no_data_found then null;
        end;

        return
            case
                when obj_mdva.default_number is not null then
                    mdva(obj_mdva.default_number)
                when obj_mdva.default_text is not null then
                    mdva(obj_mdva.default_text)
                when obj_mdva.default_date is not null then
                    mdva(obj_mdva.default_date)
                else
                    mdva(null)
            end;
    end defaulttest;
错误: PL/SQL:SQL语句被忽略 PL/SQL:ORA-00947:值不足 PL/SQL:忽略语句 PLS-00307:太多的“MDVA”声明与此呼叫匹配

代码: 创建或替换类型mdva FORCE as对象 (默认编号) ,默认值_text varchar2(200) ,默认日期 ,构造函数mdva(num number)返回self作为结果 ,构造函数mdva(txt varchar2)返回self作为结果 ,构造函数mdva(dt date)返回self作为结果 ); /

o/p: Defaulttest('表','字段') SDPSGT.MDVA(4,NULL,NULL)

SQLQUERY: 挑选 案例 当DEFAULTNUMBER不为空时,则为\u CHAR(DEFAULTNUMBER) 当DEFAULTDATE不为空时,则为_CHAR(DEFAULTDATE,“YYYY-MM-DD”) ELSE默认文本 结束 作为列值 来自测试员 其中tablename='表
和columnname='field'

您不能在'into'子句中使用*。只需在此处指定变量:

选择定义编号值、定义文本值、定义日期值
分为obj_mdvs.l_default_编号、obj_mdvs.l_default_文本、obj_mdvs.l_default_日期
来自测试员
其中Table_Name=f_Table_Name
和Column_Name=f_Column_Name;
对象定义:(我删除了
l\u
前缀,因为我们通常对局部变量使用
l\u
,而不是类型属性):

测试数据:

insert all
    into tester(table_name, column_name, def_number_value)
    values ('T1', 'C1', 123)
    into tester(table_name, column_name, def_text_value)
    values ('T1', 'C2', 'Hello')
    into tester(table_name, column_name, def_date_value)
    values ('T1', 'C3', sysdate)
select * from dual;
功能:

create or replace function def_value
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return mdvs
is
    obj_mdvs mdvs;
begin
    begin
        select mdvs(def_number_value, def_text_value, def_date_value)
        into   obj_mdvs
        from   tester
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return
        case
            when obj_mdvs.default_number is not null then
                mdvs(obj_mdvs.default_number, null, null)
            when obj_mdvs.default_text is not null then
                mdvs(null, obj_mdvs.default_text, null)
            when obj_mdvs.default_date is not null then
                mdvs(null, null, obj_mdvs.default_date)
            else
                mdvs(0, null, null)
        end;
end def_value;
注意,我们在SQL中构造了一个名为
obj_mdvs
mdvs
对象,作为
select-into
语句的一部分。(我们也可以将这三个值提取到单独的变量中,然后在第二步中构造对象。)之后,它的属性中将包含值
obj\u mdvs.default\u number

我不确定当表中没有匹配行时,您希望使用什么作为默认返回,因为
mdvs('NULL')
无效(除非您定义构造函数),因为
mdvs
对象需要三个值。您可以调整
else
条件以满足您的要求

PL/SQL语法在
if
条件周围没有括号,因为它们由
then
关键字终止

将随机代码位大写在业界非常流行,甚至在文档示例中使用,但PL/SQL不是Cobol,也不再是1974,因此您不必这样做

测试:

result.default\u编号:
result.default_text:Hello
result.default\u日期:
编辑:再考虑一下,将值提取到单独的标量变量中可能会更简单,因为我们实际上从
选择到
中创建的变量中获取的值不多。重构版本:

create or replace function def_value
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return mdvs
is
    default_mdvs     mdvs := mdvs(0, null, null);
    l_default_number default_mdvs.default_number%type;
    l_default_text   default_mdvs.default_text%type;
    l_default_date   default_mdvs.default_date%type;
begin
    begin
        select def_number_value, def_text_value, def_date_value
        into   l_default_number, l_default_text, l_default_date
        from   tester
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return
        case
            when l_default_number is not null then
                mdvs(l_default_number, null, null)
            when l_default_text is not null then
                mdvs(null, l_default_text, null)
            when l_default_date is not null then
                mdvs(null, null, l_default_date)
            else
                default_mdvs
        end;
end def_value;
另一种编辑:例如,如果您需要自定义构造函数,以便仅使用
MDV(42)
定义对象,则它们可能如下所示:

create or replace type mdvs as object
( default_number number
, default_text varchar2(200)
, default_date date
, constructor function mdvs (num number) return self as result 
, constructor function mdvs (txt varchar2) return self as result 
, constructor function mdvs (dt date) return self as result 
);
/

create or replace type body mdvs as
    constructor function mdvs (num number) return self as result 
    is
    begin
        self.default_number := num;
        return;
    end;

    constructor function mdvs (txt varchar2) return self as result 
    is
    begin
        self.default_text:= txt;
        return;
    end;

    constructor function mdvs (dt date) return self as result 
    is
    begin
        self.default_date := dt;
        return;
    end;
end;
/
函数的另一个版本,如下注释:

我保留了
mdvc
的原始名称以及表列
def_number_value
def_text_value
def_date_value
。可以在您的环境中随意重命名它们

下面是一个在
select into
子句中创建三个对象的示例。它使
select
复杂化,但简化了
return
子句。此版本依赖于上面添加的对象构造函数

create or replace function defaulttest
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return mdvs
is
    obj_mdvs_number mdvs;
    obj_mdvs_text   mdvs;
    obj_mdvs_date   mdvs;
begin
    begin
        select mdvs(t.def_number_value), mdvs(t.def_text_value), mdvs(t.def_date_value)
        into   obj_mdvs_number, obj_mdvs_text, obj_mdvs_date
        from   tester t
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return coalesce(obj_mdvs_number, obj_mdvs_text, obj_mdvs_date);
end defaulttest;
好的,我保证最后一个版本。我认为您不需要任何对象类型,因为您只需要返回一个纯标量值(数字、文本或日期)。忘了那个东西吧

create or replace function defaulttest
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return varchar2
is
    l_numval tester.def_number_value%type;
    l_textval tester.def_text_value%type;
    t_dateval tester.def_text_value%type;
begin
    begin
        select t.def_number_value, t.def_text_value, t.def_date_value
        into   l_numval, l_textval, t_dateval
        from   tester t
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return coalesce(to_char(l_numval), l_textval, to_char(t_dateval));
end defaulttest;

感谢您的帮助。代码只需返回一个值(defaultnumber、defaulttext或defaultdate),而忽略那些具有空值的值。因此,我可以通过只传递一个类似MDV(l_default_number)的参数来获取,而不是MDV(l_default_number,null,null)。这是否会返回所需的结果?否,
mdvs
是一个具有三个属性的对象类型,因此其默认构造函数需要三个相应的参数。您可以在类型主体中定义三个自定义构造函数,每个数据类型一个。添加了对象构造函数的示例。您好,我如何处理函数?。我有一个密码,但似乎不起作用。面对错误。添加了代码。添加了函数的第三个版本,以说明选择到子句中的多个值。它是MDV还是mdva
tester
def_number_value
def_text_value
def_date_value
中的列是否与原始问题中的列相同,或者它们现在是否已更改为
defaultnumber
defaulttext
defaultdate
?值不足错误是因为您试图将三个对象提取到
obj_mdva
中。如果您想这样做,您需要声明其中三个,并将它们添加到
选择到
中。
create or replace type mdvs as object
( default_number number
, default_text varchar2(200)
, default_date date
, constructor function mdvs (num number) return self as result 
, constructor function mdvs (txt varchar2) return self as result 
, constructor function mdvs (dt date) return self as result 
);
/

create or replace type body mdvs as
    constructor function mdvs (num number) return self as result 
    is
    begin
        self.default_number := num;
        return;
    end;

    constructor function mdvs (txt varchar2) return self as result 
    is
    begin
        self.default_text:= txt;
        return;
    end;

    constructor function mdvs (dt date) return self as result 
    is
    begin
        self.default_date := dt;
        return;
    end;
end;
/
create or replace function defaulttest
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return mdvs
is
    obj_mdvs_number mdvs;
    obj_mdvs_text   mdvs;
    obj_mdvs_date   mdvs;
begin
    begin
        select mdvs(t.def_number_value), mdvs(t.def_text_value), mdvs(t.def_date_value)
        into   obj_mdvs_number, obj_mdvs_text, obj_mdvs_date
        from   tester t
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return coalesce(obj_mdvs_number, obj_mdvs_text, obj_mdvs_date);
end defaulttest;
create or replace function defaulttest
    ( f_table_name  in varchar2
    , f_column_name in varchar2 )
    return varchar2
is
    l_numval tester.def_number_value%type;
    l_textval tester.def_text_value%type;
    t_dateval tester.def_text_value%type;
begin
    begin
        select t.def_number_value, t.def_text_value, t.def_date_value
        into   l_numval, l_textval, t_dateval
        from   tester t
        where  table_name = f_table_name
        and    column_name = f_column_name;
    exception
        when no_data_found then null;
    end;

    return coalesce(to_char(l_numval), l_textval, to_char(t_dateval));
end defaulttest;