GaussDB-向表中插入数据

71 阅读6分钟

GaussDB-向表中插入数据

在创建一个表后,表中并没有数据,在使用这个表之前,需要向表中插入数据。本小节介绍如何使用INSERT命令插入一行或多行数据,及从指定表插入数据。如果有大量数据需要批量导入表中请联系管理员处理。

背景信息

服务端与客户端使用不同的字符集时,两者字符集中单个字符的长度也会不同,客户端输入的字符串会以服务端字符集的格式进行处理,所以产生的最终结果可能会与预期不一致。

操作过程服务端和客户端编码一致服务端和客户端编码不一致
存入和取出过程中没有对字符串进行操作输出预期结果输出预期结果(输入与显示的客户端编码必须一致)。
存入取出过程对字符串有做一定的操作(如字符串函数操作)输出预期结果根据对字符串具体操作可能产生非预期结果。
存入过程中对超长字符串有截断处理输出预期结果字符集中字符编码长度是否一致,如果不一致可能会产生非预期的结果。

上述字符串函数操作和自动截断产生的效果会有叠加效果,例如:在客户端与服务端字符集不一致的场景下,如果既有字符串操作,又有字符串截断,在字符串被处理完以后的情况下继续截断,这样也会产生非预期的效果。详细的示例请参见表2

数据库DBCOMPATIBILITY设为兼容TD(Teradata)模式,且GUC参数td_compatible_truncation设置为on的情况下,才会对超长字符串进行截断。

执行如下命令建立示例中需要使用的表table1、table2。

| ``` gaussdb=# CREATE TABLE table1(id int, a char(6), b varchar(6),c varchar(6)); gaussdb=# CREATE TABLE table2(id int, a char(20), b varchar(20),c varchar(20));

| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

[]()[]()

| 编号 | 服务端字符集    | 客户端字符集 | 是否启用自动截断 | 示例                                                                                                                                                                                                                                                                                                                                                                                                                      | 结果                                                                                                                                                                                                                                          | 说明                                                       |
| :- | :-------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------- |
| 1  | SQL_ASCII | UTF8   | 是        | | ```
gaussdb=# INSERT INTO table1 VALUES(1,reverse('123AAA78'),reverse('123AA78'),reverse('123AA78')); 
``` |
| ---------------------------------------------------------------------------------------------------------- |                                                                                                                                                                                           | | ```
id |a|b|c ----+------+------+------ 1 | 87| 87| 87 
``` |
| ----------------------------------------------------------- |                                                                                                             | 字符串在服务端翻转后,并进行截断,由于服务端和客户端的字符集不一致,字符A在客户端由多个字节表示,结果产生异常。 |
| 2  | SQL_ASCII | UTF8   | 是        | | ```
gaussdb=# INSERT INTO table1 VALUES(2,reverse('123A78'),reverse('123A78'),reverse('123A78')); 
``` |
| ------------------------------------------------------------------------------------------------------ |                                                                                                                                                                                                   | | ```
id |a|b|c ----+------+------+------ 2 | 873| 873| 873 
``` |
| -------------------------------------------------------------- |                                                                                                       | 字符串翻转后,又进行了自动截断,所以产生了非预期的效果。                             |
| 3  | SQL_ASCII | UTF8   | 是        | | ```
gaussdb=# INSERT INTO table1 VALUES(3,'87A123','87A123','87A123'); 
``` |
| --------------------------------------------------------------------------- |                                                                                                                                                                                                                                                         | | ```
id |   a   |   b   |   c ----+-------+-------+-------   3 | 87A1 | 87A1 | 87A1 
``` |
| --------------------------------------------------------------------------------------- |                                                     | 由于字符串类型字段的长度是客户端字符编码长度的整数倍,所以截断后产生结果正常。                  |
| 4  | SQL_ASCII | UTF8   | 否        | | ```
gaussdb=# INSERT INTO table2 VALUES(1,reverse('123AA78'),reverse('123AA78'),reverse('123AA78')); gaussdb=# INSERT INTO table2 VALUES(2,reverse('123A78'),reverse('123A78'),reverse('123A78')); 
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | | ```
id |a|b|c ----+-------------------+--------+-------- 1 | 87 321| 87 321 | 87 321 2 | 87321| 87321| 87321 
``` |
| ----------------------------------------------------------------------------------------------------------------- | | 与示例1类似,多字节字符翻转之后不再表示原来的字符。                               |

#### 操作步骤

向表中插入数据前,意味着表已创建成功。创建表的步骤请参见[创建和管理表](https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/devg-dist/gaussdb-12-0026.html#ZH-CN_TOPIC_0000001865587224)。

-   向表customer_t1中插入一行数据。

    []()[]()数据值是按照这些字段在表中出现的顺序列出的,并且用逗号分隔。通常数据值是文本(常量),但也允许使用标量表达式。

    | ```
    gaussdb=# INSERT INTO customer_t1(c_customer_sk, c_customer_id, c_first_name) VALUES (3769, 'hello', 'Grace'); 
    ``` |
    | ----------------------------------------------------------------------------------------------------------------------- |

    如果用户已经知道表中字段的顺序,也可无需列出表中的字段。例如以下命令与上面的命令效果相同。

    | ```
    gaussdb=# INSERT INTO customer_t1 VALUES (3769, 'hello', 'Grace'); 
    ``` |
    | --------------------------------------------------------------------------- |

    如果用户不知道所有字段的数值,可以忽略其中的一些。如果INSERT语句中,用户没有显示指定目标表的字段名字,那么VALUES子句中待插入的多个值,将按照列号和目标表的字段一一对应,即VALUES子句的第一个值对应目标表的第一列,VALUES子句的第二个值对应目标表的第二列,依次类推,没有VALUES数值对应的列自动填充缺省值或NULL。没有数值的字段将被填充为字段的缺省值。例如:

    | ```
    gaussdb=# INSERT INTO customer_t1 (c_customer_sk, c_first_name) VALUES (3769, 'Grace');  gaussdb=# INSERT INTO customer_t1 VALUES (3769, 'hello'); 
    ``` |
    | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |

    用户也可以对独立的字段或者整个行明确缺省值:

    | ```
    gaussdb=# INSERT INTO customer_t1 (c_customer_sk, c_customer_id, c_first_name) VALUES (3769, 'hello', DEFAULT);  gaussdb=# INSERT INTO customer_t1 DEFAULT VALUES; 
    ``` |
    | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

-   如果需要在表中插入多行,请执行如下命令:

    | ```
    gaussdb=# INSERT INTO customer_t1 (c_customer_sk, c_customer_id, c_first_name) VALUES      (6885, 'maps', 'Joes'),     (4321, 'tpcds', 'Lily'),     (9527, 'world', 'James'); 
    ``` |
    | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

    如果需要向表中插入多条数据,除此命令外,也可以多次执行插入一行数据命令实现。但是建议使用此命令以提升效率。

-   如果从指定表插入数据到当前表,例如在数据库中创建了一个表customer_t1的备份表customer_t2,现在需要将表customer_t1中的数据插入到表customer_t2中,则可以执行如下命令:

    | ```
    gaussdb=# CREATE TABLE customer_t2 (     c_customer_sk             integer,     c_customer_id             char(5),     c_first_name              char(6),     c_last_name               char(8) );  gaussdb=# INSERT INTO customer_t2 SELECT * FROM customer_t1; 
    ``` |
    | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

    ![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/610e71221ea746cab5b94659c1f23371~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgamVycnl3YW5nMTk4Mw==:q75.awebp?rk3s=f64ab15b&x-expires=1772592363&x-signature=mMA9wLusSxyVzdT6F1Uue226vho%3D)

    从指定表插入数据到当前表时,若指定表与当前表对应的字段数据类型之间不存在隐式转换,则这两种数据类型必须相同。

-   使用不带AS的表别名向表中插入数据。

    | ```
    gaussdb=#  CREATE TABLE table_name(a int,b text,c timestamp,d float); gaussdb=#  INSERT INTO table_name alias_name VALUES(1,'ha','1997-01-01 10:00:00'::timestamp,1.234); gaussdb=#  INSERT INTO table_name alias_name(b,c,d) VALUES('ha','1997-01-01 10:00:00'::timestamp,1.234); 
    ``` |
    | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

    ![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/935dc4d0cfdd4303a2bd4b239bae8d71~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgamVycnl3YW5nMTk4Mw==:q75.awebp?rk3s=f64ab15b&x-expires=1772592363&x-signature=aaX2Y5%2BMrgupUS1NJeqX2CbnnMo%3D)

    1.  INSERT不带AS的表别名不能为关键字(如SELECT、VALUE)或者表达式,别名要求符合标识符命名规则。
    1.  INSERT不带AS的表别名不支持INSERT INTO table_name alias_name(alias_name.col1,...,alias_name.coln) VALUES(xxx)格式。
    1.  INSERT的分区表不带AS的表别名不支持指定分区插入操作。

-   删除备份表

    | ```
    gaussdb=# DROP TABLE customer_t2 CASCADE; 
    ``` |
    | -------------------------------------------------- |

    ![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7027cb510b2a4f9ca3ed7b3be7642cf1~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgamVycnl3YW5nMTk4Mw==:q75.awebp?rk3s=f64ab15b&x-expires=1772592363&x-signature=WQUEvPbqB5LYMiwIBT7uAabYv1M%3D)

    在删除表的时候,若当前需删除的表与其他表有依赖关系,需先删除关联的表,然后再删除当前表。

更多详情请参考GaussDB 文档中心:<https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/productdesc/qlh_03_0001.html>