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

Tcl SQLite update variable substitution cannot have apostrophe

这是问题所在:如果我像这样使用 { } 作为更新命令:

package require sqlite3
fileRepo eval {UPDATE uploads SET $col=$data WHERE rowid=$id}

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

但是,如果我像这样使用“”作为更新命令:

fileRepo eval "UPDATE uploads SET $col='$data' WHERE rowid=$id"

我可以替换双引号内的变量,但我必须使用 ' ' 才能用 space 放入数据,因此 sql 将其视为一个输入。如果我不发送类似

的内容,我会收到错误消息

$data = "Legit Stack"

因为它有一个 space sql 会被这个词噎住:堆栈 除非放在单引号内

因此...

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

$col = description
$data = "Stack's Pet"

我收到以下错误:

near "s": syntax error while executing "fileRepo eval "UPDATE uploads SET $col='$data' WHERE rowid=$id" ...

因此,根据这些规则,我无法成功地将单引号或撇号传递给更新命令。有没有不同的方法来做到这一点?

谢谢!

您必须使用转义撇号。所以它应该是这样的:

$data = "Stack''s Pet"

虽然您确实可以通过将单引号加倍来转义单引号(在 SQL 中通常如此),但您的代码面临着 SQL 注入攻击的危险。

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

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

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

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

package require sqlite3
set stmt [format {UPDATE uploads SET %s=:data WHERE rowid=:id} $col]
fileRepo eval $stmt

推荐阅读: