Здравейте.
Предполагам, че повечето от вас използват Perl за каквото и аз - web програмиране.
Това с което съм се сблъсквал досега е било горе-долу почти едно и също - вземане на стойности от базата данни, промяната им, изтриване и др. подобни действия, както и разбира се - обработката на шаблони в HTML кода, за да се изпринтят желаните стойности.
При писането на кодове, въпреки усилията чрез подаване на различни параметри, и по този начин генерирайки разновидности на SQL стрингове, винаги ми се е налагало да имам по няколко функции, които да обработват по различен начин данните от базата. В случая говоря специално и единствено за вземането им.
И когато имам една основна таблица с примерно 25-40 колони и свързаните с това понякога десетки други таблици релативни към Основната, и имам нуждата да вземам примерно по 15 различни начина тези данни, понеже не винаги искам да вземам всички данни от таблиците, става една дълга и широка ...
Та стига съм се отплесвал, а да си дойда на думата.
Идеята ми е, вместо да пиша примерно 15 различни функции според начина по които искам да взема данните, да направя едно Описание на Основната таблица и на това как тя се свързва с другите таблици, и използвайки това описание да генерирам подходящия SQL израз, чрез който да взема исканите данни, по желания начин. И това вземане с помощта на описанието да стане само с една и винаги да е с тази една функция. Един SQL израз обаче може да бъде доста комплексен при такъв брой на колони и таблици. Какво трябва да бъде това описание, за да направя това което искам?!
Какво все пак имаме при един SQL израз?
В най-общия случай, това: SELECT колони FROM таблици WHERE условия_за_селекция;
Да го разделим на 3 части:
1 - SELECT колони
2 - FROM таблици
3 - WHERE условия_за_селекция
Какви типове колони имаме, пак в най-общ вид:
1. Прости - такива който не ни сързват с други таблици, трябват ни директните им стойности
2. Релативни - Такива чрез които свързваме две таблици
2.1. - За връзки от тип One To One
2.2. - За връзки от тип One To Many
3. Участващи в условия за селекция в WHERE часта на стринга.
Да разгледаме следната структура (Не всички ключове във вътрешния хеш е нужно да участват, ще обясня после):
{някоя_колона} => {таблица_за_релация} = Име на таблицата с която някоя_колона образува релация
{колони_за_вземане} = Имената на колоните от таблица_за_релация на които искаме да вземем стойностите
{колона_за_релация} = Името на колоната от таблица_за_релация чрез която свързваме двете таблици
{колона_за_WHERE_условие} = Името на колоната която участва при дадено условие в WHERE часта
{Синтаксис_при_SELECT} = синтаксис в SELECT часта на SQL-а, който можем да искаме да използваме за тази колона
{Синтаксис_при_WHERE} = синтаксис в WHERE часта на SQL-а, който можем да искаме да използваме за тази колона
Сега да обясня за какво ще ми послужи тази структура.
{таблица_за_релация} - когато колона е от тип 2.1, значи трябва да свържем две таблици. Трябва да укажем кои са тези таблици:
FROM table_1, table_2 ...
Стойноста на този ключ ни дава реалното име на table_2. table_1 я знаем, тя си ни е основната таблица, тази с десетките колони.
{колони_за_вземане} - когато свързваме две таблици, искаме да вземем определени колони от тях. Стойноста на този ключ ни дава имената на колоните от table_2. Колоните от table_1 (основната) ги знаем, това са външните ключове (някоя_колона).
SELECT някоя_колона, table_2.some_column_1, table_2.some_column_x ...
(в момента не ме интересува каква е стойноста на този ключ, т.е. имената на колоните от table_2, дали е масив с имената им, и после ги join-вам, или пък са директно като стринг)
{колона_за_релация} - Името на колоната от table_2 чрез която осъществявам релацията. Името на колоната от table_1 e някоя_колона.
WHERE някоя_колона = table_2.колона_за_релация ...
{колона_за_WHERE_условие} - Това е в случай, че имам колона от тип 3. Не мога да разчитам, че това е колоната някоя_колона, тъй като може някоя_колона да участа само в релацията.
WHERE колона_за_WHERE_условие = x ...
(колона_за_WHERE_условие може да е някоя_колона или колона от table_2)
{Синтаксис_при_SELECT} - ако например колоната е тип 'date' (в базата данни), евентуално ще искам да я форматирам по някакъв начин. Не мога просто да напиша SELECT някоя_колона ... , а ще искам например да е
SELECT YEAR(някоя_колона) ...
Ако искам да е подобно, указвам го като стойност на този ключ.
{Синтаксис_при_WHERE} - подобно като {Синтаксис_при_SELECT}, но важи за WHERE часта на SQL-a. Например:
WHERE MONTH(някоя_колона) = x ...
Ето един пример на цялата работа:
MainTable Country
------------------------------ -------------------------
| ID | Country_id | date_add | | cnt_id | country_name |
------------------------------ -------------------------
%structure = ( ID => { колона_за_WHERE_условие => 'ID' },
Country_id => { таблица_за_релация => 'Country',
колони_за_вземане => 'country_name',
колона_за_релация => 'cnt_id',
колона_за_WHERE_условие => 'country_name' },
date_add => { Синтаксис_при_SELECT => 'MONTH(date_add)' } );
Исканият SQL стринг според описанието трябва да е:
SELECT ID, Country_id, country_name, MONTH(date_add)
FROM MainTable, Country
WHERE ID = x AND Country_id = cnt_id AND country_name = 'България';
Някой сигурно ше попита откъде се взе тва MainTable, или това х, или пък България?
Ами MainTable е Основната таблица за която говорих, името и ще е в отделна променлива, но може да бъде променено това.
х, България - това са външни стойности, евентуално дошли като параметър на CGI скрипта или откъдето искате, не е от значение. Това как ще се появят там съм го измислил по подобен начин, доста по-прост обаче от %structure, но няма да се спирам на това сега.
Значи това е основната идея, определено има какво да се добави към нея, но и без това поста стана доста обемист, а предполагам и труден за разбиране.
Ще съм благодарен за мнения и/или предложения по подобни въпроси.
Чао от мен, и have fun with Perl :-)
P.S. тук не разглеждам начин за вземане на данни от тип 2.2. - One To Many, понеже това не става по този начин, налага се допълнителна обработка на подобни данни, за да се приведат във вид за заместване на шаблони в HTML.
]
|