对象名称解析

完全限定的架构对象(表、视图、文件格式等)的形式如下:

<database_name>.<schema_name>.<object_name>

但由于编写起来可能相当繁琐,因此允许用户按照从左到右的顺序忽略限定条件。本主题介绍如何解析架构对象名称。

忽略数据库时的解决方法

(''<schema_name>.<object_name>'')

对象名称将使用当前数据库进行扩充。启动会话时,当前数据库将设置为默认值,具体取决于账户设置。之后可使用 USE DATABASE 命令进行更改。CREATE DATABASE 命令还会将当前数据库隐式更改为新创建的数据库。CURRENT_DATABASE 函数返回当前数据库的名称。

例如:

SELECT CURRENT_DATABASE();
Copy
+--------------------+
| CURRENT_DATABASE() |
+--------------------+
| TESTDB             |
+--------------------+
CREATE DATABASE db1;
Copy
+------------------------------------+
|               status               |
+------------------------------------+
| Database DB1 successfully created. |
+------------------------------------+
SELECT CURRENT_DATABASE();
Copy
+--------------------+
| CURRENT_DATABASE() |
+--------------------+
| DB1                |
+--------------------+
USE DATABASE testdb;
Copy
+----------------------------------+
|              status              |
+----------------------------------+
| Statement executed successfully. |
+----------------------------------+
SELECT CURRENT_DATABASE();
Copy
+--------------------+
| CURRENT_DATABASE() |
+--------------------+
| TESTDB             |
+--------------------+

忽略架构时的解决方法(双点表示法)

(''<database_name>..<object_name>'')

这两个点表示未指定架构名称。始终引用 PUBLIC 默认架构。

请注意,提供此符号格式的主要目的是兼容其他系统(如 Microsoft SQL Server 和 IBM Netezza)。不建议在新查询中使用这种表示法。

不合格的对象

不合格的对象(单个标识符)以两种不同的方式解析,具体取决于它们是出现在 DDL 或 DML 语句中,还是出现在查询中。

DDL 和 DML 语句

在 DDL 和 DML 语句中,不合格的对象使用当前数据库和架构扩充。当前架构的维护方式类似于当前数据库。当前架构始终属于当前数据库。

启动会话时,将根据连接的设置初始化当前架构。更改当前数据库时,当前架构默认为一个内部属性的值(通常设置为 PUBLIC)。可以使用 USE SCHEMA 命令更改当前架构(但始终在当前数据库中)。也可通过 CREATE SCHEMA 命令隐式对此进行更改。CURRENT_SCHEMA 函数返回当前架构的名称。

例如:

SELECT CURRENT_SCHEMA();
Copy
+------------------+
| CURRENT_SCHEMA() |
+------------------+
| TESTSCHEMA       |
+------------------+
CREATE DATABASE db1;
Copy
+------------------------------------+
|               status               |
+------------------------------------+
| Database DB1 successfully created. |
+------------------------------------+
SELECT CURRENT_SCHEMA();
Copy
+------------------+
| CURRENT_SCHEMA() |
+------------------+
| PUBLIC           |
+------------------+
CREATE SCHEMA sch1;
Copy
+-----------------------------------+
|              status               |
+-----------------------------------+
| Schema SCH1 successfully created. |
+-----------------------------------+
SELECT current_schema();
Copy
+------------------+
| CURRENT_SCHEMA() |
|------------------+
| SCH1             |
|------------------+

查询中的名称解析

在查询中,不合格的对象名称通过搜索路径进行解析。

搜索路径通常包含当前架构,但也可包含其他架构。

搜索路径存储在会话级参数 SEARCH_PATH 中。与任何其他参数类似,可使用 ALTER SESSION 命令更改此参数。

搜索路径的值是使用逗号分隔的标识符列表。该列表可以包含完全限定或部分限定的架构名称。每个架构名称都可以是 加双引号的标识符

搜索路径还可以包含以下伪变量:

$current

指定当前架构(请参见上文)。

$public

指定当前数据库的公共架构。公共架构的名称由 Snowflake 维护的内部属性确定,该属性通常设置为 PUBLIC (针对为每个数据库自动创建的 PUBLIC 架构)。

这些伪变量的名称不区分大小写。

搜索路径的默认值为 $current, $public

如果用户为搜索路径指定了新值,则验证新值。新值中指定的每个架构标识符都必须对应于一个现有架构。(具体而言,每个非限定架构都必须对应于当前数据库中的一个现有架构)。否则将引发错误,search_path 将保留其先前的值。但伪变量可以自由使用。例如,即使当前数据库没有公共架构,也可使用 $public

每次使用 SEARCH_PATH 参数时,系统都会重新解析该参数的值。因此,更改当前架构会更改 $current 的含义,更改当前数据库会更改 $public 的含义以及任何非限定模式的含义。

如果删除了搜索路径中的架构,或更改了当前数据库,并且新数据库中不存在搜索路径中的某些非限定架构,则不会引发错误。

SEARCH_PATH 未在 视图UDFs 内使用。视图或 UDF 定义中的所有不合格的对象均 在视图或 UDF 的架构中解析。

可以通过 SHOW PARAMETERS 命令来检查搜索路径的字面量值。

若要查看将为查询中的不合格的对象搜索的架构,请使用 CURRENT_SCHEMAS 函数。该函数的返回值会包含搜索路径中的一系列完全限定架构,架构之间使用逗号分隔。

例如:

SELECT CURRENT_SCHEMAS();
Copy
+-------------------+
| CURRENT_SCHEMAS() |
+-------------------+
| []                |
+-------------------+
USE DATABASE mytestdb;

SELECT current_schemas();
Copy
+---------------------+
| CURRENT_SCHEMAS()   |
+---------------------+
| ["MYTESTDB.PUBLIC"] |
+---------------------+
CREATE SCHEMA private;

SELECT current_schemas();
Copy
+-----------------------------------------+
| CURRENT_SCHEMAS()                       |
+-----------------------------------------+
| ["MYTESTDB.PRIVATE", "MYTESTDB.PUBLIC"] |
+-----------------------------------------+

伪变量将扩展到其当前值,非限定架构将变为完全限定形式,而不存在或不可见的架构将被忽略。

SHOW PARAMETERS LIKE 'search_path';
Copy
+-------------+--------------------+--------------------+------------------------------------------------+
| key         | value              | default            | description                                    |
+-------------+--------------------+--------------------+------------------------------------------------+
| SEARCH_PATH | $current, $public, | $current, $public, | Search path for unqualified object references. |
+-------------+--------------------+--------------------+------------------------------------------------+
SELECT current_schemas();
Copy
+---------------------------------------------------------------------------+
|                       CURRENT_SCHEMAS()                                   |
+---------------------------------------------------------------------------+
| [XY12345.TESTDB.TESTSCHEMA, XY12345.TESTDB.PUBLIC, SAMPLES.COMMON.PUBLIC] |
+---------------------------------------------------------------------------+
CREATE DATABASE db1;
Copy
+------------------------------------+
|               status               |
+------------------------------------+
| Database DB1 successfully created. |
+------------------------------------+
USE SCHEMA public;
Copy
+----------------------------------+
|              status              |
+----------------------------------+
| Statement executed successfully. |
+----------------------------------+
SELECT current_schemas();
Copy
+---------------------------------------------+
|                CURRENT_SCHEMAS()            |
+---------------------------------------------+
| [XY12345.DB1.PUBLIC, SAMPLES.COMMON.PUBLIC] |
+---------------------------------------------+
ALTER SESSION SET search_path='$current, $public, testdb.public';
Copy
+----------------------------------+
|              status              |
+----------------------------------+
| Statement executed successfully. |
+----------------------------------+
SHOW PARAMETERS LIKE 'search_path';
Copy
+-------------+----------------------------------+--------------------+------------------------------------------------+
| key         | value                            | default            | description                                    |
+-------------+----------------------------------+--------------------+------------------------------------------------+
| SEARCH_PATH | $current, $public, testdb.public | $current, $public, | Search path for unqualified object references. |
+-------------+----------------------------------+--------------------+------------------------------------------------+
SELECT current_schemas();
Copy
+---------------------------------------------+
|                CURRENT_SCHEMAS()            |
+---------------------------------------------+
| [XY12345.DB1.PUBLIC, XY12345.TESTDB.PUBLIC] |
+---------------------------------------------+

当列名与别名冲突时的优先级

您可以创建包含与列名相同的别名的查询(但通常不建议这样做):

SELECT x, some_expression AS x
  FROM ...
Copy

如果子句中包含的名称同时匹配列名和别名,则该子句将使用列名。以下示例通过 GROUP BY 子句演示了此行为:

创建表并插入行:

CREATE TABLE employees (salary FLOAT, state VARCHAR, employment_state VARCHAR);
INSERT INTO employees (salary, state, employment_state) VALUES
  (60000, 'California', 'Active'),
  (70000, 'California', 'On leave'),
  (80000, 'Oregon', 'Active');
Copy

以下查询返回在职员工的薪资总和以及休假员工的薪资总和:

SELECT SUM(salary), ANY_VALUE(employment_state)
  FROM employees
  GROUP BY employment_state;
Copy
+-------------+-----------------------------+
| SUM(SALARY) | ANY_VALUE(EMPLOYMENT_STATE) |
|-------------+-----------------------------|
|      140000 | Active                      |
|       70000 | On leave                    |
+-------------+-----------------------------+

接下来的查询使用了别名 state,该别名与查询表中的某一列名相同。在 GROUP BY 子句中使用 state 时,Snowflake 会将其解释为对列名的引用,而非别名。因此,此查询返回的是加利福尼亚州和俄勒冈州员工的薪资总和,但显示的却是 employment_state 信息(即 Active),而不是具体的州或省份名称。

SELECT SUM(salary), ANY_VALUE(employment_state) AS state
  FROM employees
  GROUP BY state;
Copy
+-------------+--------+
| SUM(SALARY) | STATE  |
|-------------+--------|
|      130000 | Active |
|       80000 | Active |
+-------------+--------+
语言: 中文