【问题标题】:Can't figure out the SQL code无法弄清楚SQL代码
【发布时间】:2017-07-14 07:24:06
【问题描述】:

CREATE TABLE empinf(
companyid varchar2(5) PRIMARY KEY,
companyname varchar2(30) NOT NULL,
emailid varchar2(20) REFERENCES usrinf(emailid),
Mobile number CONSTRAINT moc CHECK(LENGTH(Mobile)=10),
city varchar2(20),
industrytype varchar2(20),
functionalarea varchar2(20),
membershipplan varchar2(20) CONSTRAINT cmp CHECK(membershipplan in ('TRIAL','PREMIUM MONTHLY','PREMIUM YEARLY')),
dateofsignup date DEFAULT SYSDATE CONSTRAINT chd CHECK( dateofsignup>=SYSDATE ),
dateofrenewal date generated always as 
    (CASE
        WHEN membershipplan='TRIAL' THEN SYSDATE+14 
        WHEN membershipplan='PREMIUM MONTHLY' THEN SYSDATE+30
        WHEN membershipplan='PREMIUM YEARLY' THEN SYSDATE+365
        ELSE SYSDATE
    END
    ) virtual,
renewalstatus varchar2(20) CONSTRAINT chrs CHECK(renewalstatus in('ACTIVE','EXPIRED')),
CONSTRAINT mun UNIQUE(Mobile)
) 

此代码将在 Oracle Express 11G 中生成,我无法弄清楚代码有什么问题,它显示“缺少括号错误”。

【问题讨论】:

  • “缺少括号错误”是整个错误消息吗?
  • 在我看来问题可能出在 DATEOFRENEWAL 的 CASE 中(SQL 错误:ORA-54002:只能在虚拟列表达式中指定纯函数)
  • 我建议如下: 编写一个创建表的基本结构的语句。然后开始添加主/外键约束,然后添加唯一/普通索引,最后添加检查约束。这样,您将清楚地理解语句的不同部分,并且在出现问题时,您会更容易指出。这里的例子必须几乎完全重写才能工作,所以从基础开始。
  • @afonte yes.'ORA-00907 Missing Right Paranthesis' 是整个错误消息。
  • @etsa 那我该如何重写呢?

标签: sql oracle


【解决方案1】:

据我所知,在虚拟列中,您需要定义一个确定性函数(一个返回相同值的函数,无论何时调用它。

您可以尝试在 case 中使用 dateofsignup 而不是 SYSDATE。

dateofrenewal date generated always as 
    (CASE
        WHEN membershipplan='TRIAL' THEN dateofsignup+14 
        WHEN membershipplan='PREMIUM MONTHLY' THEN dateofsignup+30
        WHEN membershipplan='PREMIUM YEARLY' THEN dateofsignup+365
        ELSE dateofsignup
    END
    ) virtual

或者您可以将其从表格中移除并使用视图。

我忘记了另一个错误(我正专注于第一个错误,所以我为这个失误道歉)。正如 Thorsten 在其他答案中所说,您无法以这种方式为 datesignup 设置检查约束。
Torstein 建议的其他解决方案,另一种解决方案可能是添加另一列(例如DATE_INSERT DATE DEFAULT SYSDATE

并将约束更改 datesignup 定义写为

dateofsignup date DEFAULT SYSDATE

并添加

ALTER TABLE empinf ADD CONSTRAINT chd CHECK( dateofsignup>=DATE_INSERT)

您的括号缺失错误可能是由于您在对代码的某些部分进行注释时的尝试造成的。

提示:我同意上面的 g00dy 评论:用一个命令创建表基本结构,然后用单独的命令添加约束。

【讨论】:

    【解决方案2】:

    奇怪的是,您收到“缺少括号”错误。也许你用来执行语句的工具吞下了最后一个括号?

    我收到“ORA-02436:在 CHECK 约束中错误指定日期或系统变量”

    CONSTRAINT chd CHECK( dateofsignup>=SYSDATE )
    

    您不能在检查约束中使用SYSDATE,因为SYSDATE 可能会发生变化。检查约束必须是稳定的,并且不能依赖于当前时间、当前会话设置等。你需要一个触发器来做你想做的事情。

    删除该检查约束后,我得到“ORA-54002:只能在虚拟列表达式中指定纯函数”,原因大致相同。

    dateofrenewal date generated always as 
        (CASE
            WHEN membershipplan='TRIAL' THEN SYSDATE+14 
    ...
    

    虚拟列必须是稳定的,并且只能依赖于其他列,而不是当前时间、当前会话设置等。您可能希望 dateofrenewal 改为基于 dateofsignup 计算。

    【讨论】:

      猜你喜欢
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2014-09-03
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多