Tcl中包含希伯来语的连接列表



我使用的是Tcl 8.6.11、SQLite 3.35.5和Manjaro Linux KDE。

我试着用希伯来语写一首诗,并在数据表中每行写一个单词。这是一个例如,诗句。

在美国

目标是将数据写入列表,然后作为SQL插入语句的值部分加入该列表。正如您所看到的,每个[lindex $l n]都按预期打印,但从第二个元素开始的[join $l ,]将希伯来语放在第一个位置,而不是最后一个位置,从而导致SQL语句失败。

如何使[join $l ,]的每个组件按照[lindex $l n]中的顺序进行排序?

谢谢。

set l {}
set sql { select * from src_original where type_no=0 and book_no < 40 limit 1}
dbws eval $sql origLang {
set i 0
foreach { x } $origLang(original) { lappend l "($origLang(book_no),$origLang(chapter_no),$origLang(verse_no),[incr i],$x)" }
}
puts [lindex $l 0]; # (1,1,1,1,בְּרֵאשִׁית)
puts [lindex $l 1]; # (1,1,1,2,בָּרָא)
puts [lindex $l 2]; # (1,1,1,3,אֱלֹהִים)
puts [lindex $l 3]; # (1,1,1,4,אֵת)
puts [lindex $l 4]; # (1,1,1,5,הַשּׁמַיִם)
puts [lindex $l 5]; # (1,1,1,6,וְאֵת)
puts [lindex $l 6]; # (1,1,1,7,הָאָֽרֶץ׃)
set v [join $l ,]; # (1,1,1,1,בְּרֵאשִׁית),(1,1,1,2,בָּרָא),(1,1,1,3,אֱלֹהִים),(1,1,1,4,אֵת),(1,1,1,5,הַשּׁמַיִם),(1,1,1,6,וְאֵת),(1,1,1,7,הָאָֽרֶץ׃)
set r "insert into vowel_pts (book_no, chapter_no, verse_no, index_no, word) values $v"
dbws eval $r

感谢您提供的示例和建议。我仍然想了解join是否导致了一个无序的SQL语句,但是,在查看了@Shawn提供的SQL之后,我尝试使用SQLite JSON扩展,以下也适用。如果去掉arr_vp表中where子句的限制,使《旧约》三十九本书中每一节中的所有单词都作为一行书写,就像@DonalFellows建议的那样,它在我十岁的普通笔记本电脑上只需几秒钟就完成了。再次感谢。

with
arr_vp as (
select book_no, chapter_no, verse_no,
'["' || replace(original,' ', '","' ) || '"]' as t
from src_original
where book_no=1
and chapter_no=1
and verse_no < 3
and type_no=0
)
select a.book_no, a.chapter_no, a.verse_no,
(key+1) as index_no,
j.value as vowel_pts
from arr_vp a,
json_each( ( select t
from arr_vp r
where r.book_no=a.book_no
and r.chapter_no=a.chapter_no
and r.verse_no=a.verse_no ) ) as j
where j.type = 'text';

与SQL一样,在准备好的语句中使用参数,而不是在运行时尝试直接将值添加到查询字符串中。类似于:

# Populate an array of dicts
set l {}
set sql {select * from src_original where type_no=0 and book_no < 40 limit 1}
dbws eval $sql origLang {
set i 0
foreach x $origLang(original) {
lappend l [dict create book_no $origLang(book_no) 
chapter_no $origLang(chapter_no) 
verse_no $origLang(verse_no) 
index_no [incr i] 
word $x]
}
}
# And insert them one at a time.
foreach w $l {
dict with w {
dbws eval {
INSERT INTO vowel_pts(book_no, chapter_no, verse_no, index_no, word)
VALUES ($book_no, $chapter_no, $verse_no, $index_no, $word)
}
}
}

有关在SQL语句中嵌入(未赋值(变量名以及将值绑定到这些变量名的详细信息,请参阅文档。


我确实设法在核心Sqlite3中找到了一种方法来做到这一点,假设一个标准的空格字符来分隔单词,我认为它会起作用:

dbws eval {
WITH verse AS (SELECT * FROM src_original WHERE type_no = 0 AND book_no < 40 LIMIT 1),
words AS
(SELECT book_no, chapter_no, verse_no,
substr(original || ' ', 1, instr(original || ' ', ' ') - 1) AS word,
substr(original || ' ', instr(original || ' ', ' ') + 1) AS original,
1 AS index_no
FROM verse
UNION ALL
SELECT book_no, chapter_no, verse_no,
substr(original, 1, instr(original, ' ') - 1),
substr(original, instr(original, ' ') + 1),
index_no + 1
FROM words WHERE length(original) > 0)
INSERT INTO vowel_pts(book_no, chapter_no, verse_no, index_no, word)
SELECT book_no, chapter_no, verse_no, index_no, word FROM words
}

join命令不会更改内存中字符的顺序。然而,屏幕上混合的从左到右和从右到左脚本的渲染……嗯,到处都是。

但是,由于您这样做只是为了将数据从数据库移动到数据库,请找到一种不将数据本身带入Tcl的方法。它也会更快、更安全。

最新更新