Shell脚本编写SQLite

9
我应该写一个能够显示SQLite结果的shell脚本,我已经写了一个可以向SQLite数据库添加条目的脚本。现在我想在添加条目后显示结果。
以下是我的脚本:
echo 'insert into myTable (Date, Details, Category, Average) values (datetime('\''now'\'','\''localtime'\''), '\'''$1''\'', '\'''$2''\'', '$3');'|sqlite3 /Users/user/Documents/Test/dbName.db

接下来,我希望该脚本能够通过echo/spit语句输出内容:

select sum(Average) from (select * from myTable where Category = 'category1');
select sum(Average) from (select * from myTable where Category = 'category2');

格式应该像这样:
Category1 total = <output of first statement>
Category2 total = <output of second statement>

就是这样。我在SQL方面还很新手,对shell脚本也不是很擅长。我也在寻找好的教程来解释这类问题。


1
既然你“不太擅长shell脚本”,那么你可能不应该使用shell脚本来解决这个问题。使用你最擅长的编码系统(C ++,TCL,Python等)。几乎所有你想要使用的东西都有可用的接口到sqlite API。 - ravenspoint
@ravenspoint:实际上,我正在使用SQL来管理我的财务状况,而shell脚本则用于通过运行脚本启动器(Quicksilver)快速添加内容和读取总和。 - CodeBreaker
既然你说“我对SQL很新”,我建议不要使用SQL来管理你的财务! - ravenspoint
脚本语言(Perl、Python、Ruby等)更适合这项任务。 - user554546
@ravenspoint:我正在学习SQL,并且通过管理我的财务状况,我只是指添加日常支出和其他东西,没有太复杂的内容(只有一个表)。我正在寻找适合这种情况的好应用程序,但似乎没有完全符合我需求的应用程序。 - CodeBreaker
@JackManey:Shell几乎是我唯一了解的脚本语言。我很少编写脚本,主要使用编译语言。如果shell脚本无法工作,对我来说唯一可行的选择是编写一个C程序,然后从我的应用程序启动器中调用它。工作...工作...;) - CodeBreaker
2个回答

15

解决这个问题的一种常见方法是使用一个称为“here document”的shell特性,试试这个:

 sqlite3 /Users/user/Documents/Test/dbName.dba <<EOS
     insert into myTable (Date, Details, Category, Average) 
               values(datetime('now','localtime'), '$1', '$2', '$3');

     select "Category1 total = " sum(Average) from (
          select * from myTable where Category = 'category1'
     );

     select "Category2 total = " sum(Average) from (
         select * from myTable where Category = 'category2'
     );

 EOS

注意,EOS可以是任何你喜欢的字符串(我认为它代表“脚本结束”),但它必须单独位于文本的最后一行,没有尾随空格。

由于我不使用sqlite3,你可能需要一些语句来关闭我不知道的批处理。此外,我不确定"$1"之类的东西是否有效,如果sqlite3是宽容的,请尝试使用"$1"等。此外,你可能需要在"CategoryN total = "字符串后加上逗号。

请注意,此解决方案允许你创建几乎任意大小/长度的sql DML语句。对于经常发生并且涉及大型表的操作,如果你在我们的系统上有权限,你可能想要将你的DML存储过程化并调用它。

希望这能帮到你。

(如果这不起作用,请编辑你的帖子,指出你正在使用哪个shell、OS/Linux版本以及你遇到的最小错误信息版本)。


谢谢。逻辑是完美的,但我无法插入到表中(第一条SQL语句)。问题与括号/引号有关。其他语句正常工作。顺便说一下,Rs.52的东西不在我的问题中。我有一个浏览器扩展程序,可以将美元转换为卢比,因此 Rs.52... 实际上是美元符号,即参数:dollar1、dollar2、dollar3。不知何故,它向我显示美元符号和其他 Rs.52 符号。 - CodeBreaker
你可以对第一个EOS使用单引号,像这样:sqlite3 dbName.dba <<'EOS' 这将防止在heredoc中扩展shell变量。 - Wildcard

8
如果您需要将sqlite的SELECT结果分配给一个shell变量,可以执行以下操作。
r=$(sqlite3 your_db_path.db "select something from some_table where condition")

$r将是你的变量。

也可以获取单行数据。您可以使用IFS将其拆分为数组。

此外,请记得在每个shell脚本的顶部使用#!/bin/bash约定。它会解决许多不必要的问题。有时旧的#!/bin/sh约定会引起麻烦。:)


如果您能展示如何从 $r 中获取值,那将非常有帮助。 - rakesh.sahu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接