Перейти к основному содержимому

Быстрый старт

В этом разделе описывается разработка приложений, взаимодействующих с СУБД Pangolin.

Разработка приложения на языке С++

Создание тестовой базы данных

Создайте тестовую базу данных, с которой будет работать приложение. Чтобы создать тестовую базу данных testdb, запустите интерфейс командной строки Pangolin (psql) и выполните команду:

CREATE DATABASE testdb;

Внимание!

Для выполнения определенных команд могут потребоваться права на подключение к БД и набор прав для работы с данными (DDL, DML). Убедитесь, что у учетной записи есть необходимые права доступа, или войдите в систему под учетной записью, которой такие права предоставлены (например, postgres).

Убедитесь, что новая база данных создана. Для этого в интерфейсе командной строки Pangolin выполните команду \l. Пример вывода:

postgres-# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
testdb | postgres | UTF8 | C | C |
(4 rows)
postgres-#

Подключение к базе данных

Приведенный ниже код реализует подключение к базе данных на локальной машине через порт 5433 от имени пользователя postgres.

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}
}

Скомпилируйте программу и выполните ее:

$ gсс test.cpp -lpqxx -lpq
$ ./a.out
Подключение к базе данных testdb установлено.

Создание таблицы

Приведенный ниже код создает таблицу MYSTORE в базе данных testdb.

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
char * sql;

try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}

/* Создать инструкцию SQL */
sql = "CREATE TABLE MYSTORE(" \
"ID INT PRIMARY KEY NOT NULL," \
"ТИП TEXT NOT NULL," \
"ЦВЕТ TEXT NOT NULL," \
"МАТЕРИАЛ TEXT NOT NULL," \
"ЗАПАС INT," \
"ЦЕНА REAL );";

/* Создать транзакционный объект */
work W(C);

/* Выполнить SQL-запрос */
W.exec( sql );
W.commit();
cout << "Таблица создана успешно" << endl;
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}

return 0;
}

Скомпилируйте программу и выполните ее:

$ gсс test.cpp -lpqxx -lpq
$ ./a.out
Подключение к базе данных testdb установлено.
Таблица создана успешно

Операция INSERT

Приведенный ниже код создает записи в таблице MYSTORE:

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
char * sql;

try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}

/* Создать инструкцию SQL */
sql = "INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (1, 'Футболка', 'Синий', 'Хлопок', 500, 2000.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (2, 'Футболка', 'Желтый', 'Хлопок', 500, 2000.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (3, 'Футболка', 'Красный', 'Хлопок', 500, 2000.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (4, 'Рубашка', 'Синий', 'Шелк', 400, 2500.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (5, 'Рубашка', 'Белый', 'Хлопок', 600, 1400.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (6, 'Свитер', 'Синий', 'Шерсть', 100, 4000.00 ); " \
"INSERT INTO MYSTORE (ID,ТИП,ЦВЕТ,МАТЕРИАЛ,ЗАПАС,ЦЕНА) " \
"VALUES (7, 'Футболка', 'Синий', 'Нейлон', 500, 1000.00 ); "; \

/* Создать транзакционный объект */
work W(C);

/* Выполнить SQL-запрос */
W.exec( sql );
W.commit();
cout << "Записи созданы успешно." << endl;
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}

return 0;
}

Скомпилируйте программу и выполните ее:

$ gсс test.cpp -lpqxx -lpq
$ ./a.out
Подключение к базе данных testdb установлено.
Записи созданы успешно.

Операция SELECT

Приведенный ниже код выводит на экран записи из таблицы MYSTORE:

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
char * sql;

try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}

/* Создать инструкцию SQL */
sql = "SELECT * from MYSTORE";

/* Создать нетранзакционный объект */
nontransaction N(C);

/* Выполнить SQL-запрос */
result R( N.exec( sql ));

/* Вывести записи */
for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
cout << "ID = " << c[0].as<int>() << endl;
cout << "Тип = " << c[1].as<string>() << endl;
cout << "Цвет = " << c[2].as<string>() << endl;
cout << "Материал = " << c[3].as<string>() << endl;
cout << "Запас = " << c[4].as<int>() << endl;
cout << "Цена = " << c[5].as<float>() << endl;
cout << endl;
}
cout << "Операция выполнена успешно." << endl;
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}

return 0;
}

Скомпилируйте программу и выполните ее:

$ gсс test.cpp -lpqxx -lpq
$ ./a.out
Подключение к базе данных testdb установлено.
ID = 1
Тип = Футболка
Цвет = Синий
Материал = Хлопок
Запас = 500
Цена = 2000

ID = 2
Тип = Футболка
Цвет = Желтый
Материал = Хлопок
Запас = 500
Цена = 2000

ID = 3
Тип = Футболка
Цвет = Красный
Материал = Хлопок
Запас = 500
Цена = 2000

ID = 4
Тип = Рубашка
Цвет = Синий
Материал = Шелк
Запас = 400
Цена = 2500

ID = 5
Тип = Рубашка
Цвет = Белый
Материал = Хлопок
Запас = 600
Цена = 1400

ID = 6
Тип = Свитер
Цвет = Синий
Материал = Шерсть
Запас = 100
Цена = 4000

ID = 7
Тип = Футболка
Цвет = Синий
Материал = Нейлон
Запас = 500
Цена = 1000

Операция выполнена успешно.

Операция UPDATE

Приведенный ниже код изменяет данные в таблице MYSTORE с помощью операции UPDATE и выводит на экран обновленные записи:

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
char * sql;

try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}

/* Создать транзакционный объект */
work W(C);

/* Создать инструкцию SQL */
sql = "UPDATE MYSTORE set ЦЕНА = 999.99 where МАТЕРИАЛ='Хлопок'";

/* Выполнить SQL-запрос */
W.exec( sql );
W.commit();
cout << "Записи изменены успешно" << endl;

/* Создать инструкцию SQL */
sql = "SELECT * from MYSTORE";

/* Создать нетранзакционный объект */
nontransaction N(C);

/* Выполнить SQL-запрос */
result R( N.exec( sql ));

/* Вывести записи */
for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
cout << "ID = " << c[0].as<int>() << endl;
cout << "Тип = " << c[1].as<string>() << endl;
cout << "Цвет = " << c[2].as<string>() << endl;
cout << "Материал = " << c[3].as<string>() << endl;
cout << "Запас = " << c[4].as<int>() << endl;
cout << "Цена = " << c[5].as<float>() << endl;
cout << endl;
}
cout << "Операция выполнена успешно." << endl;
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}

return 0;
}

Скомпилируйте программу и выполните ее:

$ gсс test.cpp -lpqxx -lpq
$ ./a.out
Подключение к базе данных testdb установлено.
Записи обновлены успешно.
ID = 4
Тип = Рубашка
Цвет = Синий
Материал = Шелк
Запас = 400
Цена = 2500

ID = 6
Тип = Свитер
Цвет = Синий
Материал = Шерсть
Запас = 100
Цена = 4000

ID = 7
Тип = Футболка
Цвет = Синий
Материал = Нейлон
Запас = 500
Цена = 1000

ID = 1
Тип = Футболка
Цвет = Синий
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 2
Тип = Футболка
Цвет = Желтый
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 3
Тип = Футболка
Цвет = Красный
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 5
Тип = Рубашка
Цвет = Белый
Материал = Хлопок
Запас = 600
Цена = 999.99

Операция выполнена успешно.

Операция DELETE

Приведенный ниже код удаляет данные из таблицы MYSTORE с помощью операции DELETE и выводит на экран обновленные записи:

#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
char * sql;

try {
connection C("dbname = testdb user = postgres password = <пароль> \
hostaddr = 127.0.0.1 port = 5433");
if (C.is_open()) {
cout << "Подключение к базе данных " << C.dbname() << " установлено." << endl;
} else {
cout << "Не удается установить подключение к базе данных." << endl;
return 1;
}

/* Создать транзакционный объект */
work W(C);

/* Создать инструкцию SQL */
sql = "DELETE from MYSTORE where МАТЕРИАЛ != 'Хлопок'";

/* Выполнить SQL-запрос */
W.exec( sql );
W.commit();
cout << "Записи изменены успешно." << endl;

/* Создать инструкцию SQL */
sql = "SELECT * from MYSTORE";

/* Создать нетранзакционный объект */
nontransaction N(C);

/* Выполнить SQL-запрос */
result R( N.exec( sql ));

/* Вывести записи */
for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
cout << "ID = " << c[0].as<int>() << endl;
cout << "Тип = " << c[1].as<string>() << endl;
cout << "Цвет = " << c[2].as<string>() << endl;
cout << "Материал = " << c[3].as<string>() << endl;
cout << "Запас = " << c[4].as<int>() << endl;
cout << "Цена = " << c[5].as<float>() << endl;
cout << endl;
}
cout << "Операция выполнена успешно." << endl;
C.disconnect ();
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}

return 0;
}

Скомпилируйте программу и выполните ее:

$ ./delete.out
Подключение к базе данных testdb установлено.
Записи изменены успешно.
ID = 1
Тип = Футболка
Цвет = Синий
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 2
Тип = Футболка
Цвет = Желтый
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 3
Тип = Футболка
Цвет = Красный
Материал = Хлопок
Запас = 500
Цена = 999.99

ID = 5
Тип = Рубашка
Цвет = Белый
Материал = Хлопок
Запас = 600
Цена = 999.99

Операция выполнена успешно.

Разработка приложения на языке Java

Подключение к базе данных

Приведенный ниже код реализует подключение к базе данных postgres на локальной машине через порт 5433 от имени пользователя postgres.

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
public class Main {
// Учетные данные для подключения
static final String DB_URL = "jdbc:postgresql://<IP-адрес>/postgres"; //Замените на свой IP
static final String USER = "postgres";
static final String PASS = "пароль"; //Замените на пароль postgres
public static void main(String[] argv) {
System.out.println("Проверка подключения драйвера JDBC");
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Драйвер JDBC не обнаружен");
e.printStackTrace();
return;
}
System.out.println("Драйвер JDBC обнаружен, выполняется установка соединения");
Connection connection = null;
try {
connection = DriverManager
.getConnection(DB_URL, USER, PASS);
} catch (SQLException e) {
System.out.println("Не удалось установить соединение");
e.printStackTrace();
return;
}
if (connection != null) {
System.out.println("Соединение с базой данных установлено");
} else {
System.out.println("Не удалось установить соединение с базой данных");
}
}
}

Скомпилируйте программу и выполните ее:

java -cp ./postgresql-42.2.24.jar Main.java

Внимание!

Не забудьте подключить jar-файл с библиотекой JDBC.

Операция CREATE

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

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;

public class Create {
// Учетные данные для подключения
static final String DB_URL = "jdbc:postgresql://<IP-адрес>/postgres"; //Замените на свой IP
static final String USER = "postgres";
static final String PASS = "пароль"; //Замените на пароль postgres
public static void main(String[] argv) {
String query = "create table mystore(" + //Создание таблицы с заголовками
"ID int primary key not null," +
"Тип text not null," +
"Цвет text not null," +
"Материал text not null," +
"Запас int," +
"Цена real );" +
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " + //... и наполнение ее данными
"values (1, 'Футболка', 'Синий', 'Хлопок', 500, 2000.00 ); " +
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (2, 'Футболка', 'Желтый', 'Хлопок', 500, 2000.00 ); "
+
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (3, 'Футболка', 'Красный', 'Хлопок', 500, 2000.00 ); "
+
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (4, 'Рубашка', 'Синий', 'Шелк', 400, 2500.00 ); " +
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (5, 'Рубашка', 'Белый', 'Хлопок', 600, 1400.00 ); " +
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (6, 'Свитер', 'Синий', 'Шерсть', 100, 4000.00 ); " +
"insert into mystore (ID,Тип,Цвет,Материал,Запас,Цена) " +
"values (7, 'Футболка', 'Синий', 'Нейлон', 500, 1000.00 ); ";
try (Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pst = con.prepareStatement(query)){
pst.executeUpdate();
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Таблица создана и наполнена данными");
}
}

Скомпилируйте программу и выполните ее:

java -cp ./postgresql-42.2.24.jar create.java

Операция SELECT

Приведенный ниже код выводит на экран записи из таблицы mystore:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
public class Select {
// Учетные данные для подключения
static final String DB_URL = "jdbc:postgresql://<>IP-адрес>/postgres"; //Замените на свой IP
static final String USER = "postgres";
static final String PASS = "пароль"; //Замените на пароль postgres
public static void main(String[] argv) {
String query = "select * from mystore";
try (Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pst = con.prepareStatement(query);
ResultSet rs = pst.executeQuery()) {
ResultSetMetaData meta = pst.getMetaData(); //Получение и вывод названий столбцов таблицы
for (int i=1; i <= meta.getColumnCount(); i++)
{
System.out.print(meta.getColumnName(i) + " | ");
}
System.out.print("\n");
while (rs.next()) { //Построчный вывод содержимого таблицы
for (int i=1; i <= meta.getColumnCount();
i++)
{
System.out.print(rs.getString(i) + " | ");
}
System.out.print("\n");
}
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Таблица выведена на экран");
}
}

Скомпилируйте программу и выполните ее:

java -cp ./postgresql-42.2.24.jar select.java
id | Тип | Цвет | Материал | Запас | Цена |
1 | Футболка | Синий | Хлопок | 500 | 2000 |
2 | Футболка | Желтый | Хлопок | 500 | 2000 |
3 | Футболка | Красный | Хлопок | 500 | 2000 |
4 | Рубашка | Синий | Шелк | 400 | 2500 |
5 | Рубашка | Белый | Хлопок | 600 | 1400 |
6 | Свитер | Синий | Шерсть | 100 | 4000 |
7 | Футболка | Синий | Нейлон | 500 | 1000 |
Таблица выведена на экран

Операция UPDATE

Приведенный ниже код изменяет данные в таблице mystore с помощью операции UPDATE и выводит на экран обновленные записи:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
public class Update {
// Учетные данные для подключения
static final String DB_URL = "jdbc:postgresql://<IP-адрес>/postgres"; //Замените на свой IP
static final String USER = "postgres";
static final String PASS = "пароль"; //Замените на пароль postgres
public static void main(String[] argv) {
String query = "update mystore set Цена = 999 where Материал='Хлопок'"; //Обновление данных в таблице
try (Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pst = con.prepareStatement(query)){
pst.executeUpdate();
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Данные в таблице обновлены");
// Далее идет код вывода результата из предыдущего шага
query = "select * from mystore";
try (Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pst = con.prepareStatement(query);
ResultSet rs = pst.executeQuery()) {
ResultSetMetaData meta = pst.getMetaData(); //Получение и вывод названий столбцов таблицы
for (int i=1; i <= meta.getColumnCount(); i++)
{
System.out.print(meta.getColumnName(i) + " | ");
}
System.out.print("\n");
while (rs.next()) { //Построчный вывод содержимого таблицы
for (int i=1; i <= meta.getColumnCount();
i++)
{
System.out.print(rs.getString(i) + " | ");
}
System.out.print("\n");
}
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Таблица выведена на экран");
}
}

Скомпилируйте программу и выполните ее:

java -cp ./postgresql-42.2.24.jar update.java
Данные в таблице обновлены
id | Тип | Цвет | Материал | Запас | Цена |
4 | Рубашка | Синий | Шелк | 400 | 2500 |
6 | Свитер | Синий | Шерсть | 100 | 4000 |
7 | Футболка | Синий | Нейлон | 500 | 1000 |
1 | Футболка | Синий | Хлопок | 500 | 999 |
2 | Футболка | Желтый | Хлопок | 500 | 999 |
3 | Футболка | Красный | Хлопок | 500 | 999 |
5 | Рубашка | Белый | Хлопок | 600 | 999 |
Таблица выведена на экран

Операция DELETE

Приведенный ниже код удаляет данные из таблицы mystore с помощью операции DELETE и выводит на экран обновленные записи:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
public class Delete {
// Учетные данные для подключения
static final String DB_URL = "jdbc:postgresql://<IP-адрес>/postgres"; //Замените на свой IP
static final String USER = "postgres";
static final String PASS = "пароль"; //Замените на пароль postgres
public static void main(String[] argv) {
String query = "delete from mystore where Материал != 'Хлопок'"; //Удаление записей из таблицы
try (Connection con = DriverManager.getConnection(DB_URL, USER
, PASS);
PreparedStatement pst = con.prepareStatement(query)){
pst.executeUpdate();
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Данные в таблице обновлены");
// Далее идет код вывода результата из предыдущего шага
query = "select * from mystore";
try (Connection con = DriverManager.getConnection(DB_URL, USER
, PASS);
PreparedStatement pst = con.prepareStatement(query);
ResultSet rs = pst.executeQuery()) {
ResultSetMetaData meta = pst.getMetaData(); //Получение и вывод названий столбцов таблицы
for (int i=1; i <= meta.getColumnCount(); i++)
{
System.out.print(meta.getColumnName(i) + " | ");
}
System.out.print("\n");
while (rs.next()) { //Построчный вывод содержимого таблицы
for (int i=1; i <= meta.getColumnCount();
i++)
{
System.out.print(rs.getString(i) + " | ");
}
System.out.print("\n");
}
} catch (Exception e2) {
System.err.println("Операция выполнена с ошибкой");
System.err.println(e2);
System.exit(2);
}
System.out.println("Таблица выведена на экран");
}
}

Скомпилируйте программу и выполните ее:

java -cp ./postgresql-42.2.24.jar delete.java
Данные в таблице обновлены
id | Тип | Цвет | Материал | Запас | Цена |
1 | Футболка | Синий | Хлопок | 500 | 999 |
2 | Футболка | Желтый | Хлопок | 500 | 999 |
3 | Футболка | Красный | Хлопок | 500 | 999 |
5 | Рубашка | Белый | Хлопок | 600 | 999 |
Таблица выведена на экран