对于SQLite 3.35.2和SpatiaLite(实际上安装的是QGIS 3.16的DBManager),我有以下问题:
使用CREATE TABLE创建表时..作为SELECT...,创建的表具有与从中选择数据的原始表不同的数据类型。
原始表格是从IGN BD TOPO(免费的法国地形数据库)导入的数据,以geopack的形式下载并使用ogr2ogr导入到SQLite中:
# Name Type Null Default
0 fid INTEGER Y
1 cleabs VARCHAR(24) Y
2 nature VARCHAR Y
3 usage_1 VARCHAR Y
4 usage_2 VARCHAR Y
5 construction_legere INTEGER_BOOLEAN Y
6 etat_de_l_objet VARCHAR Y
7 date_creation TIMESTAMP Y
8 date_modification TIMESTAMP Y
9 date_d_apparition DATE Y
10 date_de_confirmation DATE Y
11 sources VARCHAR Y
12 identifiants_sources VARCHAR Y
13 methode_d_acquisition_planimetr VARCHAR Y
14 precision_planimetrique FLOAT Y
15 methode_d_acquisition_altimetri VARCHAR Y
16 precision_altimetrique FLOAT Y
17 nombre_de_logements INTEGER Y
18 nombre_d_etages INTEGER Y
19 materiaux_des_murs VARCHAR(2) Y
20 materiaux_de_la_toiture VARCHAR(2) Y
21 hauteur FLOAT Y
22 altitude_minimale_sol FLOAT Y
23 altitude_minimale_toit FLOAT Y
24 altitude_maximale_toit FLOAT Y
25 altitude_maximale_sol FLOAT Y
26 origine_du_batiment VARCHAR Y
27 appariement_fichiers_fonciers VARCHAR(32) Y
28 geometrie GEOMETRY Y
用于创建表的查询为:
CREATE TABLE test12 AS
SELECT
batiments.* , ST_Area(batiments.geometrie) AS "emprise au sol bâtiment (m²)",
parcelles.fid as parcelle_fid , parcelles.geo_parcel AS parcelle_geo_parcel , parcelles."rne_ref ca" AS "identifiant lycée" ,
(ST_Area(ST_Intersection(parcelles.geom , batiments.geometrie)) / ST_Area(batiments.geometrie)) AS "% emprise bâtiment contenue dans parcelle"
FROM 'parcelles lycées raura' LIMIT 10 as parcelles
JOIN "bâtiments bd topo" AS batiments
ON ST_Intersects(parcelles.geom , batiments.geometrie );
SELECT RecoverGeometryColumn("test12", 'geometrie', 2154, 'MULTIPOLYGON', 'XY');
得到的表格是:
# Name Type Null Default
0 fid INT Y
1 cleabs TEXT Y
2 nature TEXT Y
3 usage_1 TEXT Y
4 usage_2 TEXT Y
5 construction_legere INT Y
6 etat_de_l_objet TEXT Y
7 date_creation NUM Y
8 date_modification NUM Y
9 date_d_apparition NUM Y
10 date_de_confirmation NUM Y
11 sources TEXT Y
12 identifiants_sources TEXT Y
13 methode_d_acquisition_planimetr TEXT Y
14 precision_planimetrique REAL Y
15 methode_d_acquisition_altimetri TEXT Y
16 precision_altimetrique REAL Y
17 nombre_de_logements INT Y
18 nombre_d_etages INT Y
19 materiaux_des_murs TEXT Y
20 materiaux_de_la_toiture TEXT Y
21 hauteur REAL Y
22 altitude_minimale_sol REAL Y
23 altitude_minimale_toit REAL Y
24 altitude_maximale_toit REAL Y
25 altitude_maximale_sol REAL Y
26 origine_du_batiment TEXT Y
27 appariement_fichiers_fonciers TEXT Y
28 geometrie NUM Y
29 emprise au sol bâtiment (m²) Y
30 parcelle_fid INT Y
31 parcelle_geo_parcel TEXT Y
32 identifiant lycée TEXT Y
33 % emprise bâtiment contenue dans parcelle Y
因此,所有VARCHAR都变成了文本;日期和时间戳变成了NUM;浮点变成了真实;等等。最烦人的是,几何字段也变成了NUM。计算字段(“企业规模(m?)”和“企业规模(%)”)没有数据类型。
有没有办法保留原始数据类型?
PS:还有,在使用CREATE TABLE时,有没有办法拥有主键?作为声明?
2条答案
按热度按时间oyjwcjzk1#
SQLite只有五种数据类型。您可以在基本的CREATE TABLE语句中指示其他数据类型,SQLite将接受这些数据类型。但在处理CREATE TABLE语句期间,它仍将根据其Map方案解释每个数据类型名称。当您使用CREATE TABLE<>AS语句时,SQLite不复制原始DDL定义,而是根据先前解释的和Map的数据类型设置新列的数据类型。如果希望新数据类型定义与原始数据类型定义匹配,则必须使用为每列指定显式数据类型的CREATE TABLE。您还可以在CREATE TABLE<>AS语句中包括显式模式定义。
您也不能在架构定义语句之外指定主键。对于这两个要求,您需要将您的模式定义作为单独的语句包含,然后使用INSERT INTO/SELECT或作为CREATE TABLE<>AS语句的一部分。
llew8vvj2#
我发现了一个解决办法,尽管很麻烦:
使用常规的CREATE TABLE语句创建表,并指定每个字段数据类型。
然后使用*INSERT INTO TABLE(字段列表)SELECT..*语句。
但是,这将失去CREATE TABLE的全部美感。作为声明。