如何在SQLite中替换instr()函数?

时间:2018-02-20 06:16:54

标签: android sql sqlite

鉴于SQLite KitKat Android不支持 // Define new Class public class VhcleInfo { [DisplayName("Registration Number") public string RegNo { get; set; } [DisplayName("Make and Model") public string MakeModel {get; set; } [DisplayName("Year of Manufacture") public int Year { get; set; } } // Create IEnum for Defined Class var vlist = from lst in dc.tblVhcleInfos select new VhcleInfo() { RegNo = lst.RegNo, MakeModel = lst.makeModel, Year = lst.YOM }; // Set Data Source dataGridView1.DataSource = vlist; 功能,如何在SQL语句中获取以下表达式?

instr()

我的目标是获取字符串的第一部分,直到'_',其位置是可变的。我在substr(mystring, instr(mystring, '_')+1) 子句中使用此表达式,我需要直接在 JOIN 中使用它。

提前致谢。 达尼洛

1 个答案:

答案 0 :(得分:0)

也许不是最好/理想/优雅的方式,但你可以使用基于以下内容的东西: -

E5:F6

初始注释掉的语句使用单个列名 test 创建表 noinstr ,并根据以下内容填充表格: -

enter image description here

查询返回: -

enter image description here

编辑评论: -

  

这种“搜索和测试”方法看起来有点令人费解,但它   作品。但是如果字符串太长了怎么办?你必须硬编码   测试所有可能的角色位置

您始终可以根据最大长度生成SQL,例如: -

-- Create testing Table and data
--CREATE TABLE IF NOT EXISTS noinstr (test TEXT);
--INSERT INTO noinstr VALUES('short_xxx');
--INSERT INTO noinstr VALUES('thisisevenlonger_yyyyyyyy');
--INSERT INTO noinstr VALUES('nothing to return in this text');
SELECT 
CASE 
    WHEN substr(test,2,1) = '_' THEN substr(test,1,1)
    WHEN substr(test,3,1) = '_' THEN substr(test,1,2)
    WHEN substr(test,4,1) = '_' THEN substr(test,1,3)
    WHEN substr(test,5,1) = '_' THEN substr(test,1,4)
    WHEN substr(test,6,1) = '_' THEN substr(test,1,5)
    WHEN substr(test,7,1) = '_' THEN substr(test,1,6)
    WHEN substr(test,8,1) = '_' THEN substr(test,1,7)
    WHEN substr(test,9,1) = '_' THEN substr(test,1,8)
    WHEN substr(test,10,1) = '_' THEN substr(test,1,9)
    WHEN substr(test,11,1) = '_' THEN substr(test,1,10)
    WHEN substr(test,12,1) = '_' THEN substr(test,1,11)
    WHEN substr(test,13,1) = '_' THEN substr(test,1,12)
    WHEN substr(test,14,1) = '_' THEN substr(test,1,13)
    WHEN substr(test,15,1) = '_' THEN substr(test,1,14)
    WHEN substr(test,16,1) = '_' THEN substr(test,1,15)
    WHEN substr(test,17,1) = '_' THEN substr(test,1,16)
    WHEN substr(test,18,1) = '_' THEN substr(test,1,17)
    --- More as required
    ELSE ''
END AS result
FROM noinstr

然后可以这样调用: -

public String buildCaseClause(String coretable,
                              String corecolumn,
                              String mvcolumn,
                              String separator,
                              String resultcolumn ) {
    long maxstrlen = 0;

    // Get maximun length of Data
    Cursor mv = mDB.query(
            coretable,
            new String[]{"max(length(" + corecolumn + ")) AS " + mvcolumn},
            null,null,null,null,null
    );
    if(mv.moveToFirst()) {
        maxstrlen = mv.getLong(mv.getColumnIndex(mvcolumn));
    }
    mv.close();

    // If max string length is less than 2 then return an empty string
    if (maxstrlen < 1) {
        return "";
    }
    //WHEN substr(test,2,1) = '_' THEN substr(test,1,1)
    StringBuilder rv = new StringBuilder(" CASE");
    for (int i=2;i <= maxstrlen;i++) {
        rv.append(
                " WHEN substr(" +
                        corecolumn+
                        "," + String.valueOf(i) +
                ",1) = '" + separator +
                "' THEN substr(" +
                        corecolumn +
                        ",1," + String.valueOf(i-1) + ")");
    }
    // Add
    rv.append(" ELSE '' END AS " + resultcolumn);
    return rv.toString();
}

本身可以使用: -

public Cursor getSplitDataPart() {
    return mDB.query(TBNOINSTR,
            new String[]{"*",buildCaseClause(TBNOINSTR,COL_TBNOINSTR_DATA,"mv","_", "result")},
            null,null,null,null,null);
}
  • SO48879002DBHlpr是DatabaseHelper(SQLiteOpenHelper的子类)
  • buildCaseClause可以是私有的,但是为了进行测试,它公开了,从而便于使用 SO48879002DBHlpr dbhlpr = new SO48879002DBHlpr(this); // Add some testing data dbhlpr.addData("short_secondpart"); dbhlpr.addData("thisislonger_secondpart"); dbhlpr.addData("thisisanevenlongerfirstdatapart_secondaprt"); // Log the generated SQL that could be incoporated Log.d("SPLIDATASQL",dbhlpr.buildCaseClause(SO48879002DBHlpr.TBNOINSTR,SO48879002DBHlpr.COL_TBNOINSTR_DATA,"mv","_","result")); // Extract the data into a cursor Cursor csr = dbhlpr.getSplitDataPart(); // Log the results while (csr.moveToNext()) { Log.d("DBINFO","Extracted First Datapart is " + csr.getString(csr.getColumnIndex("result"))); } 进行测试。
  • TB_NOINSTR是表名,COl_TBNOINSTR_DATA是共同加入的数据。

在这种情况下,结果日志包括: -

Log.d("SPLIDATASQL",dbhlpr.buildCaseClause(SO48879002DBHlpr.TBNOINSTR,SO48879002DBHlpr.COL_TBNOINSTR_DATA,"mv","_","result"));