云服务器内容精选
-
PostgreSQL To GaussDB 数据类型转换说明 源数据库数据类型 转换后数据类型 相关的转换配置 SMALLINT SMALLINT - INTEGER INTEGER - BIGINT BIGINT - INTEGER INTEGER - REAL REAL - DOUBLE PRECISION DOUBLE PRECISION - NUMERIC NUMERIC - CHARACTER VARYING CHARACTER VARYING 字符数据类型转换 选择配置项的值为“扩展字符数据类型char/varchar长度。”,可与DRS转换后在GaussDB 存储等价。 CHARACTER CHARACTER 字符数据类型转换 选择配置项的值为“扩展字符数据类型char/varchar长度。”,可与DRS转换后在GaussDB 存储等价。 BIT BIT - BIT VARYING BIT VARYING - BOOLEAN BOOLEAN - BYTEA BYTEA - TEXT TEXT - TIME WITHOUT TIME ZONE TIME WITHOUT TIME ZONE - TIME WITH TIME ZONE TIME WITH TIME ZONE - TIMESTAMP WITHOUT TIME ZONE TIMESTAMP WITHOUT TIME ZONE - TIMESTAMP WITH TIME ZONE TIMESTAMP WITH TIME ZONE - INTERVAL INTERVAL - CIDR CIDR - PATH PATH - BOX BOX - LSEG LSEG - MACADDR MACADDR - POINT POINT - POLYGON POLYGON - INET INET - TSQUERY TSQUERY - TSVECTOR TSVECTOR - UUID UUID - JSON JSON - JSONB JSONB - 配置项说明可参考PostgreSQL To GaussDB配置项使用说明。 父主题: 数据类型转换说明
-
操作符类型解析 从系统表PG_OPERATOR中选出要考虑的操作符。如果可以找到一个参数类型以及参数个数都一致的操作符,那么这个操作符就是最终使用的操作符。如果找到了多个备选的操作符,那么将从中选择一个最合适的。 寻找最优匹配。 丢弃输入类型不匹配以及无法隐式转换成匹配的候选操作符。unknown文本在这种情况下可以转换成任何类型。如果只剩下一个候选操作符,则使用,否则继续下一步。 查看所有候选操作符,并保留输入类型最匹配的操作符。此时,域被看作和其基本类型相同。如果没有完全匹配的操作符,则保留所有候选。如果只剩下一个候选操作符,则使用,否则继续下一步。 查看所有候选操作符,保留需要类型转换时接受(属于输入数据类型的类型范畴的)首选类型位置最多的操作符。如果没有接受首选类型的操作符,则保留所有候选。如果只剩下一个候选操作符,则使用,否则继续下一步。 如果有任何输入参数是unknown类型,请检查其余候选操作符对应参数位置的类型范畴。在每一个能够接受string类型范畴的位置使用string类型(这种偏向字符串的做法合理,因为unknown文本跟字符串相似)。另外,如果所有剩下的候选操作符都接受相同的类型范畴,则选择该类型范畴,否则会报错(因为在没有更多线索的条件下无法作出正确的选择)。现在丢弃不接受选定类型范畴的候选操作符。此外,如果有任意候选操作符接受该范畴中的首选类型,则丢弃该参数接受非首选类型的候选操作符。如果没有一个操作符能被保留,则保留所有候选。如果只剩下一个候选操作符,则使用,否则继续下一步。 如果同时有unknown和已知参数,并且所有已知参数都是相同的类型,那么假设unknown参数也属于该类型,并检查哪些候选操作符在unknown参数位置接受该类型。如果只有一个操作符符合,则使用。否则,报错。
-
示例 character存储类型转换。对一个目标列定义为character(20)的语句,下面的语句显示存储值的长度正确: 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE x1 ( customer_sk integer, customer_id char(20), first_name char(6), last_name char(8) ) with (orientation = column,compression=middle) distribute by hash (last_name); INSERT INTO x1(customer_sk, customer_id, first_name) VALUES (3769, 'abcdef', 'Grace'); SELECT customer_id, octet_length(customer_id) FROM x1; 1 DROP TABLE x1; 这里真正发生的事情是两个unknown文本缺省解析成text,这样就允许||操作符解析成text连接。然后操作符的text结果转换成bpchar("空白填充的字符型", character类型内部名称)以匹配目标字段类型。不过,从text到bpchar的转换是二进制兼容的,这样的转换是隐含的并且实际上不做任何函数调用。最后,在系统表里找到长度转换函数bpchar(bpchar, integer, boolean) 并且应用于该操作符的结果和存储的字段长。这个类型相关的函数执行所需的长度检查和额外的空白填充。
-
值存储数据类型解析 查找与目标字段准确的匹配。 试着将表达式直接转换成目标类型。如果已知这两种类型之间存在一个已登记的转换函数,那么直接调用该转换函数即可。如果表达式是一个未知类型文本,该文本字符串的内容将交给目标类型的输入转换过程。 检查一下看目标类型是否有长度转换。长度转换是一个从某类型到自身的转换。如果在pg_cast表里面找到一个,那么在存储到目标字段之前先在表达式上应用。这样的转换函数总是接受一个额外的类型为integer的参数,它接收目标字段的atttypmod值(实际上是其声明长度,atttypmod的解释随不同的数据类型而不同),并且它可能接受一个boolean类型的第三个参数,表示转换是显式的还是隐式的。转换函数负责施加那些长度相关的语义,比如长度检查或者截断。
-
示例 示例1:Union中的待定类型解析。这里,unknown类型文本'b'将被解析成text类型。 1 2 3 4 5 6 gaussdb=# SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows) 示例2:简单Union中的类型解析。文本1.2的类型为numeric,而且integer类型的1可以隐含地转换为numeric,因此使用这个类型。 1 2 3 4 5 6 gaussdb=# SELECT 1.2 AS "numeric" UNION SELECT 1; numeric --------- 1 1.2 (2 rows) 示例3:转置Union中的类型解析。这里,因为类型real不能被隐含转换成integer,但是integer可以隐含转换成real,那么联合的结果类型将是real。 1 2 3 4 5 6 gaussdb=# SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); real ------ 1 2.2 (2 rows) 示例4:TD模式下,coalesce参数输入int和varchar类型,那么解析成varchar类型。A模式下会报错。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 --在A模式下,创建A兼容模式的数据库a_1。 gaussdb=# CREATE DATABASE a_1 dbcompatibility = 'A'; --切换数据库为a_1。 gaussdb=# \c a_1 --创建表t1。 a_1=# CREATE TABLE t1(a int, b varchar(10)); --查看coalesce参数输入int和varchar类型的查询语句的执行计划。 a_1=# EXPLAIN SELECT coalesce(a, b) FROM t1; ERROR: COALESCE types integer and character varying cannot be matched LINE 1: EXPLAIN SELECT coalesce(a, b) FROM t1; ^ CONTEXT: referenced column: coalesce --删除表。 a_1=# DROP TABLE t1; --切换数据库为testdb。 a_1=# \c testdb --在TD模式下,创建TD兼容模式的数据库td_1。 gaussdb=# CREATE DATABASE td_1 dbcompatibility = 'C'; --切换数据库为td_1。 gaussdb=# \c td_1 --创建表t2。 td_1=# CREATE TABLE t2(a int, b varchar(10)); --查看coalesce参数输入int和varchar类型的查询语句的执行计划。 td_1=# EXPLAIN VERBOSE select coalesce(a, b) from t2; QUERY PLAN --------------------------------------------------------------------------------------- Data Node Scan (cost=0.00..0.00 rows=0 width=0) Output: (COALESCE((t2.a)::character varying, t2.b)) Node/s: All dbnodes Remote query: SELECT COALESCE(a::character varying, b) AS "coalesce" FROM public.t2 (4 rows) --删除表。 td_1=# DROP TABLE t2; --切换数据库为testdb。 td_1=# \c testdb --删除A和TD模式的数据库。 gaussdb=# DROP DATABASE a_1; gaussdb=# DROP DATABASE td_1; 示例5:ORA模式下,将整个表达式最终的返回值类型定为result1的数据类型,或者与result1同类型范畴的更高精度的数据类型。 --在ORA模式下,创建ORA兼容模式的数据库ora_1。 gaussdb=# CREATE DATABASE ora_1 dbcompatibility = 'A'; --切换数据库为ora_1。 gaussdb=# \c ora_1 --开启Decode兼容性参数。 set sql_beta_feature='a_style_coerce'; --创建表t1。 ora_1=# CREATE TABLE t1(c_int int, c_float8 float8, c_char char(10), c_text text, c_date date); --插入数据。 ora_1=# INSERT INTO t1 VALUES(1, 2, '3', '4', date '12-10-2010'); --result1类型为char,defresult类型为text,text精度更高,返回值的类型由char更新为text。 ora_1=# SELECT decode(1, 2, c_char, c_text) AS result, pg_typeof(result) FROM t1; result | pg_typeof --------+----------- 4 | text (1 row) --result1类型为int,属于数值类型范畴,返回值的类型置为numeric。 ora_1=# SELECT decode(1, 2, c_int, c_float8) AS result, pg_typeof(result) FROM t1; result | pg_typeof --------+----------- 2 | numeric (1 row) --不存在defresult数据类型向result1数据类型之间的隐式转换,报错处理。 ora_1=# SELECT decode(1, 2, c_int, c_date) FROM t1; ERROR: CASE types integer and timestamp without time zone cannot be matched LINE 1: SELECT decode(1, 2, c_int, c_date) FROM t1; ^ CONTEXT: referenced column: c_date --关闭Decode兼容性参数。 set sql_beta_feature='none'; --删除表。 ora_1=# DROP TABLE t1; DROP TABLE --切换数据库为testdb。 ora_1=# \c testdb --删除ORA模式的数据库。 gaussdb=# DROP DATABASE ora_1; DROP DATABASE
-
对于case和coalesce,在TD兼容模式下的处理 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。 如果所有输入都是unknown类型则解析成text类型。 如果输入字符串(包括unknown,unknown当text来处理)和数字类型,那么解析成字符串类型,如果是其他不同的类型范畴,则报错。 如果输入类型是同一个类型范畴,则选择该类型的优先级较高的类型。 把所有输入转换为所选的类型。如果从给定的输入到所选的类型没有隐式转换则失败。
-
UNION,CASE和相关构造解析 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。 如果所有输入都是unknown类型则解析成text类型(字符串类型范畴的首选类型)。否则,忽略unknown输入。 如果输入不属于同一个类型范畴,则失败。(unknown类型除外) 如果输入类型是同一个类型范畴,则选择该类型范畴的首选类型。(例外:union操作会选择第一个分支的类型作为所选类型。) 系统表pg_type中typcategory表示数据类型范畴,typispreferred表示是否是typcategory分类中的首选类型。 把所有输入转换为所选的类型(对于字符串保持原有长度)。如果从给定的输入到所选的类型没有隐式转换则失败。 若输入中含json、txid_snapshot、sys_refcursor或几何类型,则不能进行union。
-
操作符类型解析 从系统表pg_operator中选出要考虑的操作符。如果可以找到一个参数类型以及参数个数都一致的操作符,那么这个操作符就是最终使用的操作符。如果找到了多个备选的操作符,将从中选择一个最合适的。 寻找最优匹配。 抛弃那些输入类型不匹配并且也不能隐式转换成匹配的候选操作符。unknown文本在这种情况下可以转换成任何东西。如果只剩下一个候选项,则用之,否则继续下一步。 遍历所有候选操作符,保留那些输入类型匹配最准确的。此时,域类型看做和域类型的基本类型相同。如果没有一个操作符能被保留,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 遍历所有候选操作符,保留那些需要类型转换时接受(属于输入数据类型的类型范畴的)首选类型位置最多的操作符。如果没有接受首选类型的操作符,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 如果有任何输入参数是unknown类型,检查剩余的候选操作符对应参数位置的类型范畴。在每一个能够接受字符串类型范畴的位置使用string类型(这种对字符串的偏爱是合适的,因为unknown文本确实像字符串)。如果所有剩下的候选操作符都接受相同的类型范畴,则选择该类型范畴,否则抛出一个错误(因为在没有更多线索的条件下无法作出正确的选择)。现在抛弃不接受选定的类型范畴的候选操作符,如果任意候选操作符在某个给定的参数位置接受一个首选类型,则抛弃那些在该参数位置接受非首选类型的候选操作符。如果没有一个操作符能被保留,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 如果同时有unknown和已知类型的参数,并且所有已知类型的参数都是相同的类型,那么假设unknown参数也是那种类型,并检查哪一个候选操作符在unknown参数位置接受该类型。如果只有一个操作符符合,那么使用它。否则产生一个错误。 在找到一个操作符后,如果输入的参数类型和操作符的参数类型不一致,可能会发生隐式类型转换,转换后可能发生不可预知的行为。如果隐式转换后行为有问题,可以通过显式类型转换规避此问题。例如,定长类型bpchar转换为变长类型text后,会消除字符串行尾空格,如果再和其它字符串比较时可能会发生错误行为。
-
操作符类型解析 从系统表pg_operator中选出要考虑的操作符。如果可以找到一个参数类型以及参数个数都一致的操作符,那么这个操作符就是最终使用的操作符。如果找到了多个备选的操作符,将从中选择一个最合适的。 寻找最优匹配。 抛弃那些输入类型不匹配并且也不能隐式转换成匹配的候选操作符。unknown文本在这种情况下可以转换成任何东西。如果只剩下一个候选项,则用之,否则继续下一步。 遍历所有候选操作符,保留那些输入类型匹配最准确的。域类型看做和域类型的基本类型相同。如果没有一个操作符能被保留,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 遍历所有候选操作符,保留那些需要类型转换时接受(属于输入数据类型的类型范畴的)首选类型位置最多的操作符。如果没有接受首选类型的操作符,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 如果有任何输入参数是unknown类型,检查剩余的候选操作符对应参数位置的类型范畴。在每一个能够接受字符串类型范畴的位置使用string类型(这种对字符串的偏爱是合适的,因为unknown文本确实像字符串)。如果所有剩下的候选操作符都接受相同的类型范畴,则选择该类型范畴,否则抛出一个错误(因为在没有更多线索的条件下无法作出正确的选择)。现在抛弃不接受选定的类型范畴的候选操作符,如果任意候选操作符在某个给定的参数位置接受一个首选类型,则抛弃那些在该参数位置接受非首选类型的候选操作符。如果没有一个操作符能被保留,则保留所有候选。如果只剩下一个候选项,则用之,否则继续下一步。 如果同时有unknown和已知类型的参数,并且所有已知类型的参数都是相同的类型,那么假设unknown参数也是那种类型,并检查哪一个候选操作符在unknown参数位置接受该类型。如果只有一个操作符符合,那么使用它。否则产生一个错误。 在找到一个操作符后,如果输入的参数类型和操作符的参数类型不一致,可能会发生隐式类型转换,转换后可能发生不可预知的行为。如果隐式转换后行为有问题,可以通过显式类型转换规避此问题。例如,定长类型bpchar转换为变长类型text后,会消除字符串行尾空格,如果再和其它字符串比较时可能会发生错误行为。
-
UNION,CASE和相关构造解析 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。 如果所有输入都是unknown类型则解析成text类型(字符串类型范畴的首选类型)。否则,忽略unknown输入。 如果输入不属于同一个类型范畴,则失败。(unknown类型除外) 如果输入类型是同一个类型范畴,则选择该类型范畴的首选类型。(例外:union操作会选择第一个分支的类型作为所选类型。) 系统表pg_type中typcategory表示数据类型范畴, typispreferred表示是否是typcategory分类中的首选类型。 把所有输入转换为所选的类型(对于字符串保持原有长度)。如果从给定的输入到所选的类型没有隐式转换则失败。 若输入中含json、txid_snapshot、sys_refcursor或几何类型,则不能进行union。
-
对于case和coalesce,在TD兼容模式下的处理 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。 如果所有输入都是unknown类型则解析成text类型。 如果输入字符串(包括unknown,unknown当text来处理)和数字类型,那么解析成字符串类型,如果是其他不同的类型范畴,则报错。 如果输入类型是同一个类型范畴,则选择该类型的优先级较高的类型。 把所有输入转换为所选的类型。如果从给定的输入到所选的类型没有隐式转换则失败。
-
示例 示例1:Union中的待定类型解析。unknown类型文本'b'将被解析成text类型。 1 2 3 4 5 6 gaussdb=# SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows) 示例2:简单Union中的类型解析。文本1.2的类型为numeric,而且integer类型的1可以隐含地转换为numeric,因此使用这个类型。 1 2 3 4 5 6 gaussdb=# SELECT 1.2 AS "numeric" UNION SELECT 1; numeric --------- 1 1.2 (2 rows) 示例3:转置Union中的类型解析。类型real不能被隐含转换成integer,但是integer可以隐含转换成real,那么联合的结果类型将是real。 1 2 3 4 5 6 gaussdb=# SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); real ------ 1 2.2 (2 rows) 示例4:TD模式下,coalesce参数输入int和varchar类型,那么解析成varchar类型。ORA模式下会报错。 --在oracle模式下,创建oracle兼容模式的数据库oracle_1。 gaussdb=# CREATE DATABASE oracle_1 dbcompatibility = 'ORA'; --切换数据库为oracle_1。 gaussdb=# \c oracle_1 --创建表t1。 oracle_1=# CREATE TABLE t1(a int, b varchar(10)); --查看coalesce参数输入int和varchar类型的查询语句的执行计划。 a_1=# EXPLAIN SELECT coalesce(a, b) FROM t1; ERROR: COALESCE types integer and character varying cannot be matched LINE 1: EXPLAIN SELECT coalesce(a, b) FROM t1; ^ CONTEXT: referenced column: coalesce --删除表。 oracle_1=# DROP TABLE t1; --切换数据库为testdb。 oracle_1=# \c testdb --在TD模式下,创建TD兼容模式的数据库td_1。 gaussdb=# CREATE DATABASE td_1 dbcompatibility = 'TD'; --切换数据库为td_1。 gaussdb=# \c td_1 --创建表t2。 td_1=# CREATE TABLE t2(a int, b varchar(10)); --查看coalesce参数输入int和varchar类型的查询语句的执行计划。 td_1=# EXPLAIN VERBOSE select coalesce(a, b) from t2; QUERY PLAN --------------------------------------------------------------------------------------- Data Node Scan (cost=0.00..0.00 rows=0 width=0) Output: (COALESCE((t2.a)::character varying, t2.b)) Node/s: All datanodes Remote query: SELECT COALESCE(a::character varying, b) AS "coalesce" FROM public.t2 (4 rows) --删除表。 td_1=# DROP TABLE t2; --切换数据库为testdb。 td_1=# \c testdb --删除Oracle和TD模式的数据库。 gaussdb=# DROP DATABASE oracle_1; gaussdb=# DROP DATABASE td_1; 示例5:ORA模式下,将整个表达式最终的返回值类型定为result1的数据类型,或者与result1同类型范畴的更高精度的数据类型。 --在ORA模式下,创建ORA兼容模式的数据库ora_1。 gaussdb=# CREATE DATABASE ora_1 dbcompatibility = 'A'; --切换数据库为ora_1。 gaussdb=# \c ora_1 --开启Decode兼容性参数。 set sql_beta_feature='a_style_coerce'; --创建表t1。 ora_1=# CREATE TABLE t1(c_int int, c_float8 float8, c_char char(10), c_text text, c_date date); --插入数据。 ora_1=# INSERT INTO t1 VALUES(1, 2, '3', '4', date '12-10-2010'); --result1类型为char,defresult类型为text,text精度更高,返回值的类型由char更新为text。 ora_1=# SELECT decode(1, 2, c_char, c_text) AS result, pg_typeof(result) FROM t1; result | pg_typeof --------+----------- 4 | text (1 row) --result1类型为int,属于数值类型范畴,返回值的类型置为numeric。 ora_1=# SELECT decode(1, 2, c_int, c_float8) AS result, pg_typeof(result) FROM t1; result | pg_typeof --------+----------- 2 | numeric (1 row) --不存在defresult数据类型向result1数据类型之间的隐式转换,报错处理。 ora_1=# SELECT decode(1, 2, c_int, c_date) FROM t1; ERROR: CASE types integer and timestamp without time zone cannot be matched LINE 1: SELECT decode(1, 2, c_int, c_date) FROM t1; ^ CONTEXT: referenced column: c_date --关闭Decode兼容性参数。 set sql_beta_feature='none'; --删除表。 ora_1=# DROP TABLE t1; DROP TABLE --切换数据库为testdb。 ora_1=# \c testdb --删除ORA模式的数据库。 gaussdb=# DROP DATABASE ora_1; DROP DATABASE
-
值存储数据类型解析 查找与目标字段准确的匹配。 试着将表达式直接转换成目标类型。如果已知这两种类型之间存在一个已注册的转换函数,那么直接调用该转换函数即可。如果表达式是一个未知类型文本,该文本字符串的内容将交给目标类型的输入转换过程。 检查目标类型是否有长度转换。长度转换是一个从某类型到自身的转换。如果在pg_cast表里面找到一个,那么在存储到目标字段之前先在表达式上应用。这样的转换函数总是接受一个额外的类型为integer的参数,它接收目标字段的atttypmod值(实际上是其声明长度,atttypmod的解释随不同的数据类型而不同),并且它可能接受一个Boolean类型的第三个参数,表示转换是显式的还是隐式的。转换函数负责施加那些长度相关的语义,比如长度检查或者截断。
-
示例 character存储类型转换。对一个目标列定义为character(20)的语句,下面的语句显示存储值的长度正确: 1 2 3 4 5 6 7 8 9 10 11 12 gaussdb=# CREATE TABLE tpcds.value_storage_t1 ( VS_COL1 CHARACTER(20) )DISTRIBUTE BY HASH (VS_COL1); gaussdb=# INSERT INTO tpcds.value_storage_t1 VALUES('abcdef'); gaussdb=# SELECT VS_COL1, octet_length(VS_COL1) FROM tpcds.value_storage_t1; vs_col1 | octet_length ----------------------+-------------- abcdef | 20 (1 row) ) gaussdb=# DROP TABLE tpcds.value_storage_t1; 两个unknown文本缺省解析成text,这样就允许||操作符解析成text连接。然后操作符的text结果转换成bpchar("空白填充的字符型", character类型内部名称)以匹配目标字段类型。从text到bpchar的转换是二进制兼容的,这样的转换是隐含的并且实际上不做任何函数调用。在系统表里找到长度转换函数bpchar(bpchar, integer, Boolean) 并且应用于该操作符的结果和存储的字段长。这个类型相关的函数执行所需的长度检查和额外的空白填充。
-
值存储数据类型解析 查找与目标字段准确的匹配。 试着将表达式直接转换成目标类型。如果已知这两种类型之间存在一个已注册的转换函数,那么直接调用该转换函数即可。如果表达式是一个未知类型文本,该文本字符串的内容将交给目标类型的输入转换过程。 检查目标类型是否有长度转换。长度转换是一个从某类型到自身的转换。如果在pg_cast表里面找到一个,那么在存储到目标字段之前先在表达式上应用。这样的转换函数总是接受一个额外的类型为integer的参数,它接收目标字段的atttypmod值(实际上是其声明长度,atttypmod的解释随不同的数据类型而不同),并且它可能接受一个Boolean类型的第三个参数,表示转换是显式的还是隐式的。转换函数负责施加那些长度相关的语义,比如长度检查或者截断。
更多精彩内容
CDN加速
GaussDB
文字转换成语音
免费的服务器
如何创建网站
域名网站购买
私有云桌面
云主机哪个好
域名怎么备案
手机云电脑
SSL证书申请
云点播服务器
免费OCR是什么
电脑云桌面
域名备案怎么弄
语音转文字
文字图片识别
云桌面是什么
网址安全检测
网站建设搭建
国外CDN加速
SSL免费证书申请
短信批量发送
图片OCR识别
云数据库MySQL
个人域名购买
录音转文字
扫描图片识别文字
OCR图片识别
行驶证识别
虚拟电话号码
电话呼叫中心软件
怎么制作一个网站
Email注册网站
华为VNC
图像文字识别
企业网站制作
个人网站搭建
华为云计算
免费租用云托管
云桌面云服务器
ocr文字识别免费版
HTTPS证书申请
图片文字识别转换
国外域名注册商
使用免费虚拟主机
云电脑主机多少钱
鲲鹏云手机
短信验证码平台
OCR图片文字识别
SSL证书是什么
申请企业邮箱步骤
免费的企业用邮箱
云免流搭建教程
域名价格