文章
姚 鑫 · 九月 18 阅读大约需 4 分钟

第十九章 SQL命令 CREATE TABLE(六)

第十九章 SQL命令 CREATE TABLE(六)

WITH子句,%CLASSPARAMETER关键字,STORAGETYPE关键字

可选的WITH子句可以在表格元素逗号结尾的圆括号之后和Shard Key定义(如果存在的话)之后指定。
WITH子句可以包含一个用逗号分隔的列表:
- 一个或多个%CLASSPARAMETER 子句。
- STORAGETYPE子句

%CLASSPARAMETER子句

WITH关键字之后,可以指定多个%CLASSPARAMETER关键字子句,每个子句定义一个类参数。
多个%CLASSPARAMETER子句子句之间用逗号分隔。
为了向后兼容,支持将%CLASSPARAMETER关键字子句指定为table-element-commalist中的元素。
在两个位置中指定相同的%CLASSPARAMETER关键字子句将产生SQLCODE -327错误。

%CLASSPARAMETER关键字后面跟着类参数名称、一个可选的等号和要分配给该类参数的文字值(字符串或数字)。
类参数总是定义为常数值。

因为用户可以用任何名称或值定义额外的类参数,所以只执行语法验证;
既不验证类参数是否存在,也不验证类参数的有效值。
下面的示例定义了两个类参数;
第一个%CLASSPARAMETER子句使用了等号,第二个省略了等号:

CREATE TABLE OurEmployees (
    EMPNUM     INT NOT NULL,
    NAMELAST   CHAR(30) NOT NULL,
    NAMEFIRST  CHAR(30) NOT NULL,
    CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM)
    )
WITH %CLASSPARAMETER DEFAULTGLOBAL = '^GL.EMPLOYEE',
     %CLASSPARAMETER MANAGEDEXTENT 0

DEFAULTGLOBAL:默认情况下,CREATE TABLE用生成的全局名称为创建的表创建IDKEY索引,例如^EPgS.D8T6.1;
其他索引使用生成的具有唯一整数后缀的相同全局名称。这个例子指定%CLASSPARAMETER DEFAULTGLOBAL = '^GL.EMPLOYEE'
作为索引的显式全局名称。可以使用DEFAULTGLOBAL指定扩展的全局引用,或者完整引用(%CLASSPARAMETER DEFAULTGLOBAL = '^|"USER"|GL.EMPLOYEE')或者只是命名空间部分 (%CLASSPARAMETER DEFAULTGLOBAL = '^|"USER"|')

当前使用的类参数有ALLOWIDENTITYINSERT, DATALOCATIONGLOBAL, DEFAULTGLOBAL, DSINTERVAL, DSTIME, EXTENTQUERYSPEC, EXTENTSIZE, GUIDENABLED, MANAGEDEXTENT, READONLY, ROWLEVELSECURITY, SQLPREVENTFULLSCAN, USEEXTENTSET, VERSIONCLIENTNAME, VERSIONPROPERTY

可以使用USEEXTENTSETDEFAULTGLOBAL类参数定义表数据存储和索引数据存储的全局命名策略。

IDENTIFIEDBY类参数已弃用。
必须将IDENTIFIEDBY关系转换为 IRIS中支持的正确的父/子关系。

定义分片表的CREATE TABLE不能定义DEFAULTGLOBALDSINTERVALDSTIMEVERSIONPROPERTY类参数。

STORAGETYPE子句

WITH关键字之后,可以指定一个STORAGETYPE子句,STORAGETYPE=ROWSTORAGETYPE=COLUMN。该表选项用于设置STORAGEDEFAULT参数。
如果指定ROW,则PARAMETER STORAGEDEFAULT;
将出现在类定义中。将出现在类定义中。
如果指定COLUMN,则PARAMETER STORAGEDEFAULT = "column";
将出现在类定义中。

如果多次指定STORAGETYPE,则生成SQLCODE -327错误。

示例:动态SQL和嵌入式SQL

下面的示例演示了使用动态SQL和嵌入式SQL创建表。
注意,在动态SQL中,可以在同一个程序中创建一个表并将数据插入到表中;
在嵌入式SQL中,必须使用单独的程序来创建表并将数据插入到表中。

最后一个程序示例删除表,以便可以重复运行这些示例。

下面的动态SQL示例创建表SQLUser.MyStudents
注意,因为COMPUTECODE是ObjectScript代码,而不是SQL代码,ObjectScript $PIECE函数使用双引号分隔符;
因为这行代码本身是一个带引号的字符串,$PIECE分隔符必须通过加倍的方式转义为字面量,如下所示:

ClassMethod CreateTable7()
{
    s stuDDL=5
    s stuDDL(1)="CREATE TABLE SQLUser.MyStudents ("
    s stuDDL(2)="StudentName VARCHAR(32),StudentDOB DATE,"
    s stuDDL(3)="StudentAge INTEGER COMPUTECODE {SET {StudentAge}="
    s stuDDL(4)="$PIECE(($PIECE($H,"","",1)-{StudentDOB})/365,""."",1)} CALCULATED,"
    s stuDDL(5)="Q1Grade CHAR,Q2Grade CHAR,Q3Grade CHAR,FinalGrade VARCHAR(2))"
    s tStatement = ##class(%SQL.Statement).%New(0,"Sample")
    s qStatus = tStatement.%Prepare(.stuDDL)
    if qStatus'=1 {
        w "%Prepare failed:" 
        d $System.Status.DisplayError(qStatus) 
        q 
    }
    s rtn = tStatement.%Execute()
    if rtn.%SQLCODE = 0 {
        w !,"表创建成功"
    } elseif rtn.%SQLCODE=-201 {
        w "表已存在,SQLCODE=",rtn.%SQLCODE,!
    } else {
        w !,"表创建失败,SQLCODE=",rtn.%SQLCODE,!
        w rtn.%Message,! 
    }
}

以下嵌入式 SQL 示例创建表 SQLUser.MyStudents

ClassMethod CreateTable8()
{
    &sql(CREATE TABLE SQLUser.MyStudents 
        (
            StudentName VARCHAR(32),StudentDOB DATE,
            StudentAge INTEGER COMPUTECODE {
                SET {StudentAge}=
                $PIECE(($PIECE($H,",",1)-{StudentDOB})/365,".",1)
            } CALCULATED,
            Q1Grade CHAR,Q2Grade CHAR,Q3Grade CHAR,FinalGrade VARCHAR(2)
        )
    )
    if SQLCODE=0 {
        WRITE !,"Created table" 
    } ELSEIF SQLCODE=-201 {
        WRITE !,"SQLCODE=",SQLCODE," ",%msg 
    } ELSE {
        WRITE !,"CREATE TABLE failed, SQLCODE=",SQLCODE 
    } 
}

以下示例删除由前面的示例创建的表:

ClassMethod CreateTable9()
{
    &sql(
        DROP TABLE SQLUser.MyStudents
    )
    if SQLCODE=0 {
        w !,"表已删除" 
    } else {
        w !,"SQLCODE=",SQLCODE," ",%msg 
    }
}
00
1 0 0 5
Log in or sign up to continue