با سلام
من با آموزش های موجود در سایت موفق به ساخت یک پایگاه داده با فرمت .sql و ساختار زیر شدم:
کد پیاچپی:
DROP TABLE IF EXISTS "database-name";
CREATE TABLE "database-name" ("name" ,"city" );
INSERT INTO "database-name" VALUES('name,'city');
INSERT INTO "database-name" VALUES('alireza',' #Tehran');
حال اگر بخواهم که مقدار alireza را در پایگاه داده جستجو کنم و مقدار ستون city مرتبط با آن یعنی #Tehran را نمایش دهم (تبدیل به یک String شود) از چه کدی باید استفاده کنم؟ و اینکه پایگاه داده را چگونه باید از پوشه ی assets فراخوانی کرد و حتما نیاز است که پایگاه داده در حافظهی داخلی یا خارجی گوشی کپی شود؟
سلام.
سیستم عامل اندروید این اجازه را به ما نمی دهد که با کدنویسی، کلیه فایل ها و پوشه های زیرمجموعه فایل apk مربوط به برنامه اندروید را تغییر بدهیم (حداقل تا به امروز چنین استانداردی را داشته است). پس اگر قرار است که فایلی داشته باشیم که نیاز به تغییر دادن آن است، باید آن را در حافظه داخلی یا حافظه خارجی کپی کنیم و بعد با بعد نسخه کپی شده را تغییر داده و با آن کار کنیم.
در مورد خواندن از پایگاه داده، باید از کلمه SELECT استفاده شود. اگر بخواهیم که ردیف هایی برگردانده شوند که یک ستون آنها، برابر مقداری خاص است، باید کلمه WHERE را هم به کار ببریم. به عنوان مثال (تنها query را ذکر میکنم) :
کد پیاچپی:
SELECT * FROM myTable WHERE myColumn = myValue;
myTable برابر نام جدول، myColumn برابر نام ستون و myValue برابر همان مقداری است که می خواهیم مقدار ستون همانند آن باشد (دقیقا مثل آن، اگر بخواهیم حاوی آن باشد، باید کلمه LIKE را به کار ببریم، البته با ساختاری متفاوت که مثال هایی از آن در انجمن کلیدستان موجود است).
دقت شود که اگر مقدار myValue از جنس عدد باشد (یعنی نوع ستون آن را از جنس عدد انتخاب کرده باشیم)، خود عدد نوشته می شود :
کد پیاچپی:
SELECT * FROM sqlite_master WHERE type = 7;
ولی اگر ستون از جنس متن (کاراکتر) باشد، باید دو علامت ' در دو طرف مقدار بنویسیم، مثل این کد (query) :
کد پیاچپی:
SELECT * FROM sqlite_master WHERE type = 'name';
در صورتی که تنها لازم باشد اطلاعات از پایگاه داده خوانده شود و قصد تغییری در آن نداشته باشم، باز هم باید در حافظه گوشی کپی شود؟
همچنین میشود در مورد متد openOrCreateDatabase برای باز کردن پایگاه داده توضیح دهید؟ من کدی به شکل زیر در کلاس TestCase قرار دادم که Eclipse از آن خطا گرفت:
کد پیاچپی:
SQLiteDatabase db = openOrCreateDatabase(DB_NAME, context.MODE_PRIVATE,null);
و در این دستور چگونه میتوان مکان ذخیره شده پایگاه داده را مشخص کرد؟
ببخشید سوال هام زیاد شد.
میشه خطایی که گرفته رو بفرستید؟
دوست عزیز این متد میاد میبینه اگر دیتابیس با همچین ادرس و نامی وجود نداشت میسازه ..اگر هم وجود داشت فقط بازش میکنه...که 3 آرگومان این متد میگیره..
اولیش Path که آدرس دیتابیس هست..
دومیش: MODE_PRIVATE یعنی این دیتابیس فقط به صورت خصوصی توسط اپلیکیشن شما استفاده میشه و اپلیکیشنهای دیگه نمیتونند ازش استفاده کنند..
سومیش هم شما کرسر فکتوری که لازم نیست شما تغییرش دهید و همیشه null بزارید..
درمورده سوال دوم که چگونه آدرس بدید..بستگی داره دیتابیس کجا ذخیره کرده باشید..
مثلا فرض کنید میخوای داخل فولدر example , دیتابیس خودت با نام my_dp ذخیره کردید.
ابتدا کافیه یک رشته بنام path تعریف کنید
کد پیاچپی:
String path = Environment.getExternalStorageDirectory() + "/example" + "/" + "my_db";
حالا کافیه این متغییر رو جای آرگومان اول متد openOrCreateDatabase کنید...
بسته به کاراپلیکیشن متفاوت است که ازچه روشی استفاده کنید..به نظر من یکی از بهترین روشها اینه که شما اول دیتابیس از قبل بسازید و داخل فولدر assets/ قراردهید
بعدش وقتی اپلیکیشن برای اولین بار اجرا میشود .دیتابیس کپی کنید توی حافظه و بعد برای اجراهای بعدی فقط فراخوانیش کنید..بعد با آدرسی که دیتابیس رو ذخیره کردید میتونید insert یا هرکار دیگه ای که میخواید روی دیتبایس انجام دهید...
(۱۳۹۴/۰۱/۰۹, ۰۷:۱۹ ب.ظ)'داش بهروز' نوشته: [ -> ]میشه خطایی که گرفته رو بفرستید؟
این خطا نمایش داده میشود: The method openOrCreateDatabase(String, int, null) is undefined for the type mainclass
با تشکر از پاسختان
خوب دوست عزیز این کلاس از اکتیویتی ارث بری نکرده درست؟..اگه اینجوری هست..میتونید کلاستون ارث بری کنید از
این ارور میگه در این فضا همچین متدی رو نمیشناسه
من سعی دارم با استفاده از کد زیر که در یک کلاس از گسترش BaseAdapter قرار دارد، پایگاه دادهای را کپی و مقدار myValue را در آن جستجو کنم و معادل آن را از پایگاه داده در رشتهی ID ذخیره کنم. (مقدار myValue برای هر آیتم لیست متغییر است اما در اینجا برای نمایش دادن کد مقداری ثابت آوردهام و پایگاه داده myTable در مسیر /data/data/com.test.database/databases/ کپی میشود ):
کد پیاچپی:
SQLiteDatabase database;
database db = new database(context);
SharedPreferences shared =this.context.getSharedPreferences("Prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = shared.edit();
boolean isFirstRun = shared.getBoolean("FIRSTRUN", true);
if (isFirstRun){
try
{
db.createDataBase();
}
catch (IOException io)
{
throw new Error("Unable to create database");
}
editor.putBoolean("FIRSTRUN", false);
editor.commit();
}
String myValue = "Reza";
database = db.getReadableDatabase();
String selectQuery = "SELECT * FROM mytable WHERE myColumn = ' " + myValue+"'";
Cursor cursor = database.rawQuery(selectQuery, null);
cursor.moveToFirst();
String ID = cursor.getString(0);
اما کد بالا تنها قادر به کپی کردن پایگاه داده در اولین اجرا است و بعد از آن برنامه بسته می شود و خطای زیر در لاگ نمایش داده میشود:
کد پیاچپی:
04-01 13:22:55.168: W/ActivityThread(12251): Application com.test.database can be debugged on port 8100...
04-01 13:22:55.178: W/ResourceType(12251): CREATING STRING CACHE OF 44 bytes
04-01 13:22:55.208: I/WifiManager(12251): Process dle.wifiscanner requested a scan
04-01 13:22:55.268: E/SQLiteLog(12251): (26) file is encrypted or is not a database
04-01 13:22:55.268: E/DefaultDatabaseErrorHandler(12251): Corruption reported by sqlite on database: /data/data/com.test.database/databases/mytable.db
04-01 13:22:55.268: E/DefaultDatabaseErrorHandler(12251): deleting the database file: /data/data/com.test.database/databases/mytable.db
04-01 13:22:55.388: E/SQLiteLog(12251): (1) no such table: oui
04-01 13:22:55.398: D/AndroidRuntime(12251): Shutting down VM
04-01 13:22:55.398: W/dalvikvm(12251): threadid=1: thread exiting with uncaught exception (group=0x415cfd88)
04-01 13:22:55.398: E/AndroidRuntime(12251): FATAL EXCEPTION: main
04-01 13:22:55.398: E/AndroidRuntime(12251): Process: com.test.database, PID: 12251
04-01 13:22:55.398: E/AndroidRuntime(12251): android.database.sqlite.SQLiteException: no such table: oui (code 1): , while compiling: SELECT * FROM myTable WHERE myColumn = 'Reza'
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteProgram.<init>cryingSQLiteProgram.java:58)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteQuery.<init>cryingSQLiteQuery.java:37)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-01 13:22:55.398: E/AndroidRuntime(12251): at com.test.database.ScanResultsAdapter.getView(ScanResultsAdapter.java:84)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.AbsListView.obtainView(AbsListView.java:2255)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.ListView.onMeasure(ListView.java:1175)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.View.measure(View.java:16628)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.View.measure(View.java:16628)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.View.measure(View.java:16628)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-01 13:22:55.398: E/AndroidRuntime(12251): at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.View.measure(View.java:16628)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
04-01 13:22:55.398: E/AndroidRuntime(12251): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2298)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.View.measure(View.java:16628)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5622)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.Choreographer.doCallbacks(Choreographer.java:574)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.Choreographer.doFrame(Choreographer.java:544)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.os.Handler.handleCallback(Handler.java:733)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.os.Handler.dispatchMessage(Handler.java:95)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.os.Looper.loop(Looper.java:212)
04-01 13:22:55.398: E/AndroidRuntime(12251): at android.app.ActivityThread.main(ActivityThread.java:5135)
04-01 13:22:55.398: E/AndroidRuntime(12251): at java.lang.reflect.Method.invokeNative(Native Method)
04-01 13:22:55.398: E/AndroidRuntime(12251): at java.lang.reflect.Method.invoke(Method.java:515)
04-01 13:22:55.398: E/AndroidRuntime(12251): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
04-01 13:22:55.398: E/AndroidRuntime(12251): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
04-01 13:22:55.398: E/AndroidRuntime(12251): at dalvik.system.NativeStart.main(Native Method)
من کد را به شکل زیر تغییر دادم اما همچنان برنامه بعد از باز شدن سریعاً بسته میشود:
در داخل کلاس SQLiteOpenHelper توابع زیر را قرار دادم:
کد پیاچپی:
public String getdata(String str) {
String selectQuery = "SELECT * FROM mytable WHERE myColumn = ' " +str+"'";
Cursor c = myDataBase.rawQuery(selectQuery, null);
if (c != null) {
c.moveToFirst();
}
return str=c.getString(0);
}
public void openDataBase() throws SQLException{
//Open the database
myDataBase = this.getReadableDatabase();
}
سپس در کلاس baseadapter کد زیر را قرار دادم:
کد پیاچپی:
database db = new database(context);
db.openDataBase();
String str2 = db.getdata("Reza");
اما این بار لاگ ها به شکل زیر تغییر کرد:
کد پیاچپی:
04-03 12:25:09.501: E/AndroidRuntime(28272): android.database.sqlite.SQLiteException: no such table: mytable (code 1): , while compiling: SELECT * FROM mytable WHERE myColumn = 'Reza'
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.neoriddle.wifiscanner.database.getdata(database.java:144)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.neoriddle.wifiscanner.ScanResultsAdapter.getView(ScanResultsAdapter.java:83)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.AbsListView.obtainView(AbsListView.java:2255)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.ListView.onMeasure(ListView.java:1175)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.View.measure(View.java:16628)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.View.measure(View.java:16628)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.View.measure(View.java:16628)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.View.measure(View.java:16628)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2298)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.View.measure(View.java:16628)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5622)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.Choreographer.doCallbacks(Choreographer.java:574)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.Choreographer.doFrame(Choreographer.java:544)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.os.Handler.handleCallback(Handler.java:733)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.os.Handler.dispatchMessage(Handler.java:95)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.os.Looper.loop(Looper.java:212)
04-03 12:25:09.501: E/AndroidRuntime(28272): at android.app.ActivityThread.main(ActivityThread.java:5135)
04-03 12:25:09.501: E/AndroidRuntime(28272): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 12:25:09.501: E/AndroidRuntime(28272): at java.lang.reflect.Method.invoke(Method.java:515)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
04-03 12:25:09.501: E/AndroidRuntime(28272): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
04-03 12:25:09.501: E/AndroidRuntime(28272): at dalvik.system.NativeStart.main(Native Method)