Android SQLite mit db.query () für JOIN anstelle von rawquery ()

Ich habe tableA, tableB und tableC Tabelle A und tableB werden durch tableA.Id (PK) = tableB.tableAId (FK) Tabelle B und tableC verbunden durch tableB.Id (PK) = tableC.tableBId (FK)

Ich möchte das tun können:

SELECT c.ALL from tableC c INNER JOIN tableB b on c.tableBId = b.Id INNER JOIN tableA a on b.tableAId = a.Id WHERE a.Id = 108 

Ich habe eine Menge von Posts im Web gefunden, die db.rawquery () verwendet, um diese Abfrage zu implementieren. Allerdings habe ich auch gehört, dass rawquery () ist weniger sicher als query (). Um die beste Praxis als Anfänger zu suchen, ist meine Frage:

Gibt es eine Möglichkeit, diese Abfrage mit db.query () anstelle von db.rawquery () zu implementieren?

Danke im Voraus.

  • Freigeben und Beibehalten von Daten zwischen mehreren Android-Anwendungen
  • Android sqlite: Fehler beim Ändern des Gebietsschemas für db zu 'zh_CN'
  • GreenDAO erstellt eine automatische ID-Eigenschaft
  • Sqlite: sieht aus wie moveToNext funktioniert ohne moveToFirst benötigt
  • SQLite triggert in Android?
  • SQLiteStatement führt ein SELECT / INSERT / DELETE / UPDATE aus
  • SQLite, wie bekomme ich alle Tabellennamen in der Datenbank?
  • SQLite: Kann Argument nicht bei Index 1 binden, da der Index außerhalb des Bereichs liegt. Die Anweisung hat 0 Parameter
  • 5 Solutions collect form web for “Android SQLite mit db.query () für JOIN anstelle von rawquery ()”

    Gibt es eine Möglichkeit, diese Abfrage mit db.query () anstelle von db.rawquery () zu implementieren?

    So lohnt es sich zu sagen, dass rawQuery () einen Trick macht. Aber auch ein anderer Ansatz.

    Die Methode query () ist für die Durchführung von Abfragen über eine Tabelle ausgelegt. Aber der beste Weg, wie man Tabellen in SQLite verwenden, ist die Verwendung von SQLiteQueryBuilder und mit setTables () -Methode, die Sie beitreten können.

    Daher empfehle ich Ihnen, erwähnt SQLiteQueryBuilder verwenden . Aber es ist wenig komplizierter gegen rawQuery () -Methode, wo man nur rohe Aussage zuweisen muss.

    Wenn Sie nicht wissen, wie Sie anfangen, überprüfen Sie dieses Beispiel:

    • Wie benutzt man einen Join mit SQLite

    Hinweis:

    Ist die Tatsache, dass rawQuery() weniger sicher ist als query() weil query() -Methode vorkompilierte Anweisungen verwendet, die sicherer als "raw" -Anweisungen sind. Aber immer können Sie (sollten) Platzhalter verwenden, die die Sicherheit der Aussage als Hauptschutz gegen SQL Injektionen deutlich erhöhen und die Aussage auch viel menschlich besser lesbar wird.

    Das ist irgendwie spät, aber ich dachte anderen, wer sucht das könnte davon profitieren:

    db.query() Methode nativ unterstützt LEFT OUTER JOIN UND INNER JOIN über seine table Argument, so dass Sie nicht wirklich brauchen, um SQLiteQueryBuilder , um das zu erreichen. Auch ist es einfacher und schon ziemlich einfach.

    Diese Methode ist weit verbreitet in Google I / O 2015 Schedule App Quellcode verwendet .

    Ein kurzes Beispiel (String-Konstanten für Kürze ausgelassen):

     Cursor cursor = db.query(NoteContract.Note.TABLE_NAME + " LEFT OUTER JOIN authors ON notes._id=authors.note_id", projection, selection, selectionArgs, null, null, "notes._id"); 

    Der Schlüssel ist im ersten Argument zu db.query() .

    Derzeit werden nur LEFT OUTER JOIN und INNER JOIN unterstützt, was für die meisten Apps ausreichend ist.

    Ich hoffe, diese Antwort hilft anderen, die das suchen.

    Ja, Sie können Abfrage () anstelle von rawQuery () verwenden, bei einer einzigen Annahme – es gibt keine zwei gleichen Spaltennamen in den Tabellen, die Sie beitreten.

    Wenn diese Kriterien erfüllt sind, können Sie diese Antwort https://stackoverflow.com/a/34688420/3529903 verwenden

    Wie nach SharpEdges Kommentar und nach einem komplexeren Beispiel auf der Grundlage von Nimrod Dayans Antwort, hier ist ein komplexeres Beispiel.

    4 Joins verwendet werden, wird auch eine generierte Spalte verwendet. Es verwendet einen Ausdruck (subtrahiert Zeitstempel) und verwendet dann das in der WHERE-Klausel.

    Grundsätzlich ist die Methode, die Join-Klauseln an den Tabellennamen-String anzuhängen (SQLite verschiebt dies dann für Sie nach den Spalten).

    DBConstants.SQL????? DBConstants.SQLISNOTNULL auf das jeweilige SQL aufgelöst, zB DBConstants.SQLISNOTNULL beschließt IS NOT NULL

    DBConstans.CALCULATED????? Sind Namen für berechnete Spalten.

    DB????TableConstants.????_COL auf DB????TableConstants.????_COL auflöst ( .._FULL auf table.colull z. B. um zweideutige _ID-Spalten zu vermeiden).

    Die Methode ( getToolRules ) lautet wie folgt: –

     public Cursor getToolRules(boolean rulesexist, int minimumruleperiodindays, int minimumbuycount) { String columns[] = new String[] { "0 " + DBConstants.SQLAS + DBConstants.STD_ID, DBProductusageTableConstants.PRODUCTUSAGE_PRODUCTREF_COL, DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL, DBProductusageTableConstants.PRODUCTUSAGE_COST_COL, DBProductusageTableConstants.PRODUCTUSAGE_BUYCOUNT_COL, DBProductusageTableConstants.PRODUCTUSAGE_FIRSTBUYDATE_COL, DBProductusageTableConstants.PRODUCTUSAGE_LATESTBUYDATE_COL, DBProductusageTableConstants.PRODUCTUSAGE_ORDER_COL, DBProductusageTableConstants.PRODUCTUSAGE_RULESUGGESTFLAG_COL, DBProductusageTableConstants.PRODUCTUSAGE_CHECKLISTFLAG_COL, DBProductusageTableConstants.PRODUCTUSAGE_CHECKLISTCOUNT_COL, "(" + DBProductusageTableConstants.PRODUCTUSAGE_LATESTBUYDATE_COL + "- " + DBProductusageTableConstants.PRODUCTUSAGE_FIRSTBUYDATE_COL + " / (86400000)" + ") " + DBConstants.SQLAS + DBConstants.CALCULATED_RULEPERIODINDAYS, DBProductsTableConstants.PRODUCTS_NAME_COL, DBAislesTableConstants.AISLES_NAME_COL, DBAislesTableConstants.AISLES_ORDER_COL, DBAislesTableConstants.AISLES_SHOPREF_COL, DBShopsTableConstants.SHOPS_NAME_COL, DBShopsTableConstants.SHOPS_CITY_COL, DBShopsTableConstants.SHOPS_ORDER_COL, DBRulesTableConstants.RULES_ID_COL_FULL + DBConstants.SQLAS + DBRulesTableConstants.RULES_ALTID_COL, DBRulesTableConstants.RULES_AISLEREF_COL, DBRulesTableConstants.RULES_PRODUCTREF_COL, DBRulesTableConstants.RULES_NAME_COL, DBRulesTableConstants.RULES_USES_COL, DBRulesTableConstants.RULES_PROMPT_COL, DBRulesTableConstants.RULES_ACTON_COL, DBRulesTableConstants.RULES_PERIOD_COL, DBRulesTableConstants.RULES_MULTIPLIER_COL }; String joinclauses = DBConstants.SQLLEFTJOIN + DBProductsTableConstants.PRODUCTS_TABLE + DBConstants.SQLON + DBProductusageTableConstants.PRODUCTUSAGE_PRODUCTREF_COL + " = " + DBProductsTableConstants.PRODUCTS_ID_COL_FULL + " " + DBConstants.SQLLEFTJOIN + DBAislesTableConstants.AISLES_TABLE + DBConstants.SQLON + DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL + " = " + DBAislesTableConstants.AISLES_ID_COL_FULL + DBConstants.SQLLEFTJOIN + DBShopsTableConstants.SHOPS_TABLE + DBConstants.SQLON + DBAislesTableConstants.AISLES_SHOPREF_COL + " = " + DBShopsTableConstants.SHOPS_ID_COL_FULL + DBConstants.SQLLEFTJOIN + DBRulesTableConstants.RULES_TABLE + DBConstants.SQLON + DBProductusageTableConstants.PRODUCTUSAGE_PRODUCTREF_COL + " = " + DBRulesTableConstants.RULES_PRODUCTREF_COL + DBConstants.SQLAND + DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL + " = " + DBRulesTableConstants.RULES_AISLEREF_COL ; String ruleexistoption = DBRulesTableConstants.RULES_ID_COL_FULL; if (rulesexist) { ruleexistoption = ruleexistoption + DBConstants.SQLISNOTNULL; } else { ruleexistoption = ruleexistoption + DBConstants.SQLISNULL; } String whereclause = DBProductusageTableConstants.PRODUCTUSAGE_BUYCOUNT_COL + " = ?" + DBConstants.SQLAND + ruleexistoption + DBConstants.SQLAND + "(" + DBConstants.CALCULATED_RULEPERIODINDAYS + " / ?) > 0" + DBConstants.SQLAND + DBProductusageTableConstants.PRODUCTUSAGE_BUYCOUNT_COL + " > ?"; if (minimumbuycount > 0) { --minimumbuycount; } String[] whereargs = new String[] { "0", Integer.toString(minimumruleperiodindays), Integer.toString(minimumbuycount) }; return db.query(DBProductusageTableConstants.PRODUCTUSAGE_TABLE + joinclauses, columns,whereclause,whereargs,null,null,null); } 

    Die Basis SQL, die in SQLite Manager erstellt wurde, wurde als Leitfaden für den Aufbau der Methode (sieht viel schöner, IMHO, als die SQL aus dem Cursor in Debugon extrahiert) ist: –

    Hinweis! 0 AS _ID wird verwendet, um den Cursor von einem CursorAdapter (dh CursorAdapter benötigen eine Spalte mit dem Namen _ID)

     SELECT 0 AS _id, productusage.productusageproductref, productusage.productusageaisleref, productusage.productusageorder, productusage.productusagecost, productusage.productusagebuycount, productusage.productusagefirstbuydate, productusage.productusagelatestbuydate, productusage.productusagerulesuggestflag, productusage.productusagechecklistflag, productusage.productusagechecklistcount, /********************************************************************************************************************************* Calculate the period in days from between the firstbuydate and the latestbuydate *********************************************************************************************************************************/ (productusagelatestbuydate - productusagefirstbuydate) / (1000 * 60 * 60 * 24) AS periodindays, products.productname, aisles.aislename, aisles.aisleorder, aisles.aisleshopref, shops.shopname, shops.shopcity, shops.shoporder, rules._id AS rule_id, rules.rulename, rules.ruleuses, rules.ruleprompt, rules.ruleacton, rules.ruleperiod, rules.rulemultiplier FROM productusage LEFT JOIN products ON productusageproductref = products._id LEFT JOIN aisles ON productusageaisleref = aisles._id LEFT JOIN shops ON aisles.aisleshopref = shops._id LEFT JOIN rules ON productusageaisleref = rules.ruleaisleref AND productusageproductref = rules.ruleproductref WHERE productusagebuycount > 0 AND rules._id IS NULL AND (periodindays / 2) > 0 AND productusage.productusagebuycount > 0 
     public HashMap<String, String> get_update_invoice_getdata(String gen) { // TODO Auto-generated method stub HashMap<String, String> wordList; wordList = new HashMap<String, String>(); Cursor cur_1 = ourDataBase .rawQuery( "SELECT * FROM Invoice i JOIN Client c ON i.Client_id=c.Client_id JOIN TAX t ON i.Tax_id=t.Tax_id JOIN Task it ON i.Task_id=it.Task_id WHERE i.Inv_no=?", new String[] { gen }); int intext = cur_1.getColumnIndex(C_ORG_NAME); int intext5 = cur_1.getColumnIndex(TA_NAME); int intext6 = cur_1.getColumnIndex(TA_RATE); int intext7 = cur_1.getColumnIndex(TA_QTY); int intext8 = cur_1.getColumnIndex(TA_TOTAL); if (cur_1.moveToFirst()) { do { wordList.put("Org_name", cur_1.getString(intext)); wordList.put("client_id", cur_1.getString(2)); wordList.put("po_number", cur_1.getString(4)); wordList.put("date", cur_1.getString(3)); wordList.put("dis_per", cur_1.getString(7)); wordList.put("item_name", cur_1.getString(intext5)); wordList.put("item_rate", cur_1.getString(intext6)); wordList.put("item_cost", cur_1.getString(intext7)); wordList.put("item_total", cur_1.getString(intext8)); } while (cur_1.moveToNext()); } return wordList; } 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.