返回首页

gbase数据、南大通用产品文档:GBase8sCREATE VIEW 语句

更新日期:2024年09月11日

使用 CREATE VIEW 语句创建新的视图,该视图基于驻留在数据库(或本地数据
库服务器或不同的数据库服务器中的另一个数据库)中的一个或多个现有表和视
图。
语法

元素
描述
限制
语法

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 502
column
在此处声明的视图中的列
的名称。缺省值是 SELECT
投影列表中的名称。
请参阅命名视图列。
标识符
owner
视图的所有者。如果省
略,缺省为发出此语句的
用户 ID 。
要指定另一个用户 ID
需要 DBA 存取权限。
所有者名称
row_type 已归类的视图的已命名行
类型
必须已经在数据库中存

数据类型
view
在此处声明的视图名称
在数据库中的视图、
表、序列和同义词名称
中必须唯一。
标识符
用法
视图是虚拟的表,由 SELECT 语句定义。除了以下列表中列出的语句,您可以在
任何表名称在语法上有效的 SQL 语句中指定视图的名称或同义词:

ALTER FRAGMENT

CREATE INDEX

CREATE TABLE

CREATE TRIGGER

RENAME TABLE

START VIOLATIONS TABLE

STOP VIOLATIONS TABLE

TRUNCATE

UPDATE STATISTICS
当您使用 CREATE TRIGGER 语句在视图上定义 INSTEAD OF 触发器时必须指
定视图的名称,但是此语法和功能与定义在表上的触发器不同。
通过视图更新禁止在 INSERT 、DELETE 或 UPDATE 语句中使用非可更新视图
(其中其它视图是有效的)。
要创建视图,您必须拥有对从中派生视图的所有列的 Select 特权。您可以如同表
一样查询视图,并且在以下情况下可如同表一样更新视图,但视图并不是表。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 503
如果您包含可选的 IF NOT EXISTS 关键字,当指定名称的视图已经在当前数据
库中注册过,或者指定名称是当前数据库中表、同义词或序列对象的标识符,则
数据库服务器不会执行任何操作(而不是向应用程序发送异常)。
视图是由视图定义中的 SELECT 语句在每次查询中引用该视图时返回的行和列的
集合组成。
在一些情况下,数据库服务器将用户的 SELECT 语句同定义视图的 SELECT 语
句合并,然后执行组合语句。在其它情况下,如果视图定义的复杂性导致数据库
服务器创建了一个临时表(称为实现的视图)。有关实现的视图的更多信息,请
参阅 GBase 8s 性能指南 。
视图反映了对底层表的更改,但是有两个例外:

如果 SELECT * 规范定义了视图,则视图中只有那些在由 CREATE
VIEW 定义视图时存在于底层表中的列。随后使用 ALTER TABLE 语句
添加到底层表的任何新的列不会出现在该视图中。

如果 GRANT 或 REVOKE 语句修改了视图定义中引用的表上的自由访
问权,则数据库服务器不会将这些存取特权应用到视图上。
要强制将对基础表的访问权限或模式的修改应用于视图,你可以使用 DROP
VIEW 和 CREATE VIEW 语句删除并重建此视图。还可以使用 CREATE VIEW
和 CREATE TRIGGER 语句分别重建 DROP VIEW 语句销毁的任何相关视图或
INSTEAD OF 触发器。
视图继承了从中派生视图的表的列的数据类型。数据库服务器通过表达式的特性
确定虚拟列的数据类型。
SELECT 语句存储于 sysviews 系统目录表中。当您随后在另一个语句中引用视
图的时候,数据库服务器会在执行新语句的同时执行定义 SELECT 语句的操作。
在 DB-Access 中,如果在 CREATE SCHEMA 语句外创建视图,那么在使用 -
ansi 标志或设置 DBANSIWARN 环境变量的情况下,将会收到警告。
下面的语句创建一个基于 person 表的视图。创建类似这样的没有 OF TYPE 子
句的视图时,该视图称为未归类的视图。
CREATE VIEW v1 AS SELECT * FROM person;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 504
已归类的视图
如果您对已命名的 ROW 类型拥有 Usage 特权,或者您是其所有者或 DBA ,则
您可以创建已归类的视图 。如果忽略 OF TYPE 子句,则认为视图中的行是未归
类的,并且缺省为一个未命名的 ROW 类型。
如果类型表,已归类的视图是基于命名的 ROW 类型。视图中的每个列相当于命名
的 ROW 类型中的一个字段。下面的语句创建了一个基于表 person 的已归类的视
图。
CREATE VIEW v2 OF TYPE person_t AS SELECT * FROM person;
要创建已归类的视图,必须包括 OF TYPE 子句。当创建一个已归类的视图时,
紧跟在 OF TYPE 关键字之后指定的命名的 ROW 类型必须已存在。
视图定义中有效的 SELECT 语句的子集
视图定义中支持大多数 SELECT 语句语法,但有一些例外。
您不能在临时表上创建视图。SELECT 语句的 FROM 子集不可以包括临时表的
名称。
CREATE VIEW 语句中由 SELECT 语句引用的表对象可以是永久数据库表、视
图或派生的表。该查询可以引用单独的表对象,或连接两个或多个表对象。这些
表可以是当前数据库中的表,可以是本地数据库服务器的其它数据库中的表,或
者远程服务器实例的数据库中的表。SELECT 语句可以使用用不相关表或相关表
的引用在 FROM 语句中定义派生表。这些派生表定义可以包含 LATERAL 关键
字和横向表和列引用。
如果取消用户对表的 Select 特权,而在某条定义视图(该视图为同一个用户所拥
有)的 SELECT 语句中引用了该表,则此视图会被删除,除非它还包含来自其它
数据库中的表的列。
您无法在驻留在远程数据库中的类型表(包括作为表层次结构一部分的任何表)
上创建视图。
请勿在 Projection 子句的 Select 列表中使用显示标签。Projection 子句中的显示
标签会被解释为列名称。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 505
Hardcoded 值不应在视图定义中使用,但只能在查询视图的后续 SELECT 语句的
WHERE 子句中使用。如果视图中的值不是 hardcoded ,则查询优化器可以始终
排除这些文字值,并且可以在更短的时间内完成查询。但是如果相同的值在视图
中被 hardcoded ,则查询优化器仍然必须评估每个文字值。
CREATE VIEW 中的 SELECT 语句不包括 SKIP 、FIRST 或 LIMIT 关键字或
INTO TEMP 子句。有关 SELECT 语句语法和用法的完整信息,请参阅 SELECT
语句 。
联合视图
一个在其 SELECT 语句中包含 UNION 或 UNION ALL 操作符的视图称为联合
视图。某些限制应用于联合视图:

如果 CREATE VIEW 语句定义了一个联合视图,或者包含
INTERSECT 、MINUS 或 EXCEPT 集合运算符,则您不能在 CREATE
VIEW 语句中指定 WITH CHECK OPTION 关键字。

在独立的 SELECT 语句中应用于 UNION 或 UNION ALL 操作的所有
限制,也应用于联合视图的 SELECT 语句中的 UNION 和 UNION ALL
操作。

同样,在独立的 SELECT 语句中应用于 INTERSECT 、MINUS 或
EXCEPT 集合运算符,也应用于定义视图的组合 SELECT 语句中。
关于这些限制的列表,请参阅 对组合的 SELECT 的限制。关于定义联合视图的
CREATE VIEW 语句的示例,请参阅命名视图列。
指定视图列
在 column 列表中指定的列的数目必须与定义视图的 SELECT 语句所返回的列
数一致。如果不指定列名称,则视图继承底层表的列名称。在下面的示例中,视
图 herostock 拥有的列名称与 SELECT 语句的 Projection 子句中的列名称相
同:
CREATE VIEW herostock AS
SELECT stock_num, description, unit_price, unit, unit_descr
FROM stock WHERE manu_code = 'HRO';
在本版本数据库中,当 SELECT 语句中包含表达式时,创建视图也无需指定列名
称。例如,在以下示例中,SELECT 语句的投影列表包含一个聚集表达式:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 506
CREATE VIEW newview AS
SELECT sum(col1), col2 FROM tab1;
该语句创建视图成功,其视图的字段名称和顺序为 SELECT 语句投影列名和顺
序。
当投影列列名是纯数字列名或纯数字字符串时,用户必须将 DELIMIDENT 环境
变量设置为 y,操作才能成功。
例如,由于下述示例的 SELECT 语句中包含纯数字列名,所以在执行此语句前,
必须将 DELIMIDENT 环境变量设置为 y:
CREATE VIEW newview2 AS
SELECT 1101,sum(col1), col2 FROM tab1;
上述语句创建的视图 newiew2 具有三列:1101、col1 和 col2。
有关 DELIMIDENT 环境变量的详细信息,请参阅 GBase 8s SQL 参考:指南。
当 SELECT 语句包括 UNION 操作符并且 SELECT 语句中相应列的名称不相同
时,创建视图时也可以不指定视图的列名。最终的视图的列名以第一个 SELECT
语句的投影列名为准。例如:
CREATE VIEW newview3 AS
SELECT 1101, ‘tab1’as tabname FROM tab1
UNION
SELECT 1102, ‘tab2’as tabname FROM tab2;
该语句创建的视图 newiew3 具有两列:1101、tabname。
但是,在以下环境中必须指定至少一个列名:

您还必须指定列名称,以防选择的列含有不带表限定符的重复的列名称。
例如,如果 orders.order_num 和 items.order_num 都出现在 SELECT 语
句中,则 CREATE VIEW 语句必须提供两个分开的列名以标记它们:
CREATE VIEW someorders (custnum,ocustnum,newprice) AS
SELECT orders.order_num,items.order_num,
items.total_price*1.5
FROM orders, items
WHERE orders.order_num = items.order_num
AND items.total_price > 100.00;
此处 custnum 和 ocustnum 替换两个相同的列名称。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 507
在 SELECT 语句中使用视图
您可以定义一个其列基于其它视图的视图,但必须遵守对创建视图的限制,在
GBase 8s 数据库设计和实现指南 中对这些限制进行了讨论。
WITH CHECK OPTION 关键字
WITH CHECK OPTION 关键字指示数据库服务器确保通过视图对基础表所作的所
有修改均满足视图的定义。
下面的示例创建一个名为 palo_alto 的视图,它使用城市 Palo Alto 中的顾客
的 customer 表中的所有信息。由于指定了 WITH CHECK OPTIO 关键字,所以数
据库服务器会检查通过 palo_alto 对 customer 表所做的任何修改。
CREATE VIEW palo_alto AS
SELECT * FROM customer WHERE city = 'Palo Alto'
WITH CHECK OPTION
您可以在视图中插入一个不满足视图条件的行(即通过视图不显示的行)。也可
以更新视图的行,使其不再满足视图的统计。例如,如果视图是不使用 WITH
CHECK OPTION 关键字创建的,那么您可以通过城市为 Los Altos 的视图插入一
行,或者通过将城市从 Palo Alto 更改为 Los Altos。
要防止这样的插入和更新,可以在创建视图时添加 WITH CHECK OPTION 关键
字。这些关键字要求数据库服务器测试每个插入的或更新的行以确保它满足由视
图的 WHERE 子句设置的条件。如果行不满足这些条件,则数据库服务器拒绝操
作并以出错形式表明。
即使视图是用 WITH CHECK OPTION 关键字创建的,但您也可以通过视图执行
插入和更新操作以更改不是视图定义一部分的列。如果某列未出现在定义视图的
SELECT 语句的 WHERE 子句中,则该列不是视图定义的一部分。
如果 CREATE VIEW 语句中包含 WITH CHECK OPTION 关键字,其中
UNION 、INTERSECT 、MINUS 或 EXCEPT 集合运算符在视图定义中组合两
个查询,则 CREATE VIEW 语句失败并显示错误 -940 。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 508
通过视图更新
如果视图是构建在一个单独的表上,则在定义该视图的 SELECT 语句不包含任何
以下元素的情况下,则该视图是可更新的:

投影列表中是聚集值的列

投影列表中使用 UNIQUE 或 DISTINCT 关键字

GROUP BY 子句

UNION 操作符

选择计算或文字值的查询
您可以从一个单个表中选择计算值的视图执行 DELETE 操作,但是 INSERT 和
UPDATE 操作对这样的视图无效。
在可更新的视图中,可以通过将基础表中的值插入视图来更新这些值。然而,如
果视图构建在列有派生值的表上,则该列不能够通过该视图更新。但是,可以更
新视图中的其它列。
有关使用 INSTEAD OF 触发器更新基于多个表的视图,或者更新其中包括含有聚
集值或其它计算值的列的视图的信息,另请参阅更新视图。
重要: 您无法通过使用 WITH CHECK OPTION 关键字创建的视图更新或插入远程
表中的行。

gbase_field_count ............................
17

通过JDBC 调用存储过程
该用例分为4 部分,分别实现了如下功能:

callProcedureWhitNoParamByCallableStatement 调用没有参数的存
储过程;

callProcedureWhitINParamByCallableStatement 调用只有IN 参数的
存储过程;

callProcedureWhitOUTParamByCallableStatement 调用只有OUT 参数
的存储过程;

callProcedureWhitInOutParamByCallableStatement 调用有IN、OUT
参数的存储过程。
示例如下:
package com.gbase.jdbc.simple;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

GBase 8a 程序员手册JDBC 篇


- 124 -

南大通用数据技术股份有限公司
import java.sql.Statement;
import java.sql.Types;

public class CallProcByJdbc {

private static final String URL =
"jdbc:gbase://192.168.111.95:5258/test?user=sysdba&password=";
/**
* @param args
*/
public static void main(String[] args) {

//创建存储过程
prepareProc();

CallProcByJdbc callProcByJdbc = new CallProcByJdbc();

//调用没有参数的存储过程
callProcByJdbc.callProcedureWhitNoParamByCallableStateme
nt();

//调用只有IN 参数的存储过程
callProcByJdbc.callProcedureWhitINParamByCallableStateme
nt();

//调用只有OUT 参数的存储过程
callProcByJdbc.callProcedureWhitOUTParamByCallableStatem
ent();

//调用有IN/OUT 参数的存储过程
callProcByJdbc.callProcedureWhitInOutParamByCallableStat
ement();
}

/**
* 通过CallableStatement 调用没有参数的

GBase 8a 程序员手册JDBC 篇
南大通用数据技术股份有限公司

- 125 -
* 存储过程。
*/
public void callProcedureWhitNoParamByCallableStatement() {
Connection conn = null;
CallableStatement cstm = null;
ResultSet rs = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
cstm = conn.prepareCall("call procNoParam()");
rs = cstm.executeQuery();
rs.next();
System.out.println(rs.getString(1));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
}catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
cstm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}

GBase 8a 程序员手册JDBC 篇


- 126 -

南大通用数据技术股份有限公司
}

/**
* 通过CallableStatement 调用IN 参数的
* 存储过程。
*/
public void callProcedureWhitINParamByCallableStatement() {
Connection conn = null;
CallableStatement cstm = null;
ResultSet rs = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
cstm = conn.prepareCall("{call procInParam(?)}");
cstm.setString(1, "InParam Call Works!");
rs = cstm.executeQuery();
rs.next();
System.out.println(rs.getString(1));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
}catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
cstm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
conn.close();

GBase 8a 程序员手册JDBC 篇
南大通用数据技术股份有限公司

- 127 -
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}
}

/**
* 通过CallableStatement 调用OUT 参数的
* 存储过程。
*/
public void callProcedureWhitOUTParamByCallableStatement() {
Connection conn = null;
CallableStatement cstm = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
cstm = conn.prepareCall("call procOutParam(?)");
cstm.setString(1, "@outParam");
cstm.registerOutParameter(1, Types.VARCHAR);
cstm.execute();
System.out.println(cstm.getString(1));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
cstm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {

GBase 8a 程序员手册JDBC 篇


- 128 -

南大通用数据技术股份有限公司
conn = null;
}
}
}

/**
* 通过CallableStatement 调用IN/OUT 参数的
* 存储过程。
*/
public
void
callProcedureWhitInOutParamByCallableStatement()
{
Connection conn = null;
CallableStatement cstm = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
cstm
=
conn.prepareCall("{call
procInOutParam(?,?)}");
cstm.setString(1, "aaaaa");
cstm.setString(2, "@outParam");
cstm.registerOutParameter(2, Types.VARCHAR);
cstm.execute();
System.out.println(cstm.getString(2));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
cstm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
cstm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;

GBase 8a 程序员手册JDBC 篇
南大通用数据技术股份有限公司

- 129 -
}
}

}

/**
* 创建4 个存储过程;
* 1、没有参数
* 2、只有IN 参数
* 3、只有OUT 参数
* 4、有IN、OUT 参数
*/
private static void prepareProc() {
Connection conn = null;
Statement stm = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
stm = conn.createStatement();

stm.executeUpdate("DROP PROCEDURE IF EXISTS
`test`.`procNoParam`");
stm.executeUpdate("DROP PROCEDURE IF EXISTS
`test`.`procInParam`");
stm.executeUpdate("DROP PROCEDURE IF EXISTS
`test`.`procOutParam`");
stm.executeUpdate("DROP PROCEDURE IF EXISTS
`test`.`procInOutParam`");
stm.executeUpdate("CREATE PROCEDURE
`test`.`procNoParam` () begin select 'procNoParamTest works'; end");
stm.executeUpdate("CREATE PROCEDURE
`test`.`procInParam` (IN inParam Varchar(100)) begin select inParam;
end");
stm.executeUpdate("CREATE PROCEDURE
`test`.`procOutParam` (OUT outParam Varchar(100)) begin SET outParam =
'outParamTest works'; end");
stm.executeUpdate("CREATE PROCEDURE
`test`.`procInOutParam` (IN inParam Varchar(100), OUT outParam

GBase 8a 程序员手册JDBC 篇


- 130 -

南大通用数据技术股份有限公司
Varchar(200)) begin set outParam = CONCAT(\'InOutParam \',inParam,\ '
works!\ '); end");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
stm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
stm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}
}
}