Tcl API 中的 SQLite ':' 式参数替换:为什么这个整数在条件中被视为字符串?

问题描述 投票:0回答:1

我可能又做了一些愚蠢的事情,但我不明白下面查询中的参数替换。列

char_len
被声明为整数。

在 SQLite 查询中,

Tcl 变量

selEnd
被替换为字符串,因为查询返回所有行,就好像条件始终为 true 一样。我应该写下
selENd
出现在查询中
UNION ALL
WHERE
中的
and p.char_len + p.char_bgn <= :selEnd
之后。

如果

selEnd
的声明更改为
set selEnd [expr {799+1}]
,则仅返回应返回的行。

如果使用

.param set :selEnd 800
在 CLI 或 SQLite Fiddle 中运行相同的查询,则
selEnd
被视为整数。如果我只是输入
800
而不是
:selEnd
,则会返回正确的行。

如果使用双引号而不是大括号设置变量

SQL
,并且将条件更改为使用
$selEnd
而不是
:selEnd
,则会返回正确的行。

我不明白什么会导致在使用大括号设置

:selEnd
时将
'800'
视为
800
而不是
SQL

我认为 Tcl 将所有内容都视为字符串,直到它被“用于”某些东西为止。

SQL
只是一个字符串,其中
selEnd
将作为
800
插入;但是,似乎使用
:selEnd
类型参数替换决定了
selEnd
是一个字符串,应该作为
'800'
插入。为什么?

谢谢你。

set docId 1
set selStart 500
set selEnd 800; #[expr {799+1}]

set SQL {\
with recursive
pieces( order_idx, doc_id, key, buffer_id, char_start, char_len, char_bgn ) as
(
  select
     0,
     r.*,
     0
  from
    pt_pointers r
  where
        r.key = (select order_keys->>0 from ur_maps where doc_id = :docId)
    and r.doc_id = :docId

  UNION ALL

  select
     order_idx + 1,
     r.*,
     p.char_len + p.char_bgn
  from pt_pointers as r, pieces p
  where r.key = (select order_keys->>(order_idx+1) from ur_maps where doc_id = :docId)
    and p.char_len + p.char_bgn <= :selEnd
    and r.doc_id = :docId
)
select *
from pieces;\
}

db eval $SQL {
  chan puts stdout "$order_idx, $doc_id, $key, $buffer_id, $char_start, $char_len, $char_bgn"
}
sqlite tcl
1个回答
0
投票

我在 SQLite 论坛上问了这个问题,Dr.希普的答案是:

在TCL,一切都是字符串,至少理论上是这样。在引擎盖下, TCL 跟踪整数和浮点值等。 但我们的想法是,在开发人员级别,一切都正常进行 是一个纯字符串。 (事实上,在 Tcl8.0 之前,一切都真的 始终是一个字符串。其他数据类型在 Tcl8.0 中引入为 优化。)

SQLite 背离了 TCL 中的一切都是字符串的想法。 绑定时,如果底层 TCL 值具有某种表示形式 除了字符串之外,SQLite 尝试使用替代表示形式。 从技术上讲,这违反了规则,为此我已经 斥责。但现在不能在不破坏的情况下改变设计 兼容性,所以就是这样。

通常,Tcl/SQLite 界面“正常工作”,无需您 开发商必须要考虑一下。但如果你进入一些 复杂的情况,就像你似乎遇到的那样,那么这样做总是没有坏处的 CAST 你的绑定

© www.soinside.com 2019 - 2024. All rights reserved.