SQLite/SpatiaLite:CREATE TABLE的数据类型错误..AS

gfttwv5a  于 2022-11-14  发布在  SQLite
关注(0)|答案(2)|浏览(243)

对于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时,有没有办法拥有主键?作为声明?

oyjwcjzk

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语句的一部分。

llew8vvj

llew8vvj2#

我发现了一个解决办法,尽管很麻烦:
使用常规的CREATE TABLE语句创建表,并指定每个字段数据类型。
然后使用*INSERT INTO TABLE(字段列表)SELECT..*语句。
但是,这将失去CREATE TABLE的全部美感。作为声明。

相关问题