How to insert to into many to many relationships. SQLite

But I can`t find the way to get rowIds from each list and product to insert both, idlist and idproduct, into List_Product. Thank you in advance.

asked Aug 2, 2017 at 1:13 310 3 3 gold badges 4 4 silver badges 14 14 bronze badges

Typically you'd only insert when there is a List/product relationship in which case, as you would then know the product and list, you can get the respective id's and then insert the list_product row.

Commented Aug 2, 2017 at 3:28

However, if you wanted every single permutation then you could get the id if you used long > i.e. query will return the id of the inserted row. However, I'd suggest that your test would then not cater for no relationship situations.

Commented Aug 2, 2017 at 3:38 oops sorry you'd use long > not query. Commented Aug 2, 2017 at 3:48

2 Answers 2

The main change to facilitate grabbing the id's would be to swap from using execSQL to using insert as insert returns the id of the inserted row, execsql does not.

However, I'm not sure if you can pass CURRENT_TIMESTAMP via a ContentValues and it would result getting the current timestamp as opposed to just setting the value to the literal CURRENT_TIMESTAMP. You could use DEFAULT CURRENT_TIMEPSTAMP in the respective column definitions (as I have in the code below).

I'd suggest that you would not want a link between every list/product permutation (that would be 100 rows for you 10 List rows and 10 Product rows) as in real life you would probably not have such a scenario rather you'd have some links between the two. So in the code below I've randomly created links.

First some code from the Database Helper (for my convenience named SO45449914) for performing the inserts:-

public long insertListRow(String name, int active) < ContentValues cv = new ContentValues(); cv.put(LISTNAME_COL,name); cv.put(LISTACTIVE_COL,active); cv.put(LISTDEACTIVATIONDATE_COL,""); return this.getWritableDatabase().insert(PRIVATELISTTABLE,null,cv); >public long insertProductRow(String description,int quantity, int active) < ContentValues cv = new ContentValues(); cv.put(PRODUCTDESCRIPTION_COL,description); cv.put(PRODUCTQUANTITY_COL,quantity); cv.put(PRODUCTACTIVE_COL,active); return this.getWritableDatabase().insert(PRIVATEPRODUCTTABLE,null,cv); >public void insertListProductLink(long listid, long productid) < ContentValues cv = new ContentValues(); cv.put(LISTPRODUCTLIST_COL,listid); cv.put(LISTPRODUCTPRODUCT_COL,productid); if (this.getWritableDatabase().insertOrThrow(LISTPRODUCTTABLE,null,cv) <0) < //handle failed insert >> 

Notes - I've used class variables for all columns names. - Columns that have the current time stamp get this via the default, so there is no need to have a cv.put for those columns.

In the activity is the following code :-

 void doSO45449914() < SO45449914 dbhelper = new SO45449914(this); int loopcount = 10; long[] listids = new long[loopcount]; long[] productids = new long [loopcount]; for (int i=0; i < 10; i++) < listids[i] = dbhelper.insertListRow("a" + i,1); productids[i] = dbhelper.insertProductRow("b" + i,3,1); >Cursor csra = dbhelper.getWritableDatabase().query(SO45449914.PRIVATELISTTABLE, null,null,null,null,null,null ); Cursor csrb = dbhelper.getWritableDatabase().query(SO45449914.PRIVATEPRODUCTTABLE, null,null,null,null,null,null ); Log.d("SO45449914","Number of rows in LIST TABLE = " + csra.getCount()); Log.d("SO45449914","Number of rows in PRODUCTS TABLE = " + csrb.getCount()); for (long aid: listids) < Log.d("SO45449914","LIST ID from store = " + Long.toString(aid)); >for (long bid: productids) < Log.d("SO45449914","PRODUCT ID from store = " + Long.toString(bid)); >for (long lid: listids) < for (long prdid: productids) < if ((Math.random() * 100) >60) < dbhelper.insertListProductLink(lid,prdid); Log.d("SO45449914", "Adding link between List id(" + Long.toString(lid) + ") and product id(" + Long.toString(prdid) + ")" ); >> > csra.close(); csrb.close(); > 

Exlapnation

The first few lines prepare long arrays based upon the number of Lists and products to be created (same number of both). Integer loopcount determines how many.

The first loop, inserts Lists and Products which use the insert method storing the returned id in the respective array element.

Two Cursors are then created for obtaining row counts, which are then written to the log. The id's as stored in the arrays are output to the log.

Two nested loops are then invoked with Products being the inner (not that it matters) and randomly (about 40% of the time) a row will be inserted into the link table. I've assumed random but you always easily adjust the algorithm to follow a pattern. It's if ((Math.random() * 100) > 60) < that determines whether or not to insert a link.

The two Cursors are then closed.

Results

Here are screen shots of the resultant tables :-

PrivateList Table

PrivateList Table

PrivateProduct Table

Private Product Table

List_Product Table

enter image description here

. (44 rows in the List_Product table)