当表2的某些行更新时,Sqlite触发器将更新表1

时间:2019-04-28 11:50:51

标签: android sqlite sql-update

我在android的sqlite中有两个表:

Table1: Outlets

id    pid   OutletName   Status
1      1    Tesco         1
2      1    Coors         1
3      2    Coors         1

表2:projectparams

ppid projectname outletname  param          projStatus
1      RA_Pepsi   Tesco       shelfstrip       2
2      RA_Pepsi   Tesco       shelfleft        2
3      RA_Cocola  Coors       shelfstrip       1

表1:对于每个PID(ProjectID),OutletName中都存储有多个Outlet。

表2:对于每个出口,项目参数中存储了多个参数。

只要用户完成任务,表2中的参数就会更新为2。在上面的示例中,当用户在Tesco中完成两个任务时,状态将在完成时更新为2。

我正在尝试根据每个网点的任务完成情况将网点状态设置为2。在此示例中,当projectparam表中的状态更新为2时,我希望出口Tesco的Outlet中的状态更新为2。

我正在使用以下代码:

任务完成时触发。

private void updateTaskStatus() {
        SQLiteDatabase db = sqLiteHelper.getWritableDatabase();
        String spinTextRecovered = spnTxt.getString("spinText", null);
        String updateTable = "update projectparams set projStatus=2 where param='"+spinTextRecovered+"' and projectName='"+projectName+"' and OutletName='"+outletName+"'";
        db.execSQL(updateTable);
        takePicButton.setEnabled( false );
    }

每次任务完成时触发,并在插座的所有任务完成时更新插座状态。

   private void updateOutletStatus() {
        String query = "select OutletName from projectparams where projectName= '"+projectName+"' and OutletName= '"+outletName+"' group by projStatus";
        if (sqLiteHelper.getData(query).getCount()==1) {
            Toast.makeText( getApplicationContext(), "No more tasks in this outlet!", Toast.LENGTH_SHORT ).show();
            SQLiteDatabase db = sqLiteHelper.getWritableDatabase();
            String outletUpdate = "update outlets set Status=2 where OutletName='"+outletName+"' and pid = (select id from projects where ProjectName = '"+projectName+"' ) ";
            db.execSQL(outletUpdate);
        }
    }

上面的代码有效...但是,由于我使用意图显示项目,销售点和任务参数,很多时候我发现更新销售没有发生。

我可以写得更好吗?有人可以指导我使用触发器吗?

1 个答案:

答案 0 :(得分:1)

我相信您的核心问题是查询

String query = "select OutletName from projectparams where projectName= '"+projectName+"' and OutletName= '"+outletName+"' group by projStatus";

不仅所有项目都已完成,而且所有项目都没有完成(例如,所有projStatus值为1),都将返回1。

此外,就好像Outlets表是多余的那样。那就是projectparams表中的所有列(没有ID的列)都是重复的。

您可以通过将参数数量乘以所有projstatus值的总和乘以2(状态完成值)来确定项目的所有任务。如果它们匹配,则所有参数都设置为2。

请考虑以下是您的数据(但RA_Perpsi / Tesco行的状态为1)以及一些其他数据,其中唯一完整完成的是 Completed Example 项目(突出显示),具体如下:-< / p>

enter image description here

使用(处理所有结果)

-- WHERE clause removed group by projectname added (to show all results)
SELECT OutletName FROM projectparams GROUP BY projectname,projStatus;

结果是:-

enter image description here

  • 也就是说Ra_Pepsi / Tesco没有完成参数(什么都没有完成),但是只有一行,因此该项目被检测为完成。对于RA_Cocola和其他渠道也是如此。
  • 完整示例产生1行,因此应该是完整的。残缺不全的示例(部分途经)是唯一不完整的示例。

使用以上数据,请考虑以下内容(注意,无需引用Outlets表,并且已省略WHERE子句,并且根据项目名称显示GROUP BY以显示所有项目):-

SELECT 
    OutletName, 
    CASE 
        WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
        END AS Status,
    (count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding 
FROM projectparams 
GROUP BY projectname

结果为:-

enter image description here

因此,至少在您的示例中,不需要出口表,projectparams表就足够了,因此不需要触发器。每当进行更新时,您只需使用一个表和一个查询(例如上一个示例)刷新显示。

要逐步展示您的方案,请考虑以下代码(基于上面的数据,即已添加RA_Pepsi,但未完成任何操作):-

-- First Query
SELECT 
    OutletName, 
    CASE 
        WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
        END AS Status,
    (count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding 
FROM projectparams 
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;

-- First Update
UPDATE projectparams SET projStatus = 2 WHERE param = 'shelfstrip' AND projectname = 'RA_Pepsi' AND outletName = 'Tesco';

-- 2nd Query
SELECT 
    OutletName, 
    CASE 
        WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
        END AS Status,
    (count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding 
FROM projectparams 
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;

-- 2nd Update (all completed) 
UPDATE projectparams SET projStatus = 2 WHERE param = 'shelfleft' AND projectname = 'RA_Pepsi' AND outletName = 'Tesco';


-- 3rd Query
SELECT 
    OutletName, 
    CASE 
        WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
        END AS Status,
    (count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding 
FROM projectparams 
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;

第一个查询显示的项目没有按照:-

完成

enter image description here

第二个查询(将架子带的状态更改为2后)显示:-

enter image description here

第三个查询(将架子左侧的状态更改为2后)显示:-

enter image description here

对于Android

下面的代码演示了如何在Android上应用上述内容,以及如何使用推荐的便捷方法(它们构建了大量SQL,关闭了防止SQL注入的功能,并添加了其他功能,例如update返回更新的行数):-

两种方法(第一种使用上面的查询,第二种根据您的情况进行更新,但使用update便捷方法:-

public String getOutletStatus(String projectname, String outletname) {
    String rv = "Ooops nothing found!"; // default if nothing found
    String[] columns = new String[]{"outletname",
            "CASE " +
                    "WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1 " +
                    "END AS Status", //<<<<<<<<< the column name will be Status
            "(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding" // The column name will be outstanding
    };
    String whereclause = "projectname=? AND outletName=?";
    String[] whereargs = new String[]{projectname,outletname};
    String groupby = "projectname"; // not needed
    Cursor csr = sqliteHelper.getWritableDatabase().query("projectparams",columns,whereclause,whereargs,null,null,null);
    if (csr.moveToFirst()) {
        int statuscode = csr.getInt(csr.getColumnIndex("Status"));
        String outstanding = csr.getString(csr.getColumnIndex("outstanding"));
        String outlet = csr.getColumnName(csr.getColumnIndex("outletname"));
        String statusdescription = "incomplete";
        if (statuscode == 2) {
            statusdescription = "complete";
        }
        rv = "The status of project " + projectname + " for outlet " + outlet + " is " + statusdescription + ". With " + outstanding + ".";
    }
    csr.close();
    return rv;
}

public void updateStatus(String projectname, String outletname, String param) {
    String whereclause = "projectname=? AND outletname=? AND param=?";
    String[] whereargs = new String[]{projectname,outletname,param};
    ContentValues cv = new ContentValues();
    cv.put("projStatus",2);
    int number_of_rows_updated = sqliteHelper.getWritableDatabase().update("projectparams",cv,whereclause,whereargs);
}

它们已经过测试(使用上面显示的基础数据),并且反映了最后3个查询以及它们之间的更新:-

    String status = getOutletStatus("RA_Pepsi","Tesco"); // Before anything
    Log.d("RESULT",status);

    updateStatus("RA_Pepsi","Tesco","shelfstrip"); //shelfstrip completed
    status = getOutletStatus("RA_Pepsi","Tesco");
    Log.d("RESULT",status);

    updateStatus("RA_Pepsi","Tesco","shelfleft"); //shelfleft completed
    status = getOutletStatus("RA_Pepsi","Tesco");
    Log.d("RESULT",status);

结果在日志中:-

04-29 12:46:09.615 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is incomplete. With 2 of 2.
04-29 12:46:09.621 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is incomplete. With 1 of 2.
04-29 12:46:09.625 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is complete. With 0 of 2.