SQLite3查询存储IP地址语法错误

SQLite3查询存储IP地址语法错误

我正在尝试对小型数据库运行 sqlite3 查询来更新表。虽然脚本更复杂,但为了测试我设置了以下变量:

DN=123
UP=123
downlocalip=10.1.2.3
downremoteip=123
uplocalip=123
upremoteip=123

然后我运行以下命令来更新表。

sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed='''$DN''', upspeed='''$UP''', downlocalip='''$downlocalip''', downremoteip='''$downremoteip''', uplocalip='''$uplocalip''', upremoteip='''$upremoteip''' WHERE primkey=1"

这会引发语法错误:

Error: near ".2": syntax error

如果我设置下本地ip仅作为 10.1,它工作得很好,所以它不喜欢额外的小数。

在表格本身上,我将类型设置为文本,所以我认为这并不重要?

表的编译指示输出:

0|primkey|integer|0||1
1|downspeed|integer|1||0
2|upspeed|integer|1||0
3|downlocalip|text|1||0
4|downremoteip|text|1||0
5|uplocalip|text|1||0
6|upremoteip|text|1||0

我尝试了各种引号设置,但看不出我做错了什么。

有任何想法吗?

编辑:

我根据下面的评论尝试过的完整命令是:

/usr/bin/ssh [email protected] 'sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip="$downlocalip", downremoteip="$downremoteip", uplocalip="$uplocalip", upremoteip="$upremoteip" WHERE primkey=1"'

或者

/usr/bin/ssh [email protected] 'sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip='$downlocalip', downremoteip='$downremoteip', uplocalip='$uplocalip', upremoteip='$upremoteip' WHERE primkey=1;"'

两者都给我以下错误:

Error: near ",": syntax error

新命令,更接近:

ssh [email protected] sqlite3 /var/www/server/newserverstats.db <<END_SQL
    UPDATE stats
    SET downspeed=$DN,
        upspeed=$UP,
        downlocalip="$downlocalip",
        downremoteip="$downremoteip",
        uplocalip="$uplocalip",
        upremoteip="$upremoteip"
    WHERE primkey=1
END_SQL

折叠回测试脚本中的一行:

#!/bin/bash -x
DN=123
UP=123
downlocalip=10.1.2.3
downremoteip=123
uplocalip=123
upremoteip=123
sql="UPDATE stats SET downspeed=$DN, upspeed=$UP, downlocalip="$downlocalip", downremoteip="$downremoteip", uplocalip="$uplocalip", upremoteip="$upremoteip" WHERE primkey=1"
echo $sql
ssh [email protected] sqlite3 /var/www/server/newserverstats.db "$sql"

这给了我以下回应:

UPDATE stats SET downspeed=123, upspeed=123, downlocalip=10.1.2.3, downremoteip=123, uplocalip=123, upremoteip=123 WHERE primkey=1
sqlite3: Error: too many options: "stats"
Use -help for a list of options.

答案1

问题在于文本字段中字符串的引用。

使用此处文档(它使您能够编写更美观的语句):

sqlite3 database <<END_SQL
    UPDATE stats
    SET downspeed=$DN,
        upspeed=$UP,
        downlocalip="$downlocalip",
        downremoteip="$downremoteip",
        uplocalip="$uplocalip",
        upremoteip="$upremoteip"
    WHERE primkey=1
END_SQL

这是假设您可以完全控制变量中的值,以便您知道它们已被正确清理并且不会引入任何 SQL 注入漏洞。


来自评论:

通过 SSH 执行此操作:

ssh user@server sqlite3 database <<END_SQL
    UPDATE stats
    SET downspeed=$DN,
        upspeed=$UP,
        downlocalip="$downlocalip",
        downremoteip="$downremoteip",
        uplocalip="$uplocalip",
        upremoteip="$upremoteip"
    WHERE primkey=1
END_SQL

答案2

主要问题是您在每个变量之前和之后使用了三个单引号,而不是仅一个。这是没有必要的——事实上,这是行不通的。

您在 IP 地址上收到错误,$downlocalip因为它实际上未加引号,因此 sqlite3 尝试将其解释为浮点数而不是文本字符串......并且浮点数中没有两个小数点。

另一个小问题是您在整数字段 (downspeedupspeed) 的值两边加上单引号。

试试这个:

sqlite3 /var/www/server/newserverstats.db "UPDATE stats SET downspeed=$DN,
   upspeed=$UP, downlocalip='$downlocalip', downremoteip='$downremoteip',
   uplocalip='$uplocalip', upremoteip='$upremoteip' WHERE primkey=1;"

该字符串中的单引号是里面双引号,因此不会阻止 shell 扩展变量。它们在双引号内没有特殊含义,它们只是文本的一部分。双引号内的变量确实具有特殊含义,因此请按照您的预期进行扩展。

或者使用 Kusalananda 的答案中的heredoc - 它更具可读性。

顺便说一句,如果您正在进行大量 sqlite 操作,那么最好使用具有支持占位符值的 sqlite 库模块的语言来编写脚本。例如,两者perl都有python出色的库用于处理 sqlite3 和其他 SQL 数据库。您通常可以使用这些库编写代码,这样它们只需进行很少的更改(如果有的话)即可与其他数据库(例如 postgresql 或 mysql)一起使用。

相关内容