该值未正确存储在数组中

Posted

技术标签:

【中文标题】该值未正确存储在数组中【英文标题】:the value is not storing properly in an array 【发布时间】:2016-10-04 08:31:48 【问题描述】:

我有一个 define_Variable.sql 文件并包含

DEFINE T_SCHEMA='HR'; 

2) Create_table.sql

@define_variable.sql

DECLARE 
        TYPE table_array IS TABLE OF VARCHAR2(200);
         table_list table_array;
         l_query varchar2(500);
         is_exst number :=0;
         nt_exst number :=0;

        BEGIN
              l_query:= 'select  TABLE_NAME from DBA_tables WHERE OWNER = :OWNER and TABLE_NAME IN (''employee'',''appraisal'')';

execute immediate l_query BULK COLLECT INTO table_list USING '&T_SCHEMA' ;
          DBMS_OUTPUT.PUT_LINE('Total Tables to be deployed is :'||table_list.count);

IF 'employee' member of table_list THEN
           DBMS_OUTPUT.PUT_LINE('employee TABLE ALREADY EXISTS');

         ELSE
           Execute Immediate(' create table employee( id number,name varchar2(50))');
           DBMS_OUTPUT.PUT_LINE('employee TABLE created');
end if;
end;
/

当我执行脚本时,它将检查表是否存在条件,如果存在,它将显示消息为“已经存在”,否则,它将创建一个表。 所以任何时候,我的脚本都可以执行而不会抛出错误。

现在,问题是,当我运行脚本时,由于名称已经存在,它会抛出错误,数组 table_list.count 的计数显示为零。它将变为 else 条件而不是 IF 条件。可能是什么原因?

【问题讨论】:

为什么在检查表是否已经存在时指定schema名称,而在创建表时不指定?它将在当前模式中创建它,这可能与&T_SCHEMA 不同。如果它始终是当前模式,您可以简化代码,因为您不需要变量。或者通过尝试创建表来进一步简化它,并根据需要处理 ORA-00955 name is already used 异常。 ***.com/help/someone-answers 【参考方案1】:

当你这样做时

create table employee( id number,name varchar2(50))

表名是not a quoted identifier(这很好!),数据字典中的对象名将是大写的EMPLOYEE

当您查询数据字典时,名称需要与该大小写匹配:

l_query:= 'select  TABLE_NAME from DBA_tables WHERE OWNER = :OWNER and TABLE_NAME IN (''EMPLOYEE'',''APPRAISAL'')';

当你查看集合时,它也需要是大写的:

IF 'EMPLOYEE' member of table_list THEN

您的USING 子句看起来也有问题;

USING '.&T_SCHEMA.' ;

意味着它将查找所有者值'.HR',而不仅仅是'HR',除非您已努力创建名称中带有点的新模式(作为带引号的标识符),否则将与该所有者无关。您已经使用了一个尾随点来 - 大概 - 终止替换变量名称,这很好,但在这里并不严格要求。你不应该有一个前导点:

USING '&T_SCHEMA.' ;

因此,目前您正在使用不存在的所有者名称和表名称填充您的集合,因为它们与数据字典中的实际内容不匹配。

【讨论】:

嗨,Alex,感谢 cmets,我尝试使用大写字母,但它不起作用。我的实时项目有超过 15 个表,尽管某些表已经存在,但数组显示为空。 您是否也修复了替换中的前导点?如果你有set verify on,你可以确切地看到替换在做什么。 哇,它有效,我相信它使用尾随点的错误,解决了我的问题亚历克斯。非常感谢 The trailing dot is OK - 虽然没有必要。前导点不对。【参考方案2】:

或者,您可以使用以下方法来实现您的目标:

DECLARE
   TYPE table_array IS TABLE OF VARCHAR2 (200);
   table_list   table_array;

   l_query      VARCHAR2 (500);
   is_exst      NUMBER := 0;
   nt_exst      NUMBER := 0;
BEGIN
   l_query :=
      'select  TABLE_NAME from DBA_tables WHERE OWNER = :OWNER and TABLE_NAME IN (''EMPLOYEE'',''appraisal'')';

   EXECUTE IMMEDIATE l_query BULK COLLECT INTO table_list USING '&T_SCHEMA.';

   DBMS_OUTPUT.PUT_LINE (
      'Total Tables to be deployed is :' || table_list.COUNT);

  for i in 1..table_list.count
  loop
    IF table_list(i) = 'EMPLOYEE' THEN
       DBMS_OUTPUT.PUT_LINE ('employee TABLE ALREADY EXISTS');       
     ELSE
      EXECUTE IMMEDIATE
         (' create table employee( id number,name varchar2(50))');

      DBMS_OUTPUT.PUT_LINE ('employee TABLE created');
   END IF;

  end loop;
--
-- IF 'employee' MEMBER OF table_list
--   THEN
--      DBMS_OUTPUT.PUT_LINE ('employee TABLE ALREADY EXISTS');
--   ELSE      
--      EXECUTE IMMEDIATE
--         (' create table employee( id number,name varchar2(50))');
--
--      DBMS_OUTPUT.PUT_LINE ('employee TABLE created');
--   END IF;
END;
/

【讨论】:

如果employeeappraisal都存在,则表数为2;假设他们按照这个顺序,当i=1 它将看到该员工已经存在并报告它。当i=2 的值将是'APPRAISAL',所以它仍然会尝试再次创建员工表。 @XING,感谢您的帮助 @AlexPoole.我猜 OP 刚刚询问了一个示例,说明他为什么动态创建员工表。在实际场景中,它应该是动态的。 @AnishGopinath ..尽管亚历克斯所说的是正确的,但我只是为您的工作提供了一个替代方案。你所做的也是正确的。

以上是关于该值未正确存储在数组中的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 Header 值未正确附加 [重复]

单选按钮值未存储在数据库中

无法找出为啥该值未定义

Flutter/Dart - 文本值未正确显示

我的 SKSpriteNode 速度值未正确更新

布尔值未在 Hibernate 中与 MySQL 正确映射