这个思路的起因是想把查询结果保存起来,然后下次查询,先从保存的结果查询,如果有就不用去源数据库查询,否则就查询并保存到结果表,就像手工的物化视图,以减轻源数据库负担并快速获取结果。
查询结果是json数组的格式,程序需要读取key和value,并推断出类型,然后输出表头和数据。
提示词有点冗余,但大概就是上述思路,就不给出了。
下面是DeepSeek给出的程序,第一步是读取数据,第二步是解析输出
import db.sqlite
import x.json2
@[table: 't']
struct TableRow {
id int
json_meta string
csv_meta string @[skip]
csv_data string @[skip]
}
fn main() {
// 连接SQLite数据库
mut db := sqlite.connect('data.db') or {
println('无法连接数据库: $err')
return
}
defer {
db.close() or {}
}
// 查询所有数据
rows := sql db {
select from TableRow
} or {
println('查询失败: $err')
return
}
// 处理每行数据
for db_row in rows {
json_str := db_row.json_meta
println('\nProcessing ID: ${db_row.id}')
// 解析JSON
raw_data := json2.decode[json2.Any](json_str) or {
println('JSON解析失败: $err')
continue
}
// 转换为数组
if raw_data.arr().len == 0 {
println('非数组JSON或空数组')
continue
}
json_array := raw_data.arr()
// 从第一个对象获取字段名和类型
first_obj := json_array[0].as_map()
mut headers := []string{}
mut alignments := []string{}
for key, val in first_obj {
headers << key
match val {
int, f64 { alignments << '--:' } // 数字右对齐
else { alignments << '--' } // 文本左对齐
}
}
// 生成Markdown表格头
println(headers.join('|'))
println(alignments.join('|'))
// 生成数据行
for item in json_array {
obj := item.as_map()
mut row_data := []string{}
for header in headers {
val := obj[header] or { json2.Null{} }
row_data << match val {
json2.Null { 'NULL' }
int, f64 { val.str() } // 数字右对齐填充
else { val.str() }
}
}
println(row_data.join('|'))
}
}
}
运行此程序前需要先准备数据,csv_meta, csv_data是为下一步的功能预留的
./sqlite3 data.db "CREATE TABLE t(id INT, json_meta TEXT, csv_meta TEXT, csv_data TEXT);"
./sqlite3 data.db "INSERT INTO t VALUES(1, '[{\"x\":123},{\"x\":456}]', '', '');"
./sqlite3 data.db "INSERT INTO t VALUES(2, '[{\"category\":\"vegetables\",\"calories\":45,\"fats_g\":0.5,\"sugars_g\":2.0},{\"category\":\"seafood\",\"calories\":150,\"fats_g\":5.0,\"sugars_g\":0.0}]', '', '');"
然后就可以用下面的命令运行程序
v run sqlite_json2.v
Processing ID: 1
x
123
456
Processing ID: 2
category | calories | fats_g | sugars_g |
---|---|---|---|
vegetables | 45 | 0.5 | 2.0 |
seafood | 150 | 5.0 | 0.0 |
程序还存在一处问题,整数类型的列没有输出右对齐markdown标记–:,但浮点数输出了,从源代码上看不出来。