【问题标题】:Tcl SQLite update variable substitution cannot have apostropheTcl SQLite 更新变量替换不能有撇号
【发布时间】:2016-02-03 21:26:22
【问题描述】:

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

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

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

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

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

我可以替换双引号内的变量,但我必须使用 ' ' 来输入带空格的数据,以便 sql 将其视为一个输入。如果我不发送类似

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

$data = "合法堆栈"

因为它有一个空格,所以 sql 会卡在这个词上:Stack 除非它放在单引号内

所以……

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

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

我收到以下错误:

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

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

谢谢!

【问题讨论】:

    标签: sql sqlite tcl variable-substitution


    【解决方案1】:

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

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

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

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

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

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

    推荐阅读:

    【讨论】:

    【解决方案2】:

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

    $data = "Stack''s Pet"

    【讨论】:

    • 像这样转义单引号确实是 SQL 的事情
    猜你喜欢
    • 2015-12-17
    • 2014-11-07
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2015-05-30
    • 2014-07-22
    • 2013-01-04
    • 2023-03-25
    相关资源
    最近更新 更多