Tcl SQLite 更新变量替换不能有撇号

Leg*_*ack 1 sql sqlite tcl variable-substitution

问题是:如果我使用 { } 作为更新命令,如下所示:

package require sqlite3
fileRepo eval {UPDATE uploads SET $col=$data WHERE rowid=$id}
Run Code Online (Sandbox Code Playgroud)

我无法替换大括号内的任何变量。这一切都必须进行硬编码。

但是,如果我使用“”作为更新命令,如下所示:

fileRepo eval "UPDATE uploads SET $col='$data' WHERE rowid=$id"
Run Code Online (Sandbox Code Playgroud)

我可以替换双引号内的变量,但我必须使用 ' ' 才能输入带空格的数据,以便 sql 将其视为一个输入。如果我不这样做,如果我发送类似的内容,我会收到错误

$data = "合法堆栈"

因为它有一个空格,所以 sql 会被单词“Stack”阻塞,除非它放在单引号内

所以...

如果我将此数据发送到更新命令:

$col = description
$data = "Stack's Pet"
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

靠近“s”:执行“fileRepo eval”UPDATE uploads SET $col='$data' WHERE rowid=$id”时出现语法错误...

因此,鉴于这些规则,我看不出有什么办法可以成功地将单引号或撇号传递给更新命令。有其他方法可以做到这一点吗?

谢谢!

sch*_*enk 5

虽然您确实可以通过将单引号加倍来转义它们(就像 SQL 中常见的那样),但您的代码却面临 SQL 注入攻击的危险。

最好将代码分成两个不同的步骤:

  • 替换为format {UPDATE uploads SET %s=$data WHERE rowid=$id} $col

  • 让 sqlite3 magic eval 将$data和转换$id为准备好的语句的绑定变量

这样,您只需要清理col变量,以确保它包含有效的列名,而不是所有数据,而不是其他任何内容(应该很容易)。此外,您不需要经常复制大值,因此两步方法甚至会更快。为了更清楚地表明您想要使用绑定变量,请尝试:在变量名称前面添加 a 的替代语法。

package require sqlite3
set stmt [format {UPDATE uploads SET %s=:data WHERE rowid=:id} $col]
fileRepo eval $stmt
Run Code Online (Sandbox Code Playgroud)

推荐阅读: