আমি কীভাবে আমার অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে দুটি এসকিউএলাইট টেবিলগুলিতে যোগদান করব?


97

পটভূমি

আমার কাছে একটি অ্যান্ড্রয়েড প্রকল্প রয়েছে যার দুটি টেবিল সহ একটি ডাটাবেস রয়েছে: tbl_questionএবং tbl_alternative

প্রশ্নগুলি এবং বিকল্পগুলির সাথে মতামতগুলি পপুলেট করতে আমি কার্সার ব্যবহার করছি। আমি দুটি টেবিলে যোগ দেওয়ার চেষ্টা না করা পর্যন্ত আমার প্রয়োজনীয় ডেটা পেতে কোনও সমস্যা নেই।

    টিবিএল_কোশন  
    -------------
    _আইডি  
    প্রশ্ন  
    বিভাগে  
    টিবিএল_অল্টারনেটিভ
    ---------------
    _আইডি 
    প্রশ্নবিদ্ধ 
    বিভাগে 
    বিকল্প

আমি নিম্নলিখিত মত কিছু চাই:

SELECT tbl_question.question, tbl_alternative.alternative where 
categoryid=tbl_alternative.categoryid AND tbl_question._id = 
tbl_alternative.questionid.` 

এটি আমার চেষ্টা:

public Cursor getAlternative(long categoryid) {
            String[] columns = new String[] { KEY_Q_ID, KEY_IMAGE, KEY_QUESTION, KEY_ALT, KEY_QID};
             String whereClause = KEY_CATEGORYID + "=" + categoryid +" AND "+ KEY_Q_ID +"="+ KEY_QID;
             Cursor cursor = mDb.query(true, DBTABLE_QUESTION + " INNER JOIN "+ DBTABLE_ALTERNATIVE, columns, whereClause, null, null, null, null, null);
             if (cursor != null) {
                  cursor.moveToFirst();
             }
             return cursor;

আমি নিয়মিত এসকিউএল এর চেয়ে আরও শক্তিশালী করে কোয়েরি গঠনের এই উপায়টি খুঁজে পেয়েছি তবে কম ত্রুটির প্রবণ হওয়ায় এইভাবে ব্যবহার করার পরামর্শটি পেয়েছি।

প্রশ্ন

আমি কীভাবে আমার আবেদনে দুটি এসকিউএল টেবিল যোগ দিতে পারি?


আপনি কি ত্রুটি পাচ্ছেন? আপনি কি স্ট্রিং আক্ষরিকের সাথে সংক্ষিপ্ত স্ট্রিং প্রতিস্থাপন করে পরীক্ষার চেষ্টা করেছিলেন? (FWIW, আমি 1986 বা তার থেকে একটি কার্সার ব্যবহার করতে ছিল না কিন্তু আমি Android এর জন্য বিকাশ না।।)
মাইক Sherrill 'বিড়াল রিকল'

কার্সার কোড ব্লকে অভ্যন্তরীণ-যোগ-কলামগুলি কীভাবে নির্দিষ্ট করা হচ্ছে তা আমি দেখতে পাচ্ছি না। এসকিউএল হবে "টি 1 অভ্যন্তর থেকে টি 1 অভ্যন্তর থেকে পছন্দসই-কলস তালিকাটি টি 1.কিটিএসিড = টি 2.কোশনিড এবং টি 1 কোডেরিড = টি 2 ক্যাটোরিডে নির্বাচন করা হবে যেখানে টি 1। ক্যাটাগরিড = {পছন্দসই বিভাগের মান}"
টিম

এটি আমার ত্রুটি: দ্ব্যর্থক কলামের নাম: _ আইডি:, সংকলনের সময়: নির্বাচন নির্ধারণ _id, চিত্র, প্রশ্ন, বিকল্প, প্রশ্নোত্তর থেকে tbl_qution INNER যোগদান করুন tbl_al متبادل যেখানে বিভাগে = 2 এবং _আইডি = প্রশ্নবিদ্ধ। সুতরাং আমি ধরে নিলাম যে আমাকে tbl_question._id = tbl_al متبادل.questionid নির্দিষ্ট করতে হবে, তবে আমি উপরে যেভাবে জিজ্ঞাসা-পদ্ধতি ব্যবহার করব তা কীভাবে করব তা আমি জানি না। এবং আমি কীভাবে ফিরে আসব জানি না যদি আমি "নিয়মিত" স্কুয়েল-সিনট্যাক্স ব্যবহার করি: tbl_question থেকে "নির্বাচন করুন 'INNER যোগ দিন tbl_question._id = tbl_al متبادل.questionid এবং tbl_question.categoryid = tbl_al متبادل.cवेशoryid = বিভাগ;
কাক্কা 47

@ টিম: আপনি যেভাবে এটি করেন, আমি ডিবি-সহায়ক শ্রেণিতে কীভাবে পদ্ধতিটি তৈরি করব? আমি কি কার্সার ফিরিয়ে দেব না? আমি যেতে যেতে শিখছি, যে কোনও পরামর্শ যা আমার কোডকে আরও ভাল করে তোলে আমি তার জন্য কৃতজ্ঞ!
kakka47

এখানে আমি উত্তর পোস্ট করেছি স্ট্যাকওভারফ্লো.com
সাগর

উত্তর:


206

আপনার RawQuery প্রয়োজন পদ্ধতি ।

উদাহরণ:

private final String MY_QUERY = "SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.other_id WHERE b.property_id=?";

db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)});

ব্যবহার করবেন? কাঁচা এসকিউএল কোয়েরিতে মান রাখার পরিবর্তে বাঁধাই।


4
@ এনক্রোমেন্সার কীভাবে আপনি এর VIEWচেয়ে ভাল একটি বিকল্প তৈরি করতে দেখেন rawQuery?
মুহাম্মদ বাবর

কোয়েরির পরে কী করা উচিত? কোন আইডি কোন টেবিলের অন্তর্ভুক্ত তা আপনি কীভাবে জানবেন, এবং যদি উভয় টেবিলের কোনও কোনও কলামের জন্য একই কলামের নাম থাকে? বা যদি দ্বিতীয় টেবিলে একাধিক আইটেম থাকে?
অ্যান্ড্রয়েড বিকাশকারী 23

@ অ্যান্ড্রয়েড-বিকাশকারী "ক্যোয়ারির পরে কী করা উচিত?" - আপনি একটি কার্সার পান, ডেটা দিয়ে যা চান তা করুন: পি; ২. "আপনি কীভাবে জানবেন কোন আইডি ..." - এটি একটি যোগদান, সুতরাং কোন প্রকারের উপর নির্ভর করে আপনি সর্বদা, কখনও না, বা পপুলেটেড কীগুলি পেতে পারেন; 3. "... কিছু কলামের জন্য একই কলামের নাম" - ঘটতে পারে তবে অস্পষ্টতা সরানো যেতে পারে। সত্যিকার অর্থে আমি জানি না যে আপনি "টেবিল.কমলন" দিয়ে গেটক্লাম ইন্ডেক্স ব্যবহার করে আনতে পারেন, আপনি সর্বদা সূচিটি ম্যানুয়ালি গণনা করতে পারেন, কেবল এটি ডিবাগ-টেস্ট করুন; ৪. "দ্বিতীয় টেবিলের জন্য একাধিক আইটেম" যোগদানের ধরণের উপরও নির্ভর করে।
leRobot

ভিউ ধরে নেওয়া 1-থেকে-বহু সম্পর্কের সম্পূর্ণ আউট জয়েন (যেমন RawContactsEntity ), আপনি "অনেকগুলি" টেবিলে নাল KEY সহ সারি পেতে পারেন, তবে কখনও "1" টেবিলের উপরে পাবেন না যাতে আপনার কার্সার পাসটি শাখা করা উচিত লাইক যেমন: যদিও (কার্সার.মোভটো নেক্সট () {যদি (কার্সার.জেটভ্যালু (getManyTableKeyIndex ()) == NULL) {/ * এটি কোনও সম্পর্ক নেই, কেবল "1" টেবিলের ডাটা /} অন্য {/ এটি রয়েছে একটি সম্পর্ক এইচআইটি, সুতরাং উভয় টেবিলের তথ্য রয়েছে * /}} কার্সার.ক্লস ();
ররোট

আমি "পিতামহিত অনেকগুলি" সারিগুলির জন্য অন্য একটি শাখা যুক্ত করতে ভুলে গেছি যা আপনি এখনও পুরো আউটয়ার জয়েনের সাথে পেতে পারেন, তবে সম্পর্কটি কঠোর হলে সাধারণত তা হবে না (অ্যান্ড্রয়েড সম্পর্ক প্রয়োগ করে কিনা আমি নিশ্চিত নই)) কীভাবে অস্পষ্ট কলামগুলি পেতে হয় তা সত্যই জানেন না, তবে আপনি কলামের অস্পষ্টতার সাথে একটি ভিউ ঘোষণা করে যে কোনও এসকিউএলটি সিএলআইতে এটি পরীক্ষা করে দেখতে পারেন এবং এই কলামগুলি "SELECT * FROM view_x" কোয়েরিতে কী নাম পেয়েছে তা দেখুন। তারপরে আপনি যা চান অ্যান্ড্রয়েড সহায়ক ফ্লেভারটি যা চান তা প্রয়োগ করুন (। ক্যুরি () / .আরউকিউয়ারি () ...)
ররবট

20

একটি বিকল্প উপায় হল এমন একটি ভিউ নির্মাণ করা যা পরে টেবিলের মতো অনুসন্ধান করা হয়। অনেক ডেটাবেস ম্যানেজারে একটি ভিউ ব্যবহার করে আরও ভাল পারফরম্যান্স হতে পারে।

CREATE VIEW xyz SELECT q.question, a.alternative  
   FROM tbl_question AS q, tbl_alternative AS a
  WHERE q.categoryid = a.categoryid 
    AND q._id = a.questionid;

এটি মেমরি থেকে তাই কিছু সিনট্যাকটিক সমস্যা থাকতে পারে। http://www.sqlite.org/lang_createview.html

আমি এই পদ্ধতির কথা উল্লেখ করেছি কারণ আপনি যদি পছন্দ করেন যে এটি পছন্দ হয়েছে তখন আপনি সেই ভিউটি সহ এসকিউএলকিউকিউবার্ডার ব্যবহার করতে পারেন।


4
আরডিবিএমএসের মতো ওরাকলের মতো এটি যখন আসে তখন ভিউগুলি আপনাকে কিছু পারফরম্যান্স লাভ করতে পারে তবে আমার অভিজ্ঞতায়, কেবলমাত্র পারফরম্যান্স বা রিপোর্টিংয়ের উদ্দেশ্যে যখন প্রয়োজন হয় তখন তা ব্যবহার করা হয়। অথবা এটি অন্যভাবে বলতে গেলে, আপনি ব্যবহার করেন এমন প্রতিটি যোগদানের ক্যোয়ারির জন্য আপনি কোনও দর্শন তৈরি করেন না। এবং বিশেষত এসকিউএলাইটে, আমি বিশ্বাস করি না যে কোনও কার্যকারিতা লাভ রয়েছে - এই প্রশ্নের উত্তর অনুসারে, এসকিউএলাইট একটি সাবকিউরিটি ব্যবহার করে ক্যোয়ারীটিকে পুনরায় লিখেছেন। stackoverflow.com/questions/25577407/performance-penalty- for-unused-view#25580319 অ্যান্ড্রয়েডের এপিআই ওপি কী করছে তার জন্য সীমাবদ্ধ হতে পারে তবে rawQuery()এটি সঠিক উত্তর।
spaaarky21

13

@ পাওয়েলজিবার জবাব ছাড়াও, যা দুটি টেবিলের সাথে যোগ দিতে অবশ্যই স্পষ্টভাবে সঠিক, আপনি যখন এর INNER JOINমতো ব্যবহার করতে পারেন

SELECT * FROM expense INNER JOIN refuel
ON exp_id = expense_id
WHERE refuel_id = 1

এটির মতো কাঁচা ক্যোয়ারির মাধ্যমে -

String rawQuery = "SELECT * FROM " + RefuelTable.TABLE_NAME + " INNER JOIN " + ExpenseTable.TABLE_NAME
        + " ON " + RefuelTable.EXP_ID + " = " + ExpenseTable.ID
        + " WHERE " + RefuelTable.ID + " = " +  id;
Cursor c = db.rawQuery(
        rawQuery,
        null
);

এসকিউএলাইটের অনুসন্ধানের আদিম উপায়ের পশ্চাদপটে সামঞ্জস্যপূর্ণ সমর্থনের কারণে আমরা সেই আদেশটি এটিতে পরিণত করি -

SELECT *
FROM expense, refuel
WHERE exp_id = expense_id AND refuel_id = 1

এবং তাই এসকিউএলডিড ডাটাবেস.কোয়ারী () সহায়তাকারী পদ্ধতিটি গ্রহণ করতে সক্ষম হবেন

Cursor c = db.query(
        RefuelTable.TABLE_NAME + " , " + ExpenseTable.TABLE_NAME,
        Utils.concat(RefuelTable.PROJECTION, ExpenseTable.PROJECTION),
        RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " AND " + RefuelTable.ID + " = " +  id,
        null,
        null,
        null,
        null
);

বিস্তারিত ব্লগ পোস্টের জন্য এই http://blog.championswimmer.in/2015/12/doing-a-table-join-in-android-without-used-rawquery দেখুন


4
ইউটিসকনক্যাটটি কোথা থেকে এসেছে তা আমি বুঝতে পারি না।
নিকোকিজিও

4
এটি একটি ভাল পদ্ধতির তবে কোনও টেবিলের কোনও কলামের নাম অন্য টেবিলের কলামের নামের মতো হলে কাজ করবে না। উভয় টেবিলের মতো যদি আইডির কলাম থাকে তবে এটি নিক্ষেপ করবেandroid.database.sqlite.SQLiteException: ambiguous column name
অনুপ শর্মা

8

"দ্ব্যর্থহীন কলাম" এর অর্থ হ'ল একই কলামের নামটি কমপক্ষে দুটি সারণিতে প্রদর্শিত হয়; আপনি কোনটি চান তা ডাটাবেস ইঞ্জিন বলতে পারে না। অস্পষ্টতা অপসারণ করতে পুরো টেবিলের নাম বা টেবিলের নাম ব্যবহার করুন।

এখানে আমার সম্পাদকের মধ্যে একটি উদাহরণ রয়েছে। এটি অন্য কারও সমস্যা থেকে এসেছে তবে তা যেকোনভাবেই বোঝা উচিত।

select P.* 
from product_has_image P
inner join highest_priority_images H 
        on (H.id_product = P.id_product and H.priority = p.priority)

হ্যাঁ, আমার সন্দেহ হয়েছিল। তবে উপায়টি থেকে আমি কীভাবে সারণিগুলি নির্দিষ্ট করতে পারি তা জানতাম না: DBTABLE_QUESTION.KEY_QUESTION, কাজ করেনি। তবে আমি যখন কাঁচাওয়ালা পদ্ধতি ব্যবহার করি তখন কোন টেবিলটি কোন টেবিলের অন্তর্ভুক্ত তা নির্ধারণ করা সহজ হয়েছিল।
কাক্কা 47
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.