Как сделать базу данных для андроид

Использование простой базы данных SQLite в Android-приложении

В этом руководстве я подробно расскажу о том, как использовать базу данных Android SQLite .

Что такое SQLite

SQLite — это система управления реляционными базами данных, похожая на Oracle , MySQL , PostgreSQL и SQL Server . Она реализует большую часть стандарта SQL , но в отличие от четырех упомянутых выше СУБД она не поддерживает модель « клиент-сервер ». Скорее, она встроена в конечную программу. Это означает, что можно связать базу данных SQLite с приложением и получить доступ ко всем возможностям БД в своем приложении.

Данная СУБД совместима как с Android , так и с iOS , и каждое приложение может создавать и использовать базу данных SQLite . В Android контакты и медиа хранятся и ссылаются на БД SQLite . Она является наиболее используемой СУБД в мире и самым распространенным программным обеспечением . Чтобы узнать о базах данных SQLite как можно больше, посетите официальный сайт SQLite .

Подготовка

Чтобы включить привязку данных в приложении, нужно добавить в файл build.gradle следующий код:

Чтобы использовать как RecyclerView , так и CardView для отображения списков, нужно включить соответствующие библиотеки в разделе зависимостей в файле build.gradle :

Чтобы задействовать все возможности базы данных SQLite , лучше изучить синтаксис SQL .

Описание примера приложения

В нашем Android SQLite примере мы создадим две таблицы: Employer и Employee . Таблица Employee будет содержать ссылку на внешний ключ таблицы Employer . Мы рассмотрим, как вставлять, выбирать, обновлять и удалять строки из таблиц. Я также продемонстрирую, как вывести элементы, выбранные из базы данных SQLite в RecyclerView ( список ) и в Spinner .

У нас есть MainActivity , из которого можно перейти к EmployerActivity ( для работы с таблицей Employer ) или к EmployeeActivity ( для работы с таблицей Employee ):

Классы хранения базы данных SQLite

Классы определяют то, как данные хранятся в базе. SQLite сохраняют значения с помощью пяти доступных классов хранения:

  • NULL — нулевое значение;
  • INTEGER — для целых чисел, содержащих от 1 до 8 байтов;
  • REAL — числа с плавающей запятой;
  • TEXT — текстовые строки, хранящиеся с использованием кодировки базы данных ( UTF-8 или UTF-16 );
  • BLOB — двоичные данные, хранящиеся точно так, как они были введены.

Определение таблиц

Поскольку база данных SQLite является локальной, нужно обеспечить, чтобы приложение создавало таблицы и по мере необходимости сбрасывало их.

Начнем с Android SQLite query создания таблицы Employer , а затем перейдем к EmployerActivity .

Рекомендуется размещать логику создания базы х SQLite в классе. Это облегчает устранение возможных неполадок. Назовем наш класс SampleDBContract :

Мы определяем частный конструктор для SampleDBContract , а затем создаем класс для представления таблицы Employer . Обратите внимание: класс Employer реализует интерфейс BaseColumns . Он предоставляет два столбца в нашей таблице. Это столбец _ID , который будет автоматически увеличиваться при добавлении каждой новой строки. И столбец _COUNT , который может использоваться ContentProviders для возврата количества записей, извлекаемых через запрос. Столбец _COUNT не является обязательным. Строка CREATE_TABLE компилируется в следующий оператор SQL :

На данный момент в нашем Android SQLite примере мы определили схему таблицы Employer .

Создание базы данных с помощью SQLiteOpenHelper

Самый простой способ управления созданием базы данных и версиями — создать подкласс SQLiteOpenHelper . Он упрощает управление базой данных SQLite , создавая БД, если они не существуют. Необходимо только переопределить методы onCreate() и onUpgrade() , чтобы указать нужное действие для создания или обновления базы данных:

Теперь в нашем примере Android database SQLite задаем для нашей базы данных SQLite имя ( sample_database ). Конструктор вызывает конструктор суперкласса с именем и версией базы данных. В onCreate мы указываем объекту SQLiteDatabase выполнить оператор Employer CREATE_TABLE SQL . Через onUpgrade мы сбрасываем таблицу Employer и создаем ее снова:

Таблица Employer имеет три столбца: name , description и founded_date . Нажатие кнопки сохранения вызывает метод saveToDB() :

В saveToDB() мы получаем ссылку на объект SQLiteDatabase , используя метод getWritableDatabase() из SQLiteOpenHelper . Этот метод создает базу данных, если она еще не существует, или открывает ее, если она уже создана. GetWritableDatabase возвращает объект SQLiteDatabase , который открывает доступ на чтение / запись:

В приведенном выше фрагменте кода есть четыре момента:

  1. Мы получаем объект SQLiteDatabase , который открывает доступ на запись в базу данных;
  2. Значения, которые будут храниться в базе данных, помещаются в объект ContentValue с именем столбца в качестве ключа;
  3. Мы помещаем Date в объект ContentValue , который переводится в класс хранения данных Android SQLite INTEGER ;
  4. При вставке строки в базу данных с помощью метода database.insert() возвращается идентификатор строки.

Выбор данных из базы данных SQLite

Подобно тому, как мы применили метод getWritableDatabase() , можно вызвать getReadableDatabase() объекта SQLiteOpenHelper для получения объекта SQLiteDatabase , который можно использовать для чтения информации из базы данных. Стоит отметить, что объект SQLiteDatabase , возвращаемый getReadableDatabase() , предоставляет собой тот же самый доступ на чтение / запись в базу данных, который был возвращен функцией getWritableDatabase() , за исключением тех случаев, когда существуют определенные ограничения. Например, файловая система, содержащая заполненную базу данных, и база данных может быть открыта только для чтения.

Метод readFromDB будет запрашивать БД, и возвращать все строки из таблицы Employer , в которых имя или описание из таблицы Employer совпадает со значением, введенным в EditText . А также строки, в которых дата основания компании совпадает со значением, введенным в EditText :

В коде Android SQLite query , приведенного выше, projection является массивом String , представляющим столбцы, которые мы хотим получить. selection является строковым представлением условия SQL WHERE , отформатированным таким образом, что символ ‘?’ будет заменен аргументами в массиве selectionArgs String . Вы также можете группировать, фильтровать и сортировать результаты запроса. Вставка данных в базу SQLite с использованием описанного выше метода защищает от SQL-инъекций .

Читайте также:  Tor browser android скриншоты

Обратите внимание на объект, возвращаемый запросом — Cursor . В следующем разделе мы покажем, как вывести содержимое Cursor с помощью RecyclerView .

Отображение содержимого объекта Cursor в RecyclerView

Cursor предоставляет произвольный доступ к набору результатов, возвращаемому запросом к базе данных. Это означает, что через Cursor можно получить доступ к значениям в любом месте, подобно Java-спискам или массивам. Благодаря этому приему можно реализовать RecyclerView с использованием Cursor так же, как мы реализуем RecyclerView с помощью ArrayLists . Вместо вызова List.get(i) , вы перемещаете Cursor в нужную позицию, используя moveToPosition() . После этого вызываете соответствующий метод getXXX(int columnIndex) , где XXX — это Blob , Double , Float , Int , Long , Short или String .

Чтобы не беспокоиться о корректных индексах столбцов из метода readFromDB() , примененного выше, мы используем метод getColumnIndexOrThrow() , который извлекает индекс указанного столбца или генерирует исключение, если имя столбца не существует внутри объекта Cursor :

Определение внешних ключей

На данный момент в нашем Android SQLite примере мы создали таблицу Employer , которую заполнили строками. Теперь создадим таблицу Employee , которая связана с таблицей Employer через столбец _ID Employer . Мы определяем класс Employee , который расширяет BaseColumns в классе SampleDBContract . Обратите внимание, что при создании таблицы Employee использовали « FOREIGN KEY(employer_id) REFERENCES employer(_id) «:

Обновление SQLiteOpenHelper

На данный момент в Android Studio SQLite у вас должна быть создана таблица Employer и в нее добавлены значения. Если вы не изменяете версию базы данных, новая таблица Employee не будет создана. К сожалению, если вы измените версию через повторный вызов метода onUpgrade() , то таблица Employer будет сброшена. Чтобы предотвратить это, можно закомментировать или удалить оператор drop в методе onUpgrade() и добавить оператор execSQL() для создания таблицы Employee . Поскольку таблица Employee ссылается на таблицу Employer , сначала необходимо создать таблицу Employer :

Отображение данных из запроса SQLite в Spinner

Чтобы создать работника в таблице Employee , пользователю необходимо выбрать соответствующего работодателя в таблице Employer . Для этого можно предоставить пользователю Spinner . Отобразить содержимое Cursor в Spinner довольно просто.

Сначала мы выполняем Android SQLite query , как было описано выше, выбираем только name из Employer и id (queryCols) . Затем создаем экземпляр SimpleCursorAdapter , передавая ему Cursor , массив столбцов для отображения ( adapterCols ) и массив представлений, с помощью которых должны отображаться столбцы ( adapterRowViews ). Затем устанавливаем Spinner Adapter для SimpleCursorAdapter :

Вставка внешнего ключа в базу данных

Вставка строки, содержащей внешний ключ, полностью идентична вставке строк в таблицу без ограничений по внешнему ключу. Разница заключается в том, что в Android SQLite примере мы получаем ссылку на выбранный объект Cursor из Spinner , а затем — значение столбца _ID Employer :

Выборка данных из базы SQLite с помощью JOIN

Нельзя использовать метод SQLiteDatabase query() для выполнения запроса к нескольким таблицам. Для этого нужно составить собственный SQL-запрос . В приведенном ниже примере запрос определяется в классе SampleDBContract :

Обратите внимание, что в условии WHERE мы используем символ « ? ». Чтобы не нарушить синтаксис SQL нужно определить selectArgs String [] со значениями, которые будут заменять в предоставленном SQL-запросе символ « ? »:

В заключении

Полная версия исходного кода доступна на github для использования и изменения. Базы данных Android SQLite — это мощное средство, доступное для всех мобильных приложений.

Дайте знать, что вы думаете по этой теме статьи в комментариях. Мы крайне благодарны вам за ваши комментарии, лайки, подписки, дизлайки, отклики!

Дайте знать, что вы думаете по данной теме в комментариях. За комментарии, отклики, подписки, лайки, дизлайки низкий вам поклон!

Источник

SQLite и Android. Кошкин дом. Часть вторая

В первой части мы изучили возможности SQLite. Теперь нужно научиться подключать базу данных в приложении на Android.

SQLite зарекомендовала себя в качестве чрезвычайно надёжной системы баз данных, которая используется во многих бытовых электронных устройствах и программах, включая некоторые MP3-проигрыватели, iPhone, iPod Touch, Mozilla Firefox и др.

С помощью SQLite вы можете создавать для своего приложения независимые реляционные базы данных. Android хранит базы данных в каталоге /data/data/ /databases на эмуляторе, на устройстве путь может отличаться. По умолчанию все базы данных закрытые, доступ к ним могут получить только те приложения, которые их создали.

Каждая база данных состоит из двух файлов. Имя первого файла базы данных соответствует имени базы данных. Это основной файл баз данных SQLite, в нём хранятся все данные. Вы будете создавать его программно. Второй файл — файл журнала. Его имя состоит из имени базы данных и суффикса «-journal». В файле журнала хранится информация обо всех изменениях, внесенных в базу данных. Если в работе с данными возникнет проблема, Android использует данные журнала для отмены (или отката) последних изменений. Вы с ним не будете взаимодействовать, но если вы будете просматривать внутренности своего устройства, то будете знать, зачем этот файл там присутствует.

Интерфейс

Для начала создадим интерфейс программы. Для первой активности MainActivity выберем шаблон Basic Activity. Сразу же создадим вторую активность EditorActivity из шаблона Empty Activity.

В первой активности есть кнопка Floating Action Button, через которую будем попадать на вторую активность.

Вторая активность предназначена для добавления новых гостей, которые поселяются в наш отель «Кошкин дом». Настроим его.

Экран состоит из нескольких текстовых полей и одного выпадающего списка для выбора пола гостя.

Инициализируем текстовые поля и выпадающий список.

Добавим несколько строковых ресурсов.

Подписываем контракт

Теперь можно заняться интеграцией базы данных в приложение.

При работе с базой данных принято создавать новый пакет data внутри основного пакета. Щёлкаем правой кнопкой мыши по имени пакета, выбираем New | Package и вводим новое имя.

В последних рекомендациях Гугла рекомендуется создавать класс-контракт. Будем придерживаться этого правила. Мы как бы подписываем контракт на работу с базой данных и предоставляем все нужные данные.

Внутри созданного пакета создаём новый класс HotelContract. Класс-контракт является контейнером для базы данных и может содержать несколько внутренних классов, которые представляют отдельные таблицы (не забывайте, что база данных может содержать несколько таблиц). Внутри класса создаём внутренний класс. В нашем случае будет один класс для таблицы guests.

Читайте также:  Как отослать свою геолокацию андроид

Нам следует задать схему таблицы и константы для столбцов для удобства. Класс будет выглядеть так.

В классе используется реализация интерфейса BaseColumn:

Что это нам даёт? В большинстве случаев работа с базой данных происходит через специальные объекты Cursor, которые требуют наличия в таблице колонки с именем _id. Вы можете создать столбец вручную в коде, а можно положиться на BaseColumn, который создаст столбец с нужным именем автоматически. Дело ваше. Если вы не будете работать с курсорами, то можете использовать и стандартное наименование id или вообще не использовать данный столбец, но не советую так поступать, чтобы не вырабатывать вредных привычек.

После создания класса мы можем изменить код в EditorActivity в том месте, где происходит выбор пола гостя через выпадающий список.

SQLiteOpenHelper

Следующий шаг — создание класса в пакете data, который наследуется от специального класса SQLiteOpenHelper и непосредственно работает с базой данных. В классе создаются константы для удобной работы. Также реализуются методы onCreate() и onUpgrade().

Созданный класс будет работать с базой данных — добавлять, выбирать, удалять записи и прочие операции.

Напомню, как выглядит схема нашей таблицы.

Щёлкаем правой кнопкой мыши на имени пакета в левой части студии и выбираем в меню New | Java Class и в диалоговом окне выбираем имя для нового класса, например, HotelDbHelper. Слово Helper обычно используют, чтобы показать, что класс является обёрткой (вспомогательным классом) какого-то абстрактного класса. Впрочем, вы можете придумать более замысловатое название, например, ILoveNewYork или CatsForever. Спустя год, когда вы вернётесь к своему примеру, это будет так увлекательно вспоминать, для чего был создан класс с таким красивым именем.

У нас появится заготовка. Наследуемся от SQLiteOpenHelper. Студия предложит создать два обязательных метода onCreate() и onUpgrade(), о которых поговорим позже.

После добавления методов студия по-прежнему ругается. Теперь ему подавай конструкторы. Получится такой код.:

Третий параметр null в суперклассе используется для работы с курсорами. Сейчас их не используем, поэтому оставим в покое.

Как вы уже догадались, константа DATABASE_NAME отвечает за имя файла, в котором будет храниться база данных приложения. Можно придумать любое имя и обойтись без расширения. Но мне так привычнее.

Вторая константа DATABASE_VERSION требует дополнительных объяснений. Она отвечает за номер версии базы. Принцип её работы схож с номером версий самого приложения. Когда мы видим, что вышла новая версия Chrome 33, то понимаем, что пора обновляться. Аналогично поступает и само приложение, когда замечает, что номер версии базы стал другим. Как только программа заметила обновление номера базы, она запускает метод onUpgrade(), который у нас сформировался автоматически. В этом методе необходимо разместить код, который должен сработать при обновлении базы.

Метод onCreate() вопросов не вызывает — здесь создаётся сама база данных с необходимыми данными для работы.

Метод вызывается, если в устройстве нет базы данных и наш класс должен создать его. Как мы помним, у метода есть параметр db, который относится к классу SQLiteDatabase. У класса есть специальный метод execSQL(), которому нужно передать запрос (SQL-скрипт) для создания таблицы. Для создания таблицы в SQL используется команда CREATE TABLE . . Для удобства вынесем команду в отдельную строку. Аналогично поступим с командой DROP TABLE. Так как строка очень длинная и состоит из множества строковых переменных, которые нужно соединить в одну цепочку, то поступают следующим образом. Создаём ещё одну строковую константу для формирования скрипта и передадим её в метод.

Основная сложность — не пропустить пробелы в запросе. Очень часто пропущенный пробел становится источником проблем и ваше приложение не может создать таблицу. Можете сначала написать сам скрипт создания таблицы, а уже потом заменять отдельные слова константами. Идентификатор _id всегда должен использовать INTEGER PRIMARY KEY AUTOINCREMENT, остальные колонки на ваше усмотрение.

Теперь нужно объяснить, зачем нужен этот метод onUpgrade(). Представьте ситуацию, что вы первоначально создали в базе таблицу, в которую заносятся имена котов и их электронные адреса и телефоны (продвинутые кошаки). Вроде всё замечательно. Если нужно поздравить усатых-полосатых с Международным днём кошек, который отмечается 1 марта, то проблем нет никаких. У вас есть список имён, по которому вы можете пройтись и лично написать каждому письмо. Пользователи, скачавшие ваше приложение, с удовольствием заполняют базу данных и дружно пишут письма мелким почерком. И вдруг до вас дошло, что совершили непростительную ошибку. Вы забыли добавить в базу данных даты рождения котов. А значит их никто не поздравит и не погладит (((.

Вы исправляете досадное упущение и выкладываете новую версию программы в открытый доступ. Новые пользователи, которые установят программу первый раз, радуются жизни — у них есть все необходимые данные для работы. Но что делать тем, кто уже работает со старой программой? Обновившись, они увидят дополнительное текстовое поле для ввода даты рождения, но в старой базе нет колонки для хранения новых данных. И ваша программа завершится с ошибкой. Полностью удалять и устанавливать новую версию программы тоже не выход — тогда пропадут старые данные, что тоже не желательно. Для таких случаев вы пишете код в методе onUpgrade(), чтобы при обновлении поменялась структура базы данных у старых пользователей. Мы позже попробуем смоделировать эту ситуацию.

Итак, метод onUpgrade() вызывается при несовпадении версий. Часто в этом методе просто удаляют существующую таблицу и заменяют её на новую. Это самое простое и практичное решение. Впрочем, на первых порах, вам вряд ли придётся заниматься подобными делами, поэтому метод можно оставить даже пустым.

Когда ваше приложение будет готово, то в папке data/data/имя_пакета/databases появится файл hotel.db (позже я вам покажу). Этот файл и будет вашей базой данных, в которой будет находиться созданная вами таблица. На данный момент в студии нет готового плагина для просмотра таблиц (в Eclipse есть), но вроде уже видел плагин от сторонних разработчиков. А пока вам придётся скачивать из устройства файл базы данных и просматривать его на компьютере специальными программами, работающими с SQLite на локальном компьютере.

Работаем с записями базы данных

Чтобы проверить работоспособность базы данных, в главной активности поместим вспомогательный метод displayDatabaseInfo() для отображения информации.

Читайте также:  Прошивка для андроид самсунг 9300

Массив projection — это список столбцов, которые нас интересуют. В SQL-запросе мы их указываем в операторе SELECT:

В методе query() третий и четвёртый параметр определяют условие WHERE. Возьмём случай с выражением:

В коде такое выражение выглядело бы так.

Как видим, в знак вопроса подставляется нужное значение.

Последний аргумент отвечает за сортировку по возрастанию или убыванию. Например, по возрасту.

Чтение данных

Считывать данные также можно двумя способами. В любом случае результат возвращается в виде объекта Cursor. Не путайте его с курсором мыши, который бегает у вас на экране.

Первый способ. Метод query()

Извлечение данных происходит через метод query(). Данные хранятся в наборе строк, которые можно представить в виде таблицы. Из этой таблицы вы уже можете извлечь конкретное значение.

У метода query() множество параметров. В первом параметре укажите имя таблицы, во втором — массив имён колонок, далее идут дополнительные условия. Пока везде оставим null. В нашем примере мы добавили одну запись и извлечь её просто.

Второй способ. Метод rawQuery()

Второй способ использует сырой (raw) SQL-запрос. Сначала формируется строка запроса и отдаётся методу rawQuery().

Запустите проект. При запуске создаётся база данных. Убедиться в этом можно, если запустить Android Device Monitor. Выберите вкладку File Explorer и найдите своё приложение (на эмуляторе). Вы увидите, что появилась папка data/data/имя_пакета/databases с файлом hotel.db. Метод getReadableDatabase создаёт или открывает базу данных.

Сейчас мы увидим, что пока у нас 0 гостей.

Небольшое предупреждение. При работе с базой данных мы обращаемся к файлу. Если база данных очень большая, то запросы не будут мгновенными. Операции с файлами являются медленными, поэтому следует использовать многопоточность. Для наших примеров это не страшно, поэтому мы пока не будем усложнять код.

Вставка данных для проверки

Рассмотрим, как вставлять новые данные. Добавим в меню главной активности пункт «Вставить данные». Для вставки данных применяется метод ContentValues.put(). В методе указываются ключ и значение. В качестве ключа выступает имя столбца таблицы, а его значением будет нужная информация о госте. Так как идентификатор будет вставляться автоматически, то его не используем. После того, как вы заполните все столбцы таблицы, вызывайте метод insert(), который и разместит данные в базе.

Напишем вспомогательный метод.

Вызовем метод в обработчике нажатия пункта меню.

Сразу после вставки вызываем метод displayDatabaseInfo(), чтобы увидеть результат. Можно нажимать несколько раз. Так как данные жёстко заданы в коде, то увидим одинаковые данные, кроме увеличивающего значения идентификатора.

Вставка данных. Общая информация

Теперь разберём подробнее, как делать вставки.

Первый способ. ContentValues

Для вставки сначала подготавливаются данные с помощью класса ContentValues. Вы указываете имя колонки таблицы и значение для неё, т.е. работает по принципу «ключ-значение». Когда подготовите все данные во все столбцы, то вызывайте метод insert(), который сразу раскидает данные по столбцам.

Способ очень удобен, требует мало кода и легко читаем. Вы создаёте экземпляр класса, а затем с помощью метода put() записываете в нужную колонку нужные данные. После чего вызывается метод insert(), который помещает подготовленные данные в таблицу.

У метода insert() три аргумента. В первом указывается имя таблицы, в которую будут добавляться записи. В третьем указывается объект ContentValues, созданный ранее. Второй аргумент используется для указания колонки. SQL не позволяет вставлять пустую запись, и если будет использоваться пустой ContentValue, то укажите во втором аргументе null во избежание ошибки.

Второй способ. SQL-запрос

Существует также другой способ вставки через метод execSQL(), когда подготавливается нужная строка и запускается скрипт. Этот способ возможно понравится PHP-кодерам, которые привыкли к такому синтаксису.

В этом варианте используется традиционный SQL-запрос INSERT INTO. . Основное неудобство при этом способе — не запутаться в кавычках. Если что-то не вставляется, то смотрите логи сообщений.

Научившись вставлять данные, можно заняться второй активностью, которая и предназначена для этих целей.

Наполняем базу данных

Создадим вспомогательный метод для вставки записи в базу данных. Для этого считываем данные, которые вводятся в текстовые поля, а далее по предыдущему учебному примеру.

Метод вызывается в меню для значка с галочкой, которая выводится на панели действия активности.

Запускаем проект и проверяем работу кода.

Изменение данных

Обновление не реализовано в программе, проделайте это самостоятельно.

Если запись уже существует, но вам нужно изменить какое-то значение, то вместо insert() используйте метод update(). В остальном принцип тот же. Предположим, что повторном осмотре котёнка выяснилось, что это кот, а не кошка. Если вы уже назвали котёнка Муркой, то логично назвать его теперь Мурзиком. Вызываем метод put(), а затем обновляем запись в базе данных.

Первый параметр метода update() содержит имя таблицы. Второй параметр указывает, какие значения должны использоваться для обновления. Третий параметр задает условия отбора обновляемых записей (WHERE). В приведенном примере «NAME = ?» означает, что столбец NAME должен быть равен некоторому значению. Символ ? обозначает значение столбца, которое определяется содержимым последнего параметра. Если в двух последних параметрах метода передаётся значение null, будут обновлены ВСЕ записи в таблице.

Возможны и сложные условия.

Если столбец не является строкой, то его нужно преобразовать в строку, чтобы использовать в качестве условий.

Будьте осторожны с обновлениями. Если в последних двух параметрах передать значение null, то будут обновлены все записи в таблице, так как в запросе нет условий.

Удаление данных

Также не реализовано. Проделайте самостоятельно.

Метод delete() класса SQLiteDatabase работает по тому же принципу, как и метод update(). Он имеет следующую форму:

Внедрение опасного кода

При работе с базой данной надо следить за безопасностью данных. Опытный пользователь может удалить базу. На своём устройстве он делать этого может и не будет, но на устройстве жертвы вполне.

Простой вариант атаки. Допустим у нас есть поле для ввода идентификатора, чтобы узнать информацию о госте. Нормальный пользователь введёт число «3» для поиска третьего гостя. В коде это будет следующим образом.

Тогда идентификатор будет _ID == 2;.

Хакер может ввести следующую строку в текстовое поле:

В коде это превратится в следующее:

Таким образом вредитель внедрил нежелательный код, который удалит таблицу.

Источник

Оцените статью