Archive

Posts Tagged ‘invalid data handling’

SQL_MODE ilə invalid data handling

İndiki mövzumuz data tiplərin minimum və maximum value və.s , həmçinin data type conversion dediyimiz bir şey haqqındadır. Söhbətimiz İNT və Varchar tipləri üzərində gedəcək.

Söhbətimizi əyani olaraq davam etdirək. Table yaradaq:

CREATE TABLE students (
    Stud_ID int(3) NOT NULL,
    Stud_Name VARCHAR(25) NOT NULL,
    Stud_Phone VARCHAR(5) NOT NULL,
    Stud_Address VARCHAR(50)
);

Qeyd edək ki, biz non-strict sql mode-unda işləyirik.
(MySQL-də SQL_MODE əhəmiyyəti)

set sql_mode='';

Daha sonra da insert-lər verək:

mysql> insert into students() values(1,'Orxan','0554962101','Yeni Yasamal');
Query OK, 1 row affected, 1 warning (0.11 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------+
| Level   | Code | Message                                         |
+---------+------+-------------------------------------------------+
| Warning | 1265 | Data truncated for column 'Stud_Phone' at row 1 |
+---------+------+-------------------------------------------------+
1 row in set (0.00 sec)

Gördüyümüz kimi, varchar(5) olan sütuna uzunluğu 10 olan bir məlumat daxil etdikdə o 5-ə truncate olunur.
select

Davam edək indi int-ə(stud_id) daha uzun bir məlumat daxil edək:

mysql> insert into students() values(444444,'Elvin','05567','Sovetski');
Query OK, 1 row affected (0.11 sec)

Nə error nə də ki bir Warning var və məlumat öz qaydasında daxil edilir:
select2

Demək ki, int(3) yazılsa da 3-də daha uzun bir rəqəm ora daxil edilə bilərmiş.
indi isə int-ə hər hansı bir string, varchar-a isə hər hansı bir rəqəm daxil edək:

mysql> insert into students() values('Mahmud',12345,'05078','Iceriseher');
Query OK, 1 row affected, 1 warning (0.11 sec)

stud_id int-dir ora ‘Mahmud’,stud_name varchar-dır ora 12345 daxil edirik.və nəticədə Warning görürük.
warnings

insert

Yuxarıdan aydın olur ki,non-strict sql_mode-da, int tipli column-a string insert etmək istədikdə MySQL həmin string-in yerinə 0 daxil edir!. Amma varchar tipli column-a integer daxil etdikdə onu olduğu kimi daxil edir. Demək ki, kimsə səhv edib tipləri qarışdırsa ağzına gələni daxil edəcək 🙂 bir daha deyirəm bu non-strict sql_mode-da belədir

İndi isə column definition-larda data type-ların özlərini dəyişək. Yəni table içində düzgün məlumatlar ola-ola int->varchar, varchar->int conversion edək. Təsəvvür edək ki, aşağıdakı məlumatlar var:

mysql> select * from students;
+---------+-----------+------------+--------------+
| Stud_ID | Stud_Name | Stud_Phone | Stud_Address |
+---------+-----------+------------+--------------+
|       1 | Orxan     | 05549      | Yeni Yasamal |
|  444444 | Elvin     | 05567      | Sovetski     |
|       2 | Mahmud    | 05078      | Iceriseher   |
+---------+-----------+------------+--------------+
3 rows in set (0.00 sec)

stud_id-nin data tipini varchar edək:

mysql> alter table students modify stud_id varchar(3) not null;
Query OK, 3 rows affected, 1 warning (0.32 sec)
Records: 3  Duplicates: 0  Warnings: 1

warning-ə baxaq və select verək:
select5

Yaxşı bayaqdan int-ə string gedir, data truncate olur və.s…Aləm dəyib bir-birinə 🙂 Bunun qarşısını alacaq bir şey yoxdur mu? Yəni ən azından əgər data truncate olacaqsa bir ERROR çıxsın ortaya…Məsələn, yuxarıdakı kimi int-ə string insert etmək istədikdə 0 daxil etməsin onun əvəzinə ERROR versin ki, işimizi bilək…
Adətən bu cür check-ləri PHP-də edirlər mən bilən. Data İnput Handling(error handling) deyilir səhv etmirəmsə buna. Mən bütün PHP programmer-ləri bu işi MySQL-in üstünə atmağa dəvət edirəm. 🙂
Cox sadə yolu var…STRİCT sql_mode. Bayaqkı bütün nümunələrimiz non-strict sql_mode-da çalışmışdı indi isə STRİCT-də işlədək. Yəni sql_mode-u dəyişək:

mysql> set sql_mode='traditional';
Query OK, 0 rows affected (0.00 sec)

Və indi də bayaqdan yazdıqlarımızı bir daha yazmağa çalışaq…
varchar(5) olan sütuna uzunluğu 10 olan bir məlumat daxil etdikdə:

mysql> insert into students() values(1,'Orxan','0554962101','Yeni Yasamal');
ERROR 1406 (22001): Data too long for column 'Stud_Phone' at row 1

Bəh bəh nə gözəl bir ERROR…

Daha sonra , int-ə hər hansı bir string, varchar-a isə hər hansı bir rəqəm daxil etdikdə:

mysql> insert into students() values('Mahmud',12345,'05078','Iceriseher');
ERROR 1366 (HY000): Incorrect integer value: 'Mahmud' for column 'stud_id' at r

Yenə bəh bəh… 🙂

Gördüyümüz kimi strict sql_mode-u enable etməklə biz təminat alırıq ki, int tipli column-da yalnız integer olacaq və həmçinin də hər hansı varchar(5) olan column-a yalnız 5 simvollu string daxil ediləcək…Əgər belə olmazsa ERROR alacıq.
Hər kəsi sql_mode-a daha çox fikir verməyə çağırıram, çünki bir çoxu işləri yüngülləşdirir.

SQL_MODE haqqında daha ətraflı :
MySQL-də SQL_MODE əhəmiyyəti

Təşəkkürlər…

View ilə invalid data handling

View və ondan istifadə səsəbləri,həmçinin view-dan necə istifadə etmək lazımdı ondan danışacıq.Daha sonra isə view vasitəsilə invalid data handling-ə baxacıq. Buna oxşar bir yazım var artıq SQL_MODE ilə invalid data handling
Aşağıdakı documentation-da View-dan istifadənin mümkün səbəbləri göstərilmişdir.Oxuyaraq davam edin…
Reasons to Use Views
Views provide several benefits compared to selecting data directly from base tables:

Access to data becomes simplified:

A view can be used to perform a calculation and display its result. For example, a view definition that invokes aggregate functions can be used to display a summary.

A view can be used to select a restricted set of rows by means of an appropriate WHERE clause, or to select only a subset of a table’s columns.

A view can be used for selecting data from multiple tables by using a join or union.
A view performs these operations automatically. Users need not specify the expression on which a calculation is based, the conditions that restrict rows in the WHERE clause, or the conditions used to match tables for a join.

Views can be used to display table contents differently for different users, so that each user sees only the data pertaining to that user’s activities. This improves security by hiding information from users that they should not be able to access or modify. It also reduces distraction because irrelevant columns are not displayed.

If you need to change the structure of your tables to accommodate certain applications, a view can preserve the appearance of the original table structure to minimize disruption to other applications. For example, if you split a table into two new tables, a view can be created with the name of the original table and defined to select data from the new tables such that the view appears to have the original table structure.

View özünü virtual cədvəl kimi aparır. Hər hansı table-a sanki dolayısı ilə çatırsan. Bir cədvəlin ya tam kopyasını ya da müəyyən bizə lazım olan hissəsini çıxardaraq view yarada bilərik.
Misallarla izah etməyə calışaq. Table yaradaq(hazır dump faylımdan götürmüşəm):

CREATE TABLE employees (
  emp_id int(11) NOT NULL AUTO_INCREMENT,
  Emp_Name varchar(30) DEFAULT NULL,
  address varchar(10) NOT NULL,
  salary varchar(10) NOT NULL,
  PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=latin1;

Və insert edək:

INSERT INTO employees() VALUES (12,'Sales','0','2500'),(13,'IT','0','3500'),(14,'Admin','0','4500'),(15,'Admin','0','5500'),(16,'President','0','10500');


Bəli şəkildən də göründüyü kimi insert-imiz uğurludur və daha aşağıda da göründüyü kimi bizdə 4 column var.

İndi isə istəyirəm ki bu table üstündə bir view yaradım…Və bu view bütün column-lardan təşkil olunsun…

create view emp_view as select * from employees;

Və həqiqətən də employees table-ın bütün sütunlarından ibarət bir view yaradıldı

Select verdikdə isə görürük ki, employees cədvəlində olan bütün məlumatlar eynisi ilə emp_view-dədir:

İndi isə biraz dəyişikliklər etməklə müxtəlif view-lar yaradaq. employees cədvəlindən yalnız emp_id və emp_name-i götürək.

create view emp_view2 as select emp_id,emp_name from employees;


Indi isə salary-si 4500-dən çox olanları seçib view yaradaq:

alter table employees modify salary int not null;

create view emp_view3 as select * from employees where salary>'4500';


Bəli bizə lazım olan idi 🙂
Onu da qeyd edək ki, view vasitəsilə base table-ı (view yaradılarkən istifadə olunan cədvəl.indiki halda employees) UPDATE, DELETE və İNSERT yəni dəyişə bilərik. Bu haqda ətraflı yazmıram sadə bir şeydi əslində. Adi table-ı necə UPDATE, DELETE və İNSERT ediriksə view-nu da elə edirik.

*İnvalid Data Handling*
Bu Maraqlı xüsusiyyəti misal üzərində göstərməyə çalışaq. Bir yeni cədvəl yaradaq:

CREATE TABLE employee(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(15),
salary DOUBLE,
PRIMARY KEY(id)
);

Və VIEW yaradaq:

CREATE VIEW emp_view AS
SELECT *
FROM for_view
WHERE salary>2000 WITH CHECK OPTION;

Table boş olsa belə View yarada bilərik. İndi isə VIEW vasitəsilə insert verək:

INSERT INTO emp_view(name,salary) VALUES('Orxan',3000);

İndi isə bir başqa insert:

INSERT INTO emp_view(name,salary) VALUES('Esger',1500);

İndi isə izah edək. Deyək ki bizə lazımdı ki , hər hansı bir user işçilərin maaşlarını daxil edərkən 2000-dən aşağı maaşları (səhvən) daxil etməsin(çünki 2000-dən aşağı maaş alan yoxdu 😛 ). Və yaxud istənilən başqa şərt. Və əgər belə bir şey olsa bu rəqəm daxil edilməsin, əksinə error versin.

SQL Error (1369): CHECK OPTION failed 'test.emp_view'

Bunun səbəbi VIEW-nu yaradarkən WITH CHECK OPTION-nun əlavə edilməsidir.Təbii ki user input-u hər hansı kodla da yoxlamaq olar amma mənə elə gəlir ki, bu daha sadədir.
Və əgər yoxlasaq görərik ki, həm base table, həm də view dəyişilib və səhv məlumat həqiqətən də daxil edilməyib.

Təbii ki, istənilən VIEW ilə bunları etmək olmur.Yalnız UPDATABLE VIEW sayılan VIEW-lar.UPDATE,DELETE və İNSERT oluna bilən VIEW-lar UPDATABLE VIEW adlanırlar.
Hər hansı VIEW-nun UPDATABLE olub-olmadığını öyrənmək üçün:

SELECT * FROM information_schema.views WHERE table_name='emp_view' AND table_schema='test';

İS_UPDATABLE:YES — bəli bu VIEW UPDATABLE-dır.
VIEW metadata-nı həm də :

SHOW CREATE TABLE emp_view;

Və ya:

SHOW CREATE VIEW emp_view;

Daha ətraflı:
CREATE VIEW Syntax
Using Views
Updatable and Insertable Views
The INFORMATION_SCHEMA VIEWS Table

Kateqoriyalar: MySQL Etiketlər: , , ,