简体   繁体   English

使用C ++中的sqlite3命令对表进行排序,添加和剪切

[英]Sort, add up and cut of table with sqlite3 commands in c++

I have a table which looks like this: 我有一张桌子,看起来像这样:

id | amount | value
1  |   2    |   3
2  |   4    |   5
3  |   2    |   4

First I would like to sort the table by value:. 首先,我想按值对表格进行排序: Then I want to cut of the table when the added amount is greater than a certain max_amount. 然后,当添加的数量大于某个max_amount时,我想剪切表。

Right now I have a routine to do that. 现在,我有例行的操作。 How it is supposed to work: It basically looks at each row, compares whether the added_amount is larger than the max_amount. 应该如何工作:基本上看每行,比较add_amount是否大于max_amount。 If not it writes the entry in a different, new table if yes it takes the difference (max_amount - added_amount) puts it in the new table and then returns. 如果不是,则将条目写入另一个新表中;如果是,则采用差异(max_amount-addd_amount)将其放入新表中,然后返回。 After that I delete the entries of the old table and transfer the data from the new table into the old one. 之后,我删除旧表的条目,并将数据从新表转移到旧表中。

RESULT (for max_amount = 5): 结果(对于max_amount = 5):

id | amount | value
1  |   2    |   3
3  |   2    |   4
2  |   1    |   5

It seems rather complicated and is kind of slow. 似乎比较复杂,有点慢。 Therefore, I would love to find an easier way. 因此,我很想找到一种更简单的方法。 I was wondering if there was an SQLITE3 command for that or at least a smarter way :) 我想知道是否有用于此的SQLITE3命令,或者至少是一种更聪明的方法:)

Hope someone has an idea! 希望有人有主意! :D :d

~ AMK 〜AMK

EDIT (c++ function would look something like that): 编辑(c ++函数看起来像这样):

    while(1)
{
    id = id + 1;

    sql = "SELECT * FROM table ORDER BY value ASC LIMIT 1 OFFSET ?";

    sqlite3_stmt *stmt;

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "Can not prepare: %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        exit(0);
    }

    rc = sqlite3_bind_int(stmt, 1, id);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "Can not bind: %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        exit(0);
    }
    rc = sqlite3_step(stmt);
    (...)
    value = sqlite3_column_int(stmt, 0);
    value1 = sqlite3_column_double(stmt, 1);
    value2 = sqlite3_column_double(stmt, 2);
    sqlite3_finalize(stmt);

    sql = "INSERT OR REPLACE INTO table_new (id, amount, value) values (?,?,?)";
    amount_added = amount_added + value1;
    if(amount_added >= amount_max)
    {
        value1 = value1 - (amount_added - amount_max);
                    done = 1;
    }

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    rc = sqlite3_bind_int(stmt, 0, value);
    rc = sqlite3_bind_int(stmt, 1, value1);
    rc = sqlite3_bind_int(stmt, 2, value2);
    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    (... put table_new data into table)

            if(done == 1){return = 0;}
}

First of all, take a look at this answer and adapt at your case: 首先,看看这个答案并适应您的情况:

int main() {
  std::string query = "SELECT *  FROM table WHERE amount > 5 ORDER BY value ASC"; 
  system("connectDB.sh " + query.c_str()); 
  /* connectDB.sh should be chmod +x */
}

Your script will be: 您的脚本将是:

#!/bin/bash
sqlite3 test.db ${1}

edit 编辑

if you're working on linux platform, you have to create a file, for example: 如果您使用的是Linux平台,则必须创建一个文件,例如:

connectDB.sh

and copy/paste this two rows: 并复制/粘贴这两行:

#!/bin/bash
sqlite3 test.db ${1}

first line: you're using bash 第一行:您正在使用bash
second line: execute sqlite3 program on test.db file passing ${1}, the first parameter when you call "connectDB "select* from t"": in this case ${1} = "select* from t" 第二行:在传递$ {1}的test.db文件上执行sqlite3程序,这是调用“ connectDB” select * from t“”时的第一个参数:在这种情况下$ {1} =“ select * from t”

remember to give to file the execution priviledge: 记住要给予执行特权:

 chmod +x connectDB.sh

From your main 从您的主要

system("connectDB.sh " + query.c_str()); 

you perform a system call to file connectDB.sh passing the string with your query. 您对文件connectDB.sh执行系统调用,并将字符串与查询一起传递。

I hope I was clear.. 我希望我很清楚。

I found out why the routine was rather slow. 我发现了为什么例行程序比较慢。 It is explained in the sqlite-faq https://sqlite.org/faq.html (19). 在sqlite-faq https://sqlite.org/faq.html(19 )中对此进行了解释。 The transaction speed depends on your hard drive: 事务处理速度取决于您的硬盘驱动器:

A transaction normally requires two complete rotations of the disk platter, which on a 7200RPM disk drive limits you to about 60 transactions per second. 一个事务通常需要磁盘盘完整旋转两次,在7200RPM磁盘驱动器上,这限制您每秒大约60个事务。

Therefore, you can fasten it up using "BEGIN...COMMIT". 因此,您可以使用“ BEGIN ... COMMIT”将其固定。

Other than that, you can of course combine the two statements into one... With "INSERT OR UPDATE ... SELECT ..." (not really relevant for speed) 除此之外,您当然可以将两个语句合并为一个...使用“ INSERT OR UPDATE ... SELECT ...”(与速度无关)

I came to the conclusion that you have to use some kind of routine to cut it of and am almost certain, that you can't replace this routine with some kind of sqlite statement. 我得出的结论是,您必须使用某种例程来削减它,并且几乎可以肯定,您不能用某种sqlite语句替换该例程。

Thanks for all your help. 感谢你的帮助。

~ AMK 〜AMK

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM