الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤال عن هرمية التصنيفات

بدأه أبو محمد اللحياني في 1 أكتوبر 2008 · 3 رد · 1,219 مشاهدة · في قواعد بيانات MySQL
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

عندي مسألة في عبارة SQL صعُب علي حلها ، وهي :

عندي جدول واحد عن التصنيفات :

CREATE TABLE `topics` (

`topicid` int(6) NOT NULL auto_increment,
`topicname` varchar(80) collate utf8_general_ci NOT NULL,

`topicparent` int(11) NOT NULL default '0',

`level` smallint(2) NOT NULL default '1',
`is_visible` smallint(1) NOT NULL default '1',
PRIMARY KEY  (`topicid`)
) 
ENGINE=MyISAM  DEFAULT CHARSET=utf8;

وفيه الحقول التالية :

INSERT INTO `topics` (`topicid`, `topicname`, `topicparent`, `level`, `is_visible`) VALUES
(1, 'التفسير', 0, 1, 1),
(2, 'تفسير القرآن بالمأثور', 1, 1, 1),
(3, 'الصنيف الأب 2', 0, 3, 1),
(4, 'التصنيف الابن 2', 3, 1, 1),
(5, 'التاريخ الإسلامي', 0, 1, 0),
(6, 'تاريخ الدولة العباسية', 5, 1, 1);

انظر المرفق : topics_table.gif

وفيه الحقل ( topicparent ) يشير إلى رقم التصنيف الأب للسجل الحالي . ويوضِّح أن :

التصنيف ( التفسير بالمأثور ) تابع للتصنيف ( التفسير ذو الرقم 1 ) .

التصنيف ( التصنيف الابن 2 ) تابع للتصنيف ( التصنيف الأب 2 ذو الرقم 3 ) .

التصنيف ( تاريخ الدولة العباسية ) تابع للتصنيف ( التاريخ الإسلامي ذو الرقم 5 ) .

والمطلوب التالي إنشاء VIEW يحمل المواصفات التالية :

1 - فيه الحقل [ category ] وهو اسم التصنيف الأب للسجل الحالي، وهذه وقعت على حلها أثناء كتابة السؤال .

2 - فيه الحقل [ level ] ويحمل القيمة العليا سواء كانت قيمة الحقل level للسجل الحالي أو لأحد السجلات الأصول - التصنيفات الآباء - بهدف أنا إذا خصصنا تصنيفاً بفئة أو مجموعة من المستخدمين فإنه يعمم على جميع التصنيفات الفرعية له، وينحجب هو وفروعه عن الأعضاء الآخرين الذين يحملون مستوى أقل .

3 - فيه الحقل [ is_visible ] ويحمل القيمة الأدنى سواء كانت للسجل الحالي أو لأحد سجلات الصنيفات الأصول ( الآباء ) بهدف أنّا إذا أخفينا أحد التصنيفات فستختفي جميع فروعه وفروع فروعه لأنها تحمل نفس قيمة الحقل is_visible الخاص به .

وهذا التكنيك لأجل تسهيل الإخفاء والتخصيص بدون تجشم مشقة تعديل UPDATE جميع السجلات الفرعية لتصنيف معين .

وقد حاولت إنشاء الـ VEIW ولكن دماغي يعمل hang فكانت هذه المحاولة التالية :

CREATE VIEW vwTopics AS
SELECT 
	topicid AS id, 
	topicname AS title, 
	topicparent AS parent, 
	(SELECT topicname FROM topics WHERE topicid=parent) AS category,
	CALL getLevel(id) AS level, /*  محل السؤال */
	CALL getVisible(id) AS is_visible  /*  محل السؤال  */
FROM topics  
WHERE (is_visible > 0);

post-71437-1222887276_thumb.gif

تم تعديل هذه المشاركة بواسطة أبو محمد اللحياني في 1 أكتوبر 2008 في 21:56

ولو وافيت ربك دون ذنب *** وناقشك الحساب إذاً هلكتا

ولم يظلمك في عملٍ ولكن *** عسير أن تقوم بما حملتا

#2

يظهر أن سؤالي تافه أو غير مفهوم !!

حاولت عمل دالة تعطيني الخلاصة النهائية لقيمة الحقل `level` أي القيمة العليا سواء للسجل الحالي أو للسجلات الأباء :

create function getLevel (id INT) RETURNS  smallint( 2 )
begin
	DECLARE parent INT DEFAULT 0;
	DECLARE minlevel smallint DEFAULT 1;
	DECLARE lvl smallint DEFAULT 1;
	SELECT `topicparent`, `level` INTO parent, minlevel FROM topics WHERE topicid=id;
	WHILE parent>0 DO
		SET id = parent;
		SELECT `topicparent`, `level` INTO parent, lvl FROM topics WHERE topicid=id;
		IF lvl>minlevel THEN SET minlevel = lvl;
	END WHILE 
	RETURN minlevel;
end;

ولكن تعطيني الخطأ التالي :

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3

يعني الصيغة خاطئة راجع الـ manual مع أن الصيغة فيما يظهر لي صحيحة .

تم تعديل هذه المشاركة بواسطة أبو محمد اللحياني في 2 أكتوبر 2008 في 16:15

ولو وافيت ربك دون ذنب *** وناقشك الحساب إذاً هلكتا

ولم يظلمك في عملٍ ولكن *** عسير أن تقوم بما حملتا

#3

الحمد لله أولاً وآخراً وحسب .

لقد تم بفضله سبحانه إيجاد الحل .

وانصح إخواني ألا يعتمدوا على phpMyadmin فقط في إرسال أوامر sql أو إدارة قواعد البيانات ، فقد كان يستحي أن يعطيني الخطأ كاملاً بينما البرنامج MySQL Administrator من نفس موقع mysql يعطيني الخطأ بالتفصيل .

وإليكم الحل :

CREATE FUNCTION getLevel (id INT(10), parent int(6), maxlevel smallint(2)) RETURNS  smallint( 2 )
begin
	DECLARE lvl smallint DEFAULT 1;
	WHILE parent>0 DO
		SET id = parent;
		SELECT `topicparent`, `level` INTO parent, lvl FROM topics WHERE topicid=id;
		IF (lvl>maxlevel) THEN SET maxlevel = lvl; END IF;
	END WHILE;
	RETURN maxlevel;
end;
----------------------------------------------------
CREATE FUNCTION getVisible (id INT(10), parent int(6), minVisible smallint(1)) RETURNS  smallint( 1 )
begin
	DECLARE visible smallint DEFAULT 1;
	WHILE parent>0 DO
		SET id = parent;
		SELECT `topicparent`, `level` INTO parent, visible FROM topics WHERE topicid=id;
		IF (visible<minVisible) THEN SET minVisible = lvl; END IF;
	END WHILE;
	RETURN minVisible;
end;
----------------------------------------------------
CREATE VIEW vw_topics AS
SELECT 
	topicid AS id, 
	topicname AS title, 
	topicparent AS parent, 
	(SELECT topicname FROM topics WHERE topicid=parent) AS category,
	(SELECT getLevel(id, parent, level)) AS level, 
	(SELECT getVisible(id, parent, is_visible)) AS is_visible
FROM topics  
WHERE (is_visible > 0);
---------------------------------------------------

تم تعديل هذه المشاركة بواسطة أبو محمد اللحياني في 3 أكتوبر 2008 في 22:19

ولو وافيت ربك دون ذنب *** وناقشك الحساب إذاً هلكتا

ولم يظلمك في عملٍ ولكن *** عسير أن تقوم بما حملتا

#4

اعجبتني فكرة طرح السؤال ثم الجواب

إن شاء الله في القريب العاجل ساقوم بدراسة الview و Function وساعود لموضعك واقرأة بالتفصيل للاستزادة

Logo150_60.jpg

مواضيع مشابهة