Oracle ORA-00907:缺少右括号,ORA-06512:在第16行

Oracle ORA-00907:缺少右括号,ORA-06512:在第16行,oracle,stored-procedures,plsql,oracle-sqldeveloper,procedure,Oracle,Stored Procedures,Plsql,Oracle Sqldeveloper,Procedure,对于下面的过程,我在Oracle SQL developer中运行时遇到了标题中提到的ora错误 DECLARE sqlstr VARCHAR2(1000); CURSOR TabSubPartitions IS SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'PART_TABLE' ORDER BY PARTITION_NAME; BEGIN FOR aSubPart

对于下面的过程,我在Oracle SQL developer中运行时遇到了标题中提到的ora错误

DECLARE

sqlstr VARCHAR2(1000);

CURSOR TabSubPartitions IS
SELECT TABLE_NAME, PARTITION_NAME
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = 'PART_TABLE'
ORDER BY PARTITION_NAME;

BEGIN

    FOR aSubPart IN TabSubPartitions LOOP
       IF TRUNC(LAST_DAY(SYSDATE)) = '31-07-2020' THEN
          sqlstr := 'ALTER TABLE '||aSubPart.TABLE_NAME||' MODIFY PARTITION '||aSubPart.PARTITION_NAME|| ' ADD SUBPARTITION ' ||aSubPart.PARTITION_NAME||'_'||TO_CHAR(TRUNC(LAST_DAY(SYSDATE))+1, 'MON_YYYY')||' VALUES LESS THAN ( '||TO_DATE(TRUNC(LAST_DAY(SYSDATE))+2, 'SYYYY-MM-DD HH24:MI:SS' , 'NLS_CALENDER=GREGORIAN')||')' ; 
           EXECUTE IMMEDIATE sqlstr;
        END IF;
      END LOOP;
  END;

谁能帮帮我吗。非常感谢。我有几条建议

首先,修改代码以输出
sqlstr
的值,这样您就可以准确地看到您试图执行的SQL语句是什么。这将更容易理解语法错误的位置

其次,将
TRUNC(LAST_DAY(SYSDATE))=“31-07-2020”
更改为在从日期转换为字符串时使用显式日期格式。类似于
TO_CHAR(TRUNC(LAST_DAY(SYSDATE)),'DD-MM-YYYY')…
。我认为这与您的错误无关,但这比依赖隐式转换格式更好


第三,仔细查看截止日期的通话。实际上,您似乎正在使用DATE参数调用_DATE,然后隐式地将其转换回字符串。在最好的情况下,这是没有必要的,在最坏的情况下,这将导致意外的行为。我猜您可能只是想在当前必须约会的地方使用to CHAR。

块本身的主要问题是:

'NLS_CALENDER=GREGORIAN'
它一定在哪里

'NLS_CALENDAR=GREGORIAN'
此外,您不应该依赖隐式日期转换

但是,生成的
altertable
语句也有一个问题,它看起来像

ALTER TABLE MODIFY PARTITION ... VALUES LESS THAN ( 02.08.2020 00:00:00)
取决于会话日期设置(同样是由于隐式日期转换)。我怀疑Oracle是否接受这样的时间戳。请确保生成正确的日期文字(如日期“2020-08-02”)

整个更正代码:

DECLARE
  sqlstr VARCHAR2(1000);

  CURSOR TabSubPartitions IS
    SELECT TABLE_NAME, PARTITION_NAME
    FROM USER_TAB_PARTITIONS
    WHERE TABLE_NAME = 'PART_TABLE'
    ORDER BY PARTITION_NAME;
BEGIN
  FOR aSubPart IN TabSubPartitions LOOP
    IF TRUNC(LAST_DAY(SYSDATE)) = DATE '2020-07-31' THEN
      sqlstr := 
        'ALTER TABLE ' || aSubPart.TABLE_NAME || ' MODIFY PARTITION ' || aSubPart.PARTITION_NAME ||
        ' ADD SUBPARTITION '  || aSubPart.PARTITION_NAME || '_' || TO_CHAR(TRUNC(LAST_DAY(SYSDATE))+1, 'MON_YYYY') ||
        ' VALUES LESS THAN (DATE ''' || TRIM(TO_CHAR(TRUNC(LAST_DAY(SYSDATE))+2, 'SYYYY-MM-DD', 'NLS_CALENDAR=GREGORIAN')) || ''')' ; 
      EXECUTE IMMEDIATE sqlstr;
    END IF;
  END LOOP;
END;

你好,戴夫,非常感谢你给我写信。我是PL/SQL新手。请您指导我您的第一点:如何获得sqlstr的输出,以便我可以分析语法错误。@Sneha:那将是
dbms\u输出。put\u行(sqlstr)我现在可以理解哪里有我所有的错误。非常感谢。