无法弄清楚SQL代码

时间:2017-07-14 07:24:06

标签: sql oracle

enter image description here

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中生成,我无法弄清楚代码有什么问题,它显示“缺少paranthesis错误”。

2 个答案:

答案 0 :(得分:3)

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

您可以尝试在案例中使用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

并将约束更改为dateignup定义为

dateofsignup date DEFAULT SYSDATE

并添加

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

您遗漏的括号错误可能是由您的尝试引起的,而您则评论了代码的某些部分。

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

答案 1 :(得分:1)

奇怪的是你得到了“缺失的paranthesis”错误。也许你用来执行语句的工具吞下最后一个paranthesis?

我收到“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