<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: SQL</title><link>https://academy.hsoub.com/programming/sql/page/2/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: SQL</description><language>ar</language><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645; &#x639;&#x646; &#x627;&#x644;&#x633;&#x62C;&#x644;&#x627;&#x62A; &#x645;&#x646; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%B3%D8%AC%D9%84%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r2249/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_02/-------SELECT-FROM--SQL.png.28347c5112ce8b14f7997b9551e6192e.png" /></p>
<p>
	ينطوي التعامل مع قواعد البيانات بشكلٍ أساسيّ على استخراج المعلومات حول البيانات المُخزّنة ضمنها. ويُطلق مصطلح الاستعلام query على أي عملية لاسترجاع المعلومات من جدول في أنظمة إدارة قواعد البيانات العلاقية.
</p>

<p>
	سنبحث في هذا المقال في بنية الاستعلامات بلغة الاستعلام البنيوية <span ipsnoautolink="true">SQL</span> وبعض الوظائف والعوامل الأكثر استخدامًا فيها.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز كمبيوتر يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العلاقية RDBMS التي تستخدم <a href="https://academy.hsoub.com/programming/sql/" rel="">SQL</a>. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، وللقيام بذلك يمكنك الاطلاع على المقال <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		MySQL مثبتة ومؤمنة على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في الخطوة 3 من هذا المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقية <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-%D8%A8%D9%8A%D9%86-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-sqlite-%D9%85%D8%B9-mysql-%D9%85%D8%B9-postgresql-r72/" rel="">RDBMS</a> لها تقديماتها الفريدة من لغة SQL. فبالرغم من كون الأوامر المُقدمة في هذا المقال ستعمل مع معظم هذه الأنظمة، ولكن قد تجد بعض الاختلافات في الصيغة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، ستحتاج أيضًا إلى قاعدة بيانات وجدول مُحمّل ببعض البيانات التجريبية النموذجية لتتمكن من التدرب على كتابة الاستعلامات. لذا ننصحك بقراءة القسم القادم الاتصال بـ MySQL وإعداد <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">قاعدة بيانات</a> تجريبية نموذجية للمزيد من التفاصيل حول كيفية إعداد قاعدة بيانات وجدول لاستخدامهما في الأمثلة خلال هذا المقال.
</p>

<h2 id="mysql">
	الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم عن بُعد، اتصل بالخادم مُستخدمًا بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr> من جهازك المحلي على النحو:
</p>

<pre class="ipsCode">$ ssh ssh user@your_server_ip
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_12" style=""><span class="pln">$ mysql </span><span class="pun">-</span><span class="pln">u user </span><span class="pun">-</span><span class="pln">p</span></pre>

<p>
	الآن ومن نافذة سطر الأوامر، أنشئ قاعدة بيانات باسم <code>queries_DB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_20" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE queries_DB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد <a href="https://wiki.hsoub.com/SQL/create_database" rel="external">إنشاء قاعدة البيانات</a> بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>queries_DB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_17" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE queries_DB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	بعد تحديد قاعدة البيانات <code>queries_db</code>، سننشئ عدة جداول داخلها.
</p>

<p>
	للمتابعة مع الأمثلة المستخدمة في هذا المقال، تخيل أنك تدير مبادرة لتنظيف المنتزهات العامة في مدينة ما. إذ تضم المبادرة عددًا من المتطوعين الملتزمين بتنظيف منتزه المدينة الأقرب لمنازل كل منهم من خلال جمع القمامة بانتظام. ولدى الانضمام إلى المبادرة، يضع كل متطوع هدفًا لعدد أكياس القمامة التي يود جمعها كل أسبوع. وبفرض أننا قررنا تخزين المعلومات حول أهداف المتطوعين في قاعدة بيانات <code>SQL</code> باستخدام جدول يحتوي على خمسة أعمدة، على النحو:
</p>

<ul>
	<li>
		<code>vol_id</code>: مُعرّف كل متطوع، مُعبرًا عنه بنمط بيانات الأعداد الصحيحة <code>int</code>. سيكون هذا العمود هو المفتاح الأساسي للجدول، مما يعني أن كل قيمة منه ستلعب دور المعرّف الفريد لسجلها المقابل. ونظرًا لأن كل قيمة في المفتاح الأساسي يجب أن تكون فريدة، فسيتم تطبيق قيد <code>UNIQUE</code> على هذا العمود أيضًا.
	</li>
	<li>
		<code>name</code>: اسم كل متطوع، مُعبرًا عنه بنمط البيانات <code>varchar</code> بحد أقصى 20 محرفًا.
	</li>
	<li>
		<code>park</code>: اسم المنتزه التي سيجمع فيها كل متطوع القمامة، مُعبرًا عنه بنمط البيانات <code>varchar</code> بحد أقصى 20 محرفًا. لاحظ أنه يمكن لعدة متطوعين تنظيف نفس المنتزه.
	</li>
	<li>
		<code>weekly_goal</code>: هدف كل متطوع لعدد أكياس القمامة التي يرغب في جمعها في الأسبوع، مُعبرًا عنه بنمط البيانات <code>int</code>.
	</li>
	<li>
		<code>max_bags</code>: الرقم القياسي الشخصي لكل متطوع لأكبر عدد من أكياس القمامة التي جمعها في أسبوع واحد، مُعبرًا عنه بنمط البيانات عدد صحيح <code>int</code>.
	</li>
</ul>

<p>
	أنشئ جدولًا باسم <code>volunteers</code> يحتوي على هذه الأعمدة الخمسة بتنفيذ تعليمة <code>CREATE TABLE</code> على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_22" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE volunteers </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> vol_id </span><span class="kwd">int</span><span class="pln"> UNIQUE</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> park varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> weekly_goal </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> max_bags </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> PRIMARY KEY </span><span class="pun">(</span><span class="pln">vol_id</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	بعد إنشاء جدول <code>volunteers</code>، املأه ببعض البيانات النموذجية. نفّذ تعليمة <code><a href="https://wiki.hsoub.com/SQL/insert" rel="external">INSERT INTO</a></code> التالية لإضافة سبع سجلات تمثل سبعة من متطوعي البرنامج:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_24" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO volunteers
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Gladys'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Prospect Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Catherine'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Central Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Georgeanna'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Central Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Wanda'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Van Cortland Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Ann'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Prospect Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">7</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Juanita'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Riverside Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Georgia'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Prospect Park'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">);</span></pre>

<p>
	وبذلك غدوتَ جاهزًا لمتابعة باقي المقال والبدء في تعلم كيفية إنشاء الاستعلامات في لغة الاستعلام البنيوية <a href="https://wiki.hsoub.com/SQL" rel="external">SQL</a>.
</p>

<h2 id="selectfrom">
	مكونات الاستعلام الأساسية: بنيتي SELECT و FROM
</h2>

<p>
	تُعرّف التعليمة البرمجية في SQL بأنّها أي عملية تُرسَل إلى نظام قاعدة البيانات لتنفيذ مهمّة محددة، من قبيل إنشاء جدول أو إدخال أو حذف بيانات أو تغيير هيكلية عمود أو جدول. وما الاستعلام سوى تعليمة برمجية في SQL تسترجع معلومات حول البيانات المحفوظة في قاعدة البيانات.
</p>

<p>
	لن يُغير الاستعلام أي بيانات موجودة في جدول من تلقاء نفسه، إذ سيقتصر الأمر فقط على استرجاع المعلومات حول البيانات التي يطلبها مُنشئ الاستعلام بشكلٍ صريح. ويُشار إلى المعلومات التي يُعيدها استعلام معين بمجموعة نتائجه. والتي عادةً ما تتكون من عمود واحد أو أكثر من جدول محدد، وكل عمود يُعاد في مجموعة النتائج يمكن أن يحتوي على سجل واحد أو أكثر من المعلومات.
</p>

<p>
	فيما يلي الصيغة العامة لاستعلام SQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_28" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT columns_to_return
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM table_to_query</span><span class="pun">;</span></pre>

<p>
	تتألف تعليمات SQL من بنى مختلفة، والتي تتكون بدورها من كلمات مفتاحية معينة مع المعلومات التي تتطلبها هذه الكلمات. وفي هذا السياق تتطلب الاستعلامات في SQL منك تضمين بنيتين على الأقل، وهما: <code>SELECT</code> و <code>FROM</code>.
</p>

<p>
	<strong>ملاحظة</strong>: كُتبت كل بنية في هذه صيغة هذا المثال في سطرها الخاص. ولكن يمكن كتابة أي تعليمة برمجية في SQL على سطرٍ واحد على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_32" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT columns_to_return FROM table_to_query</span><span class="pun">;</span></pre>

<p>
	يتبع هذا المقال القاعدة الشائعة في أسلوب SQL بتقسيم التعليمات البرمجية على سطور متعددة بحيث يحتوي كل سطر على بنية واحدة فقط. والهدف من ذلك تحسين قابلية القراءة والفهم لكل مثال، لكن ينبغي الإشارة إلى أنه بإمكانك كتابة استعلام على سطر واحد أو توزيعه على عدة سطور، طالما أنه لا يحتوي على أخطاء في الصياغة.
</p>

<p>
	تبدأ كل استعلامات SQL عادةً ببنية <code>SELECT</code>، ولذلك يُشار إليها عمومًا بتعليمات <code>SELECT</code>. وتأتي بعد كلمة <code>SELECT</code> المفتاحية قائمة بأسماء الأعمدة التي ترغب في استرجاعها في مجموعة النتائج، والتي يتم اختيارها من الجدول المُحدد في بنية <code>FROM</code>.
</p>

<p>
	يبدأ تنفيذ العملية في استعلامات SQL من بنية <code>FROM</code>. الأمر الذي قد يبدو محيرًا نظرًا لأن بنية <code>SELECT</code> تُكتب قبل <code>FROM</code>، ولكن من الضروري أن يحدد نظام إدارة قواعد البيانات أولًا مجموعة البيانات الكاملة التي سيتم الاستعلام عنها قبل البدء في استرجاع المعلومات منها. يُفيد التفكير في الاستعلامات على أنها عملية اختيار <code>SELECT</code> لأعمدة محددة من <code>FROM</code> جدول مُعين. ومن المهم التذكير بأن كل تعليمة SQL يجب أن تختتم بفاصلة منقوطة (<code>;</code>).
</p>

<p>
	كمثال، نفذ الاستعلام التالي الذي يسترجع عمود <code>name</code> من جدول <code>volunteers</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_34" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT name
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<p>
	إليك مجموعة نتائج هذا الاستعلام:
</p>

<pre class="ipsCode">الخرج
+------------+
| name       |
+------------+
| Gladys     |
| Catherine  |
| Georgeanna |
| Wanda      |
| Ann        |
| Juanita    |
| Georgia    |
+------------+
7 rows in set (0.00 sec)
</pre>

<p>
	على الرغم من أن هذه العملية استعرضت جدول <code>volunteers</code> بأكمله، إلا أنها استرجعت فقط العمود المُحدد، ألا وهو <code>name</code>.
</p>

<p>
	يمكنك استرجاع المعلومات من عدة أعمدة عن طريق فصل اسماء الأعمدة بعلامات فاصلة، كما في الاستعلام التالي. إذ سيعيد هذا الاستعلام أعمدة <code>vol_id</code>, <code>name</code>, و <code>park</code> من جدول <code>volunteers</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_36" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT park</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> vol_id
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------------+------------+--------+
| park              | name       | vol_id |
+-------------------+------------+--------+
| Prospect Park     | Gladys     |      1 |
| Central Park      | Catherine  |      2 |
| Central Park      | Georgeanna |      3 |
| Van Cortland Park | Wanda      |      4 |
| Prospect Park     | Ann        |      5 |
| Riverside Park    | Juanita    |      6 |
| Prospect Park     | Georgia    |      7 |
+-------------------+------------+--------+
7 rows in set (0.00 sec)
</pre>

<p>
	لاحظ أنّ هذه النتيجة تُعيد العمود <code>park</code> أولًا، يليه عمود <code>name</code> ثم <code>vol_id</code>. تُعيد قواعد البيانات SQL الأعمدة عمومًا بالترتيب الذي تم سرده في بنية <code>SELECT</code>.
</p>

<p>
	قد تحتاج في بعض الأحيان إلى استرجاع كل الأعمدة من جدول ما. فبدلًا من كتابة أسماء كافّة الأعمدة في استعلامك، يمكنك ببساطة إدخال علامة النجمة (<code>*</code>). وهي الطريقة المختصرة في SQL، للدلالة على "كل الأعمدة".
</p>

<p>
	الاستعلام التالي سيُعيد كل الأعمدة من جدول <code>volunteers</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_38" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+--------+------------+-------------------+-------------+----------+
| vol_id | name       | park              | weekly_goal | max_bags |
+--------+------------+-------------------+-------------+----------+
|      1 | Gladys     | Prospect Park     |           3 |        5 |
|      2 | Catherine  | Central Park      |           2 |        2 |
|      3 | Georgeanna | Central Park      |           2 |        1 |
|      4 | Wanda      | Van Cortland Park |           1 |        1 |
|      5 | Ann        | Prospect Park     |           2 |        7 |
|      6 | Juanita    | Riverside Park    |           1 |        4 |
|      7 | Georgia    | Prospect Park     |           1 |        3 |
+--------+------------+-------------------+-------------+----------+
7 rows in set (0.00 sec)
</pre>

<p>
	لاحظ كيف تُعرَض الأعمدة في هذه النتيجة بنفس الترتيب المُحدّد في تعليمة <code>CREATE TABLE</code> من فقرة <strong>الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية</strong> السابقة. وهي الطريقة التي ستُرتب بها معظم أنظمة قواعد البيانات العلاقية الأعمدة في مجموعة النتائج عند تنفيذ استعلام يستخدم علامة النجمة (<code>*</code>) بدلًا من أسماء الأعمدة الفردية.
</p>

<p>
	ومن الجدير بالملاحظة أنّه من الممكن استرجاع المعلومات من عدة جداول في نفس الاستعلام باستخدام الكلمة المفتاحية <code>JOIN</code>. ونشجعك في هذا الصدد على قراءة مقال <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">استخدام عمليات الدمج في SQL</a>.
</p>

<h2 id="distinct">
	استبعاد القيم المكررة باستخدام DISTINCT
</h2>

<p>
	تُعيد أنظمة إدارة قواعد البيانات العلاقية افتراضيًا جميع القيم من أعمدة الجدول المُستعلم عنه، بما في ذلك القيم المكررة.
</p>

<p>
	كمثال، نفّذ الاستعلام التالي. إذ سيُرجع القيم من عمود <code>park</code> في جدول <code>volunteers</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_40" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT park
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------------+
| park              |
+-------------------+
| Prospect Park     |
| Central Park      |
| Central Park      |
| Van Cortland Park |
| Prospect Park     |
| Riverside Park    |
| Prospect Park     |
+-------------------+
7 rows in set (0.00 sec)
</pre>

<p>
	لاحظ أن مجموعة النتائج تتضمّن قيمتين مكررتين هما <code>Prospect Park</code> و<code>Central Park</code>. وهو أمر منطقي، إذ يمكن لعدد من المتطوعين التعاون في تنظيف نفس المتنزه. ومع ذلك، قد ترغب في بعض الأحيان بمعرفة القيم الفريدة المخزنة في عمود ما ويمكنك تحقيق ذلك وإزالة القيم المكررة من نتائج استعلامك باستخدام الكلمة المفتاحية <code>DISTINCT</code> بعد <code>SELECT</code>.
</p>

<p>
	سيُرجع الاستعلام التالي كافة القيم الفريدة من عمود <code>park</code>، مُستبعدًا أية قيم مكررة. وهو مُتشابه للاستعلام السابق ولكن مع إضافة كلمة <code>DISTINCT</code>، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_42" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT DISTINCT park
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------------+
| park              |
+-------------------+
| Prospect Park     |
| Central Park      |
| Van Cortland Park |
| Riverside Park    |
+-------------------+
4 rows in set (0.00 sec)
</pre>

<p>
	تحتوي مجموعة نتائج هذا الاستعلام على ثلاث سجلات أقل من الاستعلام السابق، بسبب إزالة إحدى قيم <code>Central Park</code> واثنتين من قيم <code>Prospect Park</code>.
</p>

<p>
	تجدر الإشارة إلى أن SQL تُعامل كل سجل في مجموعة النتائج كسجل فردي، وتُزيل <code>DISTINCT</code> القيم المكررة فقط في حال تشاركت عدة سجلات بنفس القيم في كل الأعمدة.
</p>

<p>
	لتوضيح ذلك، لنُصدر الاستعلام التالي المُتضمّن للكلمة المفتاحية <code>DISTINCT</code> والذي يُرجع كلا العمودين <code>name</code> و<code>park</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_44" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT DISTINCT name</span><span class="pun">,</span><span class="pln"> park
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+------------+-------------------+
| name       | park              |
+------------+-------------------+
| Gladys     | Prospect Park     |
| Catherine  | Central Park      |
| Georgeanna | Central Park      |
| Wanda      | Van Cortland Park |
| Ann        | Prospect Park     |
| Juanita    | Riverside Park    |
| Georgia    | Prospect Park     |
+------------+-------------------+
7 rows in set (0.00 sec)
</pre>

<p>
	تشتمل مجموعة النتائج هذه على قيم مكررة في عمود <code>park</code>، بواقع ثلاث تكرارات لقيم <code>Prospect Park</code> وتكرارين لقيم <code>Central Park</code>، وذلك على الرغم من إدراج الكلمة المفتاحية <code>DISTINCT</code> في الاستعلام. فعلى الرغم من احتواء الأعمدة الفردية في مجموعة النتائج على قيم مكررة، لكن يجب أن تكون السجلات متطابقة بالكامل لتُستبعد من قبل <code>DISTINCT</code>. وفي حالتنا، ونظرًا لأن القيم في عمود <code>name</code> فريدة لكل سجل، فإن <code>DISTINCT</code> لن تزيل أي من السجلات لدى تحديد هذا العمود ضمن بنية <code>SELECT</code>.
</p>

<h2 id="where">
	تصفية البيانات باستخدام بنى WHERE
</h2>

<p>
	قد ترغب في بعض الحالات باسترجاع معلومات أكثر تحديدًا من جداول قاعدة البيانات. إذ يمكنك تصفية سجلات معينة بإدراج بنية <code>WHERE</code> في استعلامك بعد بنية <code>FROM</code>، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_46" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT columns_to_return
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM table_to_query
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE search_condition</span><span class="pun">;</span></pre>

<p>
	يأتي شرط البحث بعد كلمة <code>WHERE</code> في الصيغة المذكورة بالمثال، والذي يُحدّد على وجه الخصوص أي السجلات مُراد تصفيتها من مجموعة النتائج. وما شرط البحث سوى مجموعة من التوابع الشرطية أو التعبيرات القادرة على تقييم تعبير قيمة واحد أو أكثر. إذ يُعرّف تعبير القيمة في لغة SQL - والذي يُشار إليه أحيانًا باسم التعبير ذو القيمة المفردة - بأنّه أي تعبير يُعيد قيمة واحدة. ويمكن أن يكون تعبير القيمة عبارة عن قيمة محددة النوع (سلسلة نصية أو قيمة عددية)، أو تعبير رياضي، أو اسم عمود.
</p>

<p>
	يمكن أن تأخذ التوابع الشرطية في شرط البحث الخاص ببنية <code>WHERE</code> أشكالاً مختلفة، ولكنها عادةً ما تتبع الصيغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_48" style=""><span class="pln">WHERE </span><span class="kwd">value</span><span class="pln"> expression OPERATOR value_expression</span></pre>

<p>
	فقد وضعنا بعد الكلمة المفتاحية <code>WHERE</code> في هذه الصيغة تعبير قيمة، يليه أحد معاملات SQL الخاصة والمُستخدمة لتقييم قيم الأعمدة بالنسبة لتعبير القيمة (أو تعابير القيم) الآتي بعد العامل.
</p>

<p>
	وهناك العديد من هذه العوامل المتاحة في SQL، وسنقدّم في هذا القسم لمحة موجزة عن بعضها، ولكن لغرض التوضيح سنركّز فقط على أحد أكثر العوامل استخدامًا، ألا وهو: علامة المساواة (<code>=</code>). يختبر هذا العامل ما إذا كان تعبيرين يحتويان على قيم متطابقة.
</p>

<p>
	دائمًا ما تُعطي التوابع الشرطية الناتج "صحيح True" أو "خاطئ False" أو "غير محدد Unknown". فلدى تشغيل استعلامات SQL التي تحتوي على بنية <code>WHERE</code>، سيطبّق نظام إدارة قاعدة البيانات شرط البحث تتابعيًا على كل سجل في الجدول المحدد في بنية <code>FROM</code>. ولن يعيد سوى السجلات التي يُقيّم فيها كل شرط بحث على أنه "صحيح".
</p>

<p>
	لتوضيح هذه الفكرة، نفّذ تعليمة <code>SELECT</code> التالية. يُرجع هذا الاستعلام قيمًا من عمود <code>name</code> في جدول <code>volunteers</code>. لكن بدلًا من تقييم قيم أحد أعمدة الجدول، تختبر بنية <code>WHERE</code> في هذا الاستعلام ما إذا كان التعبير <code>(2 + 2)</code> و <code>4</code>  متساويين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4077_8" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT name
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE </span><span class="pun">(</span><span class="lit">2</span><span class="pun">+</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pun">;</span></pre>

<p>
	ونظرًا لأنّ التعبير <code>(2+2)</code> يساوي <code>4</code> دائمًا، فإن شرط البحث هذا يُقيّم بأنه صحيح لكل سجل في الجدول. ونتيجةً لذلك، تُرجع قيمة الاسم لكل سجل في مجموعة النتائج، على النحو:
</p>

<pre class="ipsCode">الخرج
+------------+
| name       |
+------------+
| Gladys     |
| Catherine  |
| Georgeanna |
| Wanda      |
| Ann        |
| Juanita    |
| Georgia    |
+------------+
7 rows in set (0.00 sec)
</pre>

<p>
	ولكن ونظرًا لأن شرط البحث هذا يعيد دائمًا نتيجة "صحيحة"، فهو ليس مفيدًا بدرجة كبيرة. وبالتالي من الممكن في هذه الحالة عدم تضمين بنية <code>WHERE</code> أصلًا، لأن تعليمة <code>SELECT name FROM volunteers;</code> ستعطي نفس مجموعة النتائج كما في حالة استخدام <code>WHERE</code> مع شرط بحث مُحقق دومًا.
</p>

<p>
	عادةً ما نستخدم اسم عمود كأحد تعبيري القيمة في شرط البحث ضمن بنية <code>WHERE</code> وذلك بدلاً من مقارنة قيمتين مُحددتي النوع كما في الأسلوب أعلاه. وبذلك نُعلم نظام إدارة قاعدة البيانات باستخدام قيمة كل سجل من العمود المحدد كجزء من تعبير القيمة للتكرار الخاص بكل سجل في شرط البحث.
</p>

<p>
	تُطبّق بنية <code><a href="https://wiki.hsoub.com/SQL/where" rel="external">WHERE</a></code> في الاستعلام التالي شرط بحث أكثر تحديدًا على كل سجل. إذ ستُرجع قيم كل من عمودي <code>name</code> و <code>max_bags</code> من أي سجل تساوي فيه قيمة <code>max_bags</code> الرقم <code>4</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_57" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT name</span><span class="pun">,</span><span class="pln"> max_bags
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE max_bags </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pun">;</span></pre>

<p>
	يُرجع هذا الاستعلام سجل متطوع واحد فقط، نظرًا لأنّ قيمة <code>max_bags</code> لهذا المتطوع وحده تساوي <code>4</code> تمامًا، فيكون الخرج على النحو:
</p>

<pre class="ipsCode">الخرج
+---------+----------+
| name    | max_bags |
+---------+----------+
| Juanita |        4 |
+---------+----------+
1 row in set (0.00 sec)
</pre>

<p>
	يمكنك أيضًا تقييم قيم السلاسل النصية المحرفية في التوابع الشرطية الخاصة بشروط البحث. فمثلًا يُرجع الاستعلام التالي قيم عمودي <code>vol_id</code> و <code>name</code> لكل سجل تكون قيمة العمود <code>name</code> فيه مساوية لـ 'Wanda':
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_59" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT vol_id</span><span class="pun">,</span><span class="pln"> name
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM volunteers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Wanda'</span><span class="pun">;</span></pre>

<p>
	ونظرًا لوجود متطوعة واحدة فقط تُدعى <code>Wanda</code>، فإن الاستعلام يُرجع معلومات سجلها فقط:
</p>

<pre class="ipsCode">الخرج
+--------+-------+
| vol_id | name  |
+--------+-------+
|      4 | Wanda |
+--------+-------+
1 row in set (0.00 sec)
</pre>

<p>
	من الجدير بالملاحظة أنّنا استخدمنا نفس العامل لشرط البحث في جميع أمثلة هذا القسم وهو علامة المساواة وذلك لتوضيح الفكرة. ولكن يوجد العديد من أنواع المعاملات <a href="https://wiki.hsoub.com/SQL/operators" rel="external">Operators</a> الأخرى التي تتيح لنا إمكانية كتابة مجموعة متنوعة من التوابع الشرطية، مما يوفر مستوى عالٍ من التحكم في المعلومات التي تُرجعها الاستعلامات.
</p>

<p>
	يُحدّد معيار SQL ثمانية عشر نمطًا مختلفًا من التوابع الشرطية، وعلى الرغم من أنّها لا تتوفر كاملةً في كافّة أنظمة إدارة <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">قواعد البيانات العلاقية</a> RDBMS. إليك خمسة من أكثر أنواع توابع الشرط شيوعًا في شروط البحث والعوامل المستخدمة في كل منها:
</p>

<p>
	<strong>المقارنة</strong>: تقارن التوابع الشرطية المقارنِة بين تعبيري قيمة، وفي معظم الاستعلامات يكون أحد هذين التعبيرين هو اسم عمود. وعوامل المقارنة الستة هي:
</p>

<ul>
	<li>
		<code>=</code> يختبر ما إذا كانت القيمتان متساويتين.
	</li>
	<li>
		<code>&lt;&gt;</code> يختبر ما إذا كانت القيمتان غير متساويتين.
	</li>
	<li>
		<code>&lt;</code> يختبر ما إذا كانت القيمة الأولى أقل من الثانية.
	</li>
	<li>
		<code>&gt;</code> يختبر ما إذا كانت القيمة الأولى أكبر من الثانية.
	</li>
	<li>
		<code>&lt;</code>= يختبر ما إذا كانت القيمة الأولى أقل من أو تساوي الثانية.
	</li>
	<li>
		<code>&gt;=</code> يختبر ما إذا كانت القيمة الأولى أكبر من أو تساوي الثانية.
	</li>
</ul>

<p>
	<strong>القيم الفارغة</strong>: تختبر التوابع الشرطية التي تستخدم عامل <code>IS NULL</code> ما إذا كانت القيم في عمود معين فارغة.
</p>

<p>
	<strong>النطاق</strong>: تستخدم التوابع الشرطية النطاقية عامل <code>BETWEEN</code> لاختبار ما إذا كان تعبير قيمة ما يقع بين تعبيري قيمة آخرين.
</p>

<p>
	<strong>العضوية</strong>: يستخدم هذا النوع من التوابع الشرطية عامل <code>IN</code> لاختبار ما إذا كانت قيمة ما تُمثّل عضوًا في مجموعة معينة.
</p>

<p>
	<strong>تطابق الأنماط</strong>: تستخدم توابع مطابقة الأنماط الشرطية عامل <code>LIKE</code> لاختبار ما إذا كانت قيمة ما تطابق نمطًا نصيًا يحتوي على محارف بدل.
</p>

<p>
	لمعرفة المزيد حول هذه الأنواع من التوابع الشرطية، ننصحك بالاطلاع على المقالات التالية:
</p>

<ul>
	<li>
		كيفية استخدام عوامل المقارنة و IS NULL في لغة الاستعلام البنيوية SQL
	</li>
	<li>
		كيفية استخدام عوامل BETWEEN و IN في لغة الاستعلام البنيوية SQL
	</li>
	<li>
		كيفية استخدام محارف البدل في SQL
	</li>
	<li>
		وللاطلاع على المزيد حول بنى <code>WHERE</code> عمومًا، ننصحك بقراءة مقالنا حول كيفية استخدام بنى WHERE في لغة الاستعلام البنيوية SQL.
	</li>
</ul>

<h2 id="orderby">
	فرز نتائج الاستعلام باستخدام بنية ORDER BY
</h2>

<p>
	قد تُعيد الاستعلامات في بعض الأحيان المعلومات بطرق غير واضحة أو غير متوافقة تمامًا مع احتياجاتك. لذا يمكنك فرز أو ترتيب نتائج الاستعلام بتضمين بنية <code>ORDER BY</code> في نهاية تعليمة الاستعلام.
</p>

<p>
	فيما يلي الصيغة العامّة لاستعلام يتضمن بنية <code>ORDER BY</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_64" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT columns_to_return
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM table_to_query
mysql</span><span class="pun">&gt;</span><span class="pln"> ORDER BY column_name</span><span class="pun">;</span></pre>

<p>
	لتوضيح الأمر، بفرض أننا نرغب في معرفة أي من المتطوعين يحقق أعلى قيمة في عمود <code>max_bags</code>. لنُنفّذ الاستعلام التالي الذي يُعيد قيم عمودي <code>name</code> و<code>max_bags</code> من جدول <code>volunteers</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_66" style=""><span class="pln">$ SELECT name</span><span class="pun">,</span><span class="pln"> max_bags
$ FROM volunteers</span><span class="pun">;</span></pre>

<p>
	ولكن يفرز هذا الاستعلام مجموعة النتائج حسب الترتيب الذي أُضيف فيه كل سجل.
</p>

<pre class="ipsCode">الخرج
+------------+----------+
| name       | max_bags |
+------------+----------+
| Gladys     |        5 |
| Catherine  |        2 |
| Georgeanna |        1 |
| Wanda      |        1 |
| Ann        |        7 |
| Juanita    |        4 |
| Georgia    |        3 |
+------------+----------+
7 rows in set (0.00 sec)
</pre>

<p>
	ولعلّ فرز مجموعة بيانات صغيرة نسبيًا كهذه ليس بتلك الأهمية، إذ يمكننا ببساطة مراجعة قيم <code>max_bags</code> في مجموعة النتائج لإيجاد القيمة الأعلى لكن هذا الأمر قد يصبح متعبًا عند العمل مع كميات أكبر من البيانات.
</p>

<p>
	يمكننا تنفيذ الاستعلام ذاته ولكن مع إضافة بنية <code>ORDER BY</code> التي تفرز مجموعة النتائج تبعًا لقيم <code>max_bags</code> للسجلات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_68" style=""><span class="pln">$ SELECT name</span><span class="pun">,</span><span class="pln"> max_bags
$ FROM volunteers
$ ORDER BY max_bags</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+------------+----------+
| name       | max_bags |
+------------+----------+
| Georgeanna |        1 |
| Wanda      |        1 |
| Catherine  |        2 |
| Georgia    |        3 |
| Juanita    |        4 |
| Gladys     |        5 |
| Ann        |        7 |
+------------+----------+
7 rows in set (0.00 sec)
</pre>

<p>
	كما يُظهر هذا الخرج، فالسلوك الافتراضي لاستعلامات SQL التي تتضمن بنية <code>ORDER BY</code> هو فرز قيم العمود المحدد تصاعديًا (من الأصغر إلى الأكبر). ويمكننا تغيير هذا السلوك وفرزها بترتيب تنازلي عن طريق إضافة الكلمة المفتاحية <code>DESC</code> إلى بنية <code>ORDER BY</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_221_70" style=""><span class="pln">$ SELECT name</span><span class="pun">,</span><span class="pln"> max_bags
$ FROM volunteers
$ ORDER BY max_bags DESC</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+------------+----------+
| name       | max_bags |
+------------+----------+
| Ann        |        7 |
| Gladys     |        5 |
| Juanita    |        4 |
| Georgia    |        3 |
| Catherine  |        2 |
| Georgeanna |        1 |
| Wanda      |        1 |
+------------+----------+
7 rows in set (0.00 sec)
</pre>

<h2 id="-1">
	الخلاصة
</h2>

<p>
	باطلاعك على هذا المقال، اكتسبت المعرفة حول كيفية كتابة استعلامات أساسية، وكيفية تصفية وفرز مجموعات نتائج الاستعلام، ومن المفترض أن تعمل الأوامر المشروحة في هذا المقال مع أي نظام لإدارة قواعد البيانات يستخدم SQL، لكن تذكر أن لكل قاعدة بيانات SQL تقديمها الخاص للغة، لذا ينبغي مراجعة التوثيق الرسمي لنظام إدارة قواعد البيانات الخاص بك للحصول على وصف أكثر تفصيلاً لكل أمر فيها ومجموعة خياراته الكاملة.
</p>

<p>
	وللمزيد حول SQL، نشجعك على متابعة <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">المقالات المنشورة تحت وسم سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-select-rows-from-tables-in-sql" rel="external nofollow">How To SELECT Rows FROM Tables in SQL</a> لصاحبه Mark Drake.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%A7%D9%84%D8%A8%D9%86%D9%8A%D9%88%D9%8A%D8%A9-sql-r2246/" rel="">كيفية حذف البيانات في لغة الاستعلام البنيوية SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أنواع قواعد البيانات وأهم مميزاتها واستخداماتها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">تعرف على مكونات قاعدة البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">ما هي محركات قواعد البيانات؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">فهم قواعد البيانات العلاقية</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2249</guid><pubDate>Sun, 18 Feb 2024 12:07:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62D;&#x630;&#x641; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645; &#x627;&#x644;&#x628;&#x646;&#x64A;&#x648;&#x64A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%A7%D9%84%D8%A8%D9%86%D9%8A%D9%88%D9%8A%D8%A9-sql-r2246/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_02/-------SQL-.png.92d89b851cb950e1188a0c369499575e.png" /></p>
<p>
	سنتعرف في مقال اليوم على تعليمة <code>DELETE</code> في لغة الاستعلام البنيوية SQL واحدة من أقوى العمليات المتاحة للمستخدمين. وهي كما يوحي اسمها، تحذف سجلًا أو أكثر من جدول قاعدة البيانات على نحوٍ لا يمكن التراجع عنه. ومن المهم لمستخدمي SQL فهم كيف تعمل تعليمة <code>DELETE</code> باعتبارها جانبًا أساسيًا من إدارة البيانات.
</p>

<p>
	سيغطي المقال كيفية استخدام صيغة <code>DELETE</code> في SQL لحذف البيانات من جدول واحد أو أكثر. كما سيشرح كيف تتعامل SQL مع عمليات الحذف التي قد تتعارض مع <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">قيود المفتاح الخارجي Foreign key</a>.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز حاسوب يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العلاقية RDBMS التي تستخدم <a href="https://academy.hsoub.com/programming/sql/" rel="">SQL</a>. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، ويمكنك إعداد الخادم بالاستعانة بمقال <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		MySQL مثبتة ومؤمنة على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في الخطوة 3 من هذا المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقية لها تقديماتها الفريدة من لغة SQL. فبالرغم من كون الأوامر المُقدمة في هذا المقال ستعمل مع معظم هذه الأنظمة، ولكن قد تجد بعض الاختلافات في الصيغة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، ستحتاج أيضًا إلى قاعدة بيانات وجدول مُحمّل ببعض البيانات التجريبية النموذجية لتتمكن من التدرب على حذف البيانات. لذا ننصحك بقراءة الفقرة التالية <strong>الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية</strong> للمزيد من التفاصيل حول كيفية إعداد قاعدة بيانات وجدول لاستخدامهما في الأمثلة خلال هذا المقال.
</p>

<h2 id="mysql">
	الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم عن بُعد، اتصل بالخادم مُستخدمًا بروتوكول <a href="https://academy.hsoub.com/devops/security/ssh/" rel=""><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr></a> من جهازك المحلي على النحو:
</p>

<pre class="ipsCode">$ ssh ssh user@your_server_ip
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode">$ mysql -u user -p
</pre>

<p>
	أنشئ قاعدة بيانات باسم<code>deleteDB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_6" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE deleteDB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>deleteDB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_8" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE deleteDB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	بعد اختيار قاعدة البيانات <code>deleteDB</code>، أنشئ جدولين داخلها. كمثال، تخيل أنك وبعض أصدقائك تملكون ناديًا حيث يمكن للأعضاء مشاركة المعدات الموسيقية مع بعضهم البعض. فقررت إنشاء بعض الجداول لتساعدك في تتبع أعضاء النادي ومعداتهم. سيتضمّن الجدول الأول الأعمدة الأربعة التالية:
</p>

<ul>
	<li>
		<code>memberID</code>: مُعرّف كل عضو في النادي، مُعبّر عنه بنمط بيانات الأعداد الصحيحة <code>int</code>. سيكون هذا العمود هو المفتاح الأساسي للجدول.
	</li>
	<li>
		<code>name</code>: اسم كل عضو، مُعبّر عنه بنمط بيانات المحارف <code>varchar</code> مع حد أقصى يصل إلى 30 محرفًا.
	</li>
	<li>
		<code>homeBorough</code>: هذا العمود سيخزن المنطقة التي يعيش فيها كل عضو، مُعبر عنه بنمط البيانات <code>varchar</code> ولكن بحد أقصى يصل إلى 15 محرفًا فقط.
	</li>
	<li>
		<code>email</code>: عنوان البريد الإلكتروني الذي يمكن من خلاله الاتصال بكل عضو، مُعبر عنه بنمط البيانات <code>varchar</code> مع حد أقصى يصل إلى 30 محرفًا.
	</li>
</ul>

<p>
	لننشئ إذًا جدولًا باسم <code>clubMembers</code> يحتوي على هذه الأعمدة الأربعة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_10" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE clubMembers </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> memberID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> homeBorough varchar</span><span class="pun">(</span><span class="lit">15</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> email varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	أمّا الجدول الثاني فسيتضمّن الأعمدة التالية:
</p>

<ul>
	<li>
		<code>equipmentID</code>: معرّف فريد لكل قطعة من المعدات. إذ ستكون القيم في هذا العمود من نمط بيانات الأعداد الصحيحة <code>int</code>. وسيكون هذا العمود هو المفتاح الأساسي للجدول على نحوٍ مشابه لعمود <code>memberID</code> في جدول <code>clubMembers</code>،
	</li>
	<li>
		<code>equipmentType</code>: نوع الآلة أو الأداة التي يُمثّلها كل سجل (على سبيل المثال الغيتار <code>guitar</code> ومازج الأصوات <code>mixer</code> ومضخّم الصوت<code>amplifier</code> وما إلى ذلك). سنعبّر عن هذه القيم باستخدام نمط البيانات <code>varchar</code> مع حد أقصى يصل إلى 30 محرفًا.
	</li>
	<li>
		<code>brand</code>: العلامة التجارية التي أنتجت كل قطعة من المعدات، معبّر عنها أيضًا بنمط البيانات <code>varchar</code> مع حد أقصى يصل إلى 30 محرفًا.
	</li>
	<li>
		<code>ownerID</code>: هذا العمود سيحتوي على معرّف العضو المالك للقطعة نت المعدات، مُعبر عنه برقم صحيح.
	</li>
</ul>

<p>
	ولضمان أنّ عمود <code>ownerID</code> لن يتضمّن سوى قيم تُمثّل مُعرّفات أعضاء صالحة، يمكنك إنشاء قيد مفتاح خارجي عليه بحيث يُشير إلى عمود <code>memberID</code> في جدول <code>clubMembers</code>. يُعد قيد المفتاح الخارجي طريقة لتحديد علاقة بين جدولين، إذ يفرض أن تكون القيم في العمود المُطبّق عليه موجودة بالفعل في العمود المُشار إليه. في المثال التالي، يشترط قيد المفتاح الخارجي أن تكون كل قيمة تُضاف إلى عمود <code>ownerID</code> موجودة مسبقًا في عمود <code>memberID</code>.
</p>

<p>
	أنشئ جدولًا بهذه الأعمدة وهذا القيد باسم <code>clubEquipment</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_12" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE clubEquipment </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> equipmentID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> equipmentType varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> brand varchar</span><span class="pun">(</span><span class="lit">15</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ownerID </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CONSTRAINT fk_ownerID
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">ownerID</span><span class="pun">)</span><span class="pln"> REFERENCES clubMembers</span><span class="pun">(</span><span class="pln">memberID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	ومن الجدير بالملاحظة أنّ هذا المثال يوفّر اسمًا لقيد المفتاح الخارجي، ألا وهو: <code>fk_ownerID</code>.
</p>

<p>
	إذ تُنشئ MySQL تلقائيًا اسمًا لأي قيد تضيفه، إلّا أنّ تحديد اسم من قبلنا في هذه الحالة سيكون مفيدًا عندما نحتاج للإشارة إلى هذا القيد لاحقًا.
</p>

<p>
	بعد ذلك، نفّذ تعليمة <code><a href="https://wiki.hsoub.com/SQL/insert" rel="external">INSERT INTO</a></code> التالية لملء جدول <code>clubMembers</code> بستة سجلات من البيانات النموذجية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_14" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO clubMembers
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Rosetta'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Manhattan'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'hightower@example.com'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Linda'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Staten Island'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'lyndell@example.com'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Labi'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Brooklyn'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'siffre@example.com'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bettye'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Queens'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'lavette@example.com'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Phoebe'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bronx'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'snow@example.com'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Mariya'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Brooklyn'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'takeuchi@example.com'</span><span class="pun">);</span></pre>

<p>
	ثم نفّذ تعليمة <code>INSERT INTO</code> أخرى لملء جدول <code>clubEquipment</code> بعشرين سجلًا من البيانات النموذجية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_17" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'electric guitar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Gilled'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'trumpet'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Yemehe'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'drum kit'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Purl'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'mixer'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bearinger'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'microphone'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Sure'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="str">'bass guitar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Fandar'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="str">'acoustic guitar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Marten'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="str">'synthesizer'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Korgi'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">9</span><span class="pun">,</span><span class="pln"> </span><span class="str">'guitar amplifier'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Vax'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="str">'keytar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Poland'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">11</span><span class="pun">,</span><span class="pln"> </span><span class="str">'acoustic/electric bass'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Pepiphone'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">12</span><span class="pun">,</span><span class="pln"> </span><span class="str">'trombone'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Cann'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">13</span><span class="pun">,</span><span class="pln"> </span><span class="str">'mandolin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Rouge'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">14</span><span class="pun">,</span><span class="pln"> </span><span class="str">'electric guitar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Vax'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">15</span><span class="pun">,</span><span class="pln"> </span><span class="str">'accordion'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Nonher'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">16</span><span class="pun">,</span><span class="pln"> </span><span class="str">'electric organ'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Spammond'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">17</span><span class="pun">,</span><span class="pln"> </span><span class="str">'bass guitar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Peabey'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">18</span><span class="pun">,</span><span class="pln"> </span><span class="str">'guitar amplifier'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Fandar'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">19</span><span class="pun">,</span><span class="pln"> </span><span class="str">'cello'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Yemehe'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">20</span><span class="pun">,</span><span class="pln"> </span><span class="str">'PA system'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Mockville'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">);</span></pre>

<p>
	وبذلك، غدوتَ جاهزًا لمتابعة باقي المقال وبدء التعلم حول كيفية حذف البيانات باستخدام لغة الاستعلام البنيوية SQL.
</p>

<h2 id="-1">
	حذف البيانات من جدول واحد
</h2>

<p>
	إنّ الصيغة العامة لحذف البيانات في SQL على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_19" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM table_name
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE conditions_apply</span><span class="pun">;</span></pre>

<p>
	<strong>تحذير</strong>: الجزء المهم من هذه الصيغة هو البنية <code>WHERE</code> فمن خلالها يمكنك تحديد السجلات التي يجب حذفها بدقة. وبدونها، سيُنفَّذ أمر مثل <code>DELETE FROM table_name;</code> على نحوٍ صحيح، ولكنه سيحذف كل سجلات البيانات من الجدول!
</p>

<p>
	وبالعودة إلى موضوعنا، تذكّر أنّ أي عملية حذف ناجحة لا يمكن التراجع عنها. فإذا نفذّت عملية حذف دون معرفة دقيقة بالبيانات التي ستُحذف، فقد تحذف سجلات عن طريق الخطأ. ومن الطرق التي تفيدك في التأكد من عدم حذف بيانات عن طريق الخطأ هي إجراء استعلام عن البيانات المحددة للحذف باستخدام <code>SELECT</code> لرؤية البيانات التي ستعيدها بنية <code>WHERE</code> ضمن عملية الحذف <code>DELETE</code> من البداية قبل تنفيذ عملية الحذف.
</p>

<p>
	ولتوضيح الأمر، لنفترض أنّك تريد إزالة أي سجلات مُتعلقة بمعدات الموسيقى المصنعة من قبل العلامة التجارية Korgi. ولكنك قررت البدء بكتابة استعلام لرؤية كافة سجلات الآلات المُتضمنة لعلامة <code>korgi</code> تحديدًا في عمود <code>brand</code>.
</p>

<p>
	لمعرفة الآلات الموسيقية في جدولك المُصنّعة من قبل Korgi، يمكنك تنفيذ الاستعلام المبيّن أدناه. ومن الجدير بالملاحظة أنّه وعلى العكس من الاستعلام باستخدام <code>SELECT</code> أو عملية <code>INSERT INTO</code>، فلا تسمح عمليات الحذف بتحديد أعمدة فردية، لأنها مُخصصّة لحذف سجلات البيانات بالكامل.
</p>

<p>
	ولمحاكاة هذا السلوك، أتبعنا الكلمة المفتاحية <code>SELECT</code> بعلامة النجمة (<code>*</code>) في الاستعلام التالي والتي تعدّ اختصارًا في SQL يمثل "كل الأعمدة":
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_21" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE brand </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Korgi'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------+---------------+-------+---------+
| equipmentID | equipmentType | brand | ownerID |
+-------------+---------------+-------+---------+
|           8 | synthesizer   | Korgi |       4 |
+-------------+---------------+-------+---------+
1 row in set (0.00 sec)
</pre>

<p>
	ولحذف هذا السجل، عليك تنفيذ عملية حذف <code>DELETE</code> تحتوي على بنيتي <code>FROM</code> و<code>WHERE</code> مطابقتين لاستعلام <code>SELECT</code> السابق، على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_23" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE brand </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Korgi'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	يُظهر هذا الخرج أن عملية الحذف <code>DELETE</code> قد نُفِّذت على سجل واحد فقط. ولكن بإمكانك حذف عدة سجلات باستخدام بنية <code>WHERE</code> تُعيد أكثر من سجل واحد.
</p>

<p>
	أمّا استعلام <code>SELECT</code> التالي فيعيد كافّة السجلات في جدول <code>clubEquipment</code> التي يتضمن عمود <code>equipmentType</code> فيها كلمة <code>electric</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_25" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE equipmentType LIKE </span><span class="str">'%electric%'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------+------------------------+-----------+---------+
| equipmentID | equipmentType          | brand     | ownerID |
+-------------+------------------------+-----------+---------+
|           1 | electric guitar        | Gilled    |       6 |
|          11 | acoustic/electric bass | Pepiphone |       2 |
|          14 | electric guitar        | Vax       |       6 |
|          16 | electric organ         | Spammond  |       1 |
+-------------+------------------------+-----------+---------+
4 rows in set (0.00 sec)
</pre>

<p>
	ولحذف هذه السجلات الأربعة، لنعد كتابة الاستعلام السابق مستبدلين <code>SELECT *</code> بتعليمة <code>DELETE</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_27" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE equipmentType LIKE </span><span class="str">'%electric%'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 4 rows affected (0.00 sec)
</pre>

<p>
	كما من الممكن استخدام الاستعلامات الفرعية <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">Subqueries</a> لإعادة وحذف مجموعات نتائج أكثر تفصيلاً. ويُعرّف الاستعلام الفرعي بأنّه عملية استعلام كاملة - تعليمة SQL تبدأ بـ <code>SELECT</code> وتتضمن بنية <code>FROM</code>- مُضمنة ضمن عملية أخرى، تأتي عقب بنية <code>FROM</code> الخاصة بالعملية المحيطة (الاستعلام الرئيسي).
</p>

<p>
	على سبيل المثال، لنفترض أنك ترغب في حذف أي معدات مُدرجة في جدول <code>clubEquipment</code> تخص أي عضو يبدأ اسمه بالحرف "L". يمكنك أولاً الاستعلام عن هذه البيانات باستخدام تعليمة <code><a href="https://wiki.hsoub.com/SQL/select" rel="external">SELECT</a> </code>كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_33" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE ownerID IN
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT memberID FROM clubMembers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name LIKE </span><span class="str">'L%'</span><span class="pun">);</span></pre>

<p>
	تُعيد هذه العملية كل سجل من جدول <code>clubEquipment</code> تظهر قيمة عمود <code>ownerID</code> الخاصة به ضمن القيم المُعادة من الاستعلام الفرعي الذي يبدأ في السطر الرابع. إذ يُعيد هذا الاستعلام الفرعي مُعرّف العضو <code>memberID</code> لأي سجل تبدأ قيمة العمود <code>name</code> الموافقة له بالحرف "L":
</p>

<pre class="ipsCode">الخرج
+-------------+------------------+-----------+---------+
| equipmentID | equipmentType    | brand     | ownerID |
+-------------+------------------+-----------+---------+
|          12 | trombone         | Cann      |       2 |
|          19 | cello            | Yemehe    |       2 |
|           3 | drum kit         | Purl      |       3 |
|           4 | mixer            | Bearinger |       3 |
|          10 | keytar           | Poland    |       3 |
|          18 | guitar amplifier | Fandar    |       3 |
+-------------+------------------+-----------+---------+
6 rows in set (0.00 sec)
</pre>

<p>
	يمكنك بعد ذلك حذف هذه البيانات باستخدام تعليمة <code>DELETE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_35" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE ownerID IN
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT memberID FROM clubMembers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name LIKE </span><span class="str">'L%'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 6 rows affected (0.01 sec)
</pre>

<h2 id="-2">
	حذف البيانات من عدة جداول
</h2>

<p>
	يمكنك حذف البيانات من أكثر من جدول في عملية واحدة عن طريق تضمين بنية <a href="https://wiki.hsoub.com/SQL/join" rel="external"><code>JOIN</code></a>.
</p>

<p>
	تُستخدم بنى <code>JOIN</code> لدمج السجلات من جدولين أو أكثر في نتيجة استعلام واحد. يتم ذلك عن طريق إيجاد عمود مشترك بين الجداول وفرز النتائج على نحوٍ مناسب في الخرج.
</p>

<p>
	تبدو صيغة عملية الحذف التي تتضمن بنية <code>JOIN</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_37" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE table_1</span><span class="pun">,</span><span class="pln"> table_2
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM table_1 JOIN table_2
mysql</span><span class="pun">&gt;</span><span class="pln"> ON table_2</span><span class="pun">.</span><span class="pln">related_column </span><span class="pun">=</span><span class="pln"> table_1</span><span class="pun">.</span><span class="pln">related_column
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE conditions_apply</span><span class="pun">;</span></pre>

<p>
	لاحظ أنه نظرًا لقدرة <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">صيغ الدمج JOIN</a> على مقارنة البيانات من عدة جداول، فإن صيغة هذا المثال تُوضّح الجدول المُستهدف لكل عمود بوضع اسم الجدول متبوعًا بنقطة قبل اسم العمود، وهذا ما يُعرف بالإشارة الكاملة والمؤهلة للعمود. ويُمكنك تحديد الجدول المصدر لكل عمود بهذه الطريقة في أي عملية، على الرغم من عدم ضرورتها عند الاختيار من جدول واحد فقط كما فعلنا في الأمثلة السابقة.
</p>

<p>
	لتوضيح مفهوم حذف البيانات باستخدام بنية <code>JOIN</code>، لنفترض أن ناديك قرر تحديد العلامات التجارية للمعدات الموسيقية التي يمكن للأعضاء مشاركتها. نفّذ الأمر التالي لإنشاء جدول باسم <code>prohibitedBrands</code> حيث ستسرد العلامات التجارية التي لم تعد مقبولة في النادي. يحتوي هذا الجدول على عمودين فقط، كلاهما يستخدم نمط بيانات <code>varchar</code>، لتخزين اسم كل علامة تجارية والبلد الذي تعمل فيه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_39" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE prohibitedBrands </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> brandName varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> homeCountry varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	ثم املأ هذا الجدول الجديد ببعض البيانات النموذجية التجريبية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_41" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO prohibitedBrands
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES 
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Fandar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Givson'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Muug'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Peabey'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Yemehe'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Japan'</span><span class="pun">);</span></pre>

<p>
	بعد ذلك، يقرر النادي حذف أي سجلات للمعدات من جدول <code>clubEquipment</code> التي تظهر علاماتها التجارية في جدول <code>prohibitedBrands</code> ومقرها في الولايات المتحدة.
</p>

<p>
	يمكنك الاستعلام عن هذه البيانات بتنفيذ عملية استعلام مثل التالية باستخدام <code>SELECT</code>. إذ تدمج هذه العملية جدولي <code>clubEquipment</code> و<code>prohibitedBrands</code> معًا، وتُرجع فقط السجلات التي تشترك فيها أعمدة <code>brand</code> و<code>brandName</code> في نفس القيمة. وتعمل بنية <code>WHERE</code> على إتمام تحديد نتائج الاستعلام بإقصاء أي علامة تجارية لا تتضمن القيمة "USA" في عمود <code>homeCountry</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_43" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> 
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM clubEquipment JOIN prohibitedBrands
mysql</span><span class="pun">&gt;</span><span class="pln"> ON clubEquipment</span><span class="pun">.</span><span class="pln">brand </span><span class="pun">=</span><span class="pln"> prohibitedBrands</span><span class="pun">.</span><span class="pln">brandName
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE homeCountry </span><span class="pun">=</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------------+---------------+--------+---------+-----------+-------------+
| equipmentID | equipmentType | brand  | ownerID | brandName | homeCountry |
+-------------+---------------+--------+---------+-----------+-------------+
|           6 | bass guitar   | Fandar |       4 | Fandar    | USA         |
|          17 | bass guitar   | Peabey |       1 | Peabey    | USA         |
+-------------+---------------+--------+---------+-----------+-------------+
2 rows in set (0.00 sec)
</pre>

<p>
	هذه هي كل المعلومات التي نبحث عنها؛ وهي كل علامة تجارية مقرها الولايات المتحدة والموجودة في جدول <code>prohibitedBrands</code> والتي تظهر أيضًا في جدول <code>clubEquipment</code>.
</p>

<p>
	لحذف هذه العلامات التجارية من جدول <code>prohibitedBrands</code> والمعدات المرتبطة بها من جدول <code>clubEquipment</code>، أعد كتابة استعلام <code>SELECT</code> السابق ولكن استبدل تعليمة <code>SELECT *</code> بتعليمة <code>DELETE</code> متبوعةً بأسماء كلا الجدولين:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_45" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE clubEquipment</span><span class="pun">,</span><span class="pln"> prohibitedBrands
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM clubEquipment JOIN prohibitedBrands
mysql</span><span class="pun">&gt;</span><span class="pln"> ON clubEquipment</span><span class="pun">.</span><span class="pln">brand </span><span class="pun">=</span><span class="pln"> prohibitedBrands</span><span class="pun">.</span><span class="pln">brandName
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE homeCountry </span><span class="pun">=</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 4 rows affected (0.01 sec)
</pre>

<p>
	يشير هذا الخرج إلى أن العملية حذفت أربع سجلات من قاعدة البيانات: سجلين من جدول <code>clubEquipment</code> وسجلين من جدول <code>prohibitedBrands</code>. إذا كنت تريد حذف السجلات من جدول <code>clubEquipment</code> فقط والاحتفاظ بجميع السجلات في جدول <code>prohibitedBrands</code>، فعليك إدراج <code>clubEquipment</code> فقط بعد كلمة <code>DELETE</code>، والعكس صحيح.
</p>

<h2 id="delete">
	تغيير سلوك تعليمة DELETE للمفاتيح الخارجية
</h2>

<p>
	ستفشل أي تعليمة <code>DELETE</code> قد تسبب تعارضًا مع قيد <code>FOREIGN KEY</code> افتراضيًا.
</p>

<p>
	بالعودة إلى فقرة <strong>الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية</strong> في مستلزمات العمل وبتذكّر أنّ العمود <code>ownerID</code> في جدول المعدات <code>clubEquipment</code> هو مفتاح خارجي يشير إلى عمود <code>memberID</code> في جدول الأعضاء <code>clubMembers</code>. فهذا يعني أنّ أي قيمة مُدخلة في عمود <code>ownerID</code> يجب أن تكون موجودة بالفعل في جدول <code>memberID</code>.
</p>

<p>
	إذا حاولت إزالة سجل من جدول <code>clubMembers</code> تُستخدم قيمة <code>memberID</code> المُخصصة له في مكان ما ضمن عمود <code>ownerID</code> من جدول <code>clubEquipment</code>، سيؤدي ذلك إلى ظهور خطأ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_47" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM clubMembers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE memberID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">6</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
</pre>

<p>
	يمكنك تجنب هذا الخطأ بإزالة أي سجلات في الجدول الابن (<code>clubEquipment</code> في هذا المثال) حيث توجد قيمة المفتاح الخارجي في الجدول الأب (<code>clubMembers</code>). كبديل، يمكنك تغيير هذا السلوك بتعديل قيد المفتاح الخارجي القائم بآخر يعالج عمليات الحذف على نحوٍ مختلف.
</p>

<p>
	<strong>ملاحظة</strong>: لا تسمح كافة أنظمة إدارة قواعد البيانات العلاقية أو محركاتها بإضافة أو إزالة قيود من جدول قائم كما هو موضح في الفقرات اللاحقة. فإذا كنت تستخدم نظام RDBMS غير MySQL، يجب عليك مراجعة الوثائق الرسمية الخاصة به لفهم القيود المتعلقة بإدارة القيود.
</p>

<p>
	وبالعودة إلى موضوعنا، بذلك ستكون قادرًا على تحديث قيمة <code>clientID</code> لأي سجل في الجدول الأب <code>clubMembers</code>، وستنتقل هذه التغييرات بشكل تلقائي إلى أي سجلات في الجدول الابن <code>clubEquipment</code> المرتبطة به. لاستبدال القيد الحالي، يجب أولًا إزالته باستخدام تعليمة <code>ALTER TABLE</code>. تذكر أننا في تعليمة <code>CREATE TABLE</code> لجدول <code>clubEquipment</code>، قمنا بتحديد <code>fk_ownerID</code> كاسم لقيد المفتاح الخارجي للجدول.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_49" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> DROP FOREIGN KEY fk_ownerID</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
</pre>

<p>
	بعد ذلك، أنشئ قيد مفتاح خارجي جديد مُعدّ ليتعامل مع عمليات الحذف <code>DELETE</code> بطريقة تتناسب مع حالة الاستخدام المعطاة. بصرف النظر عن الإعداد الافتراضي الذي يمنع تعليمات <code>DELETE</code> التي تخالف المفتاح الخارجي، هناك خياران آخران متاحان في معظم أنظمة إدارة قواعد البيانات العلاقية:
</p>

<ul>
	<li>
		<code>ON DELETE SET NULL</code>: يسمح لك هذا الخيار بحذف السجلات من الجدول الأب، وسيعيد تعيين أي قيم مرتبطة بها في الجدول الابن على أنها قيم فارغة <code>NULL</code>.
	</li>
	<li>
		<code>ON DELETE CASCADE</code>: عند حذف سجل في الجدول الأب، سيدفع هذا الخيار SQL لحذف أي سجلات في الجدول الابن مرتبطة بذلك السجل من الجدول الأب.
	</li>
</ul>

<p>
	في سياق هذا المثال، لا يُعد استخدام خيار <code>ON DELETE SET NULL</code> منطقيًا. فإذا غادر أحد الأعضاء النادي وحُذِف سجله من جدول <code>clubMembers</code>، فلن تكون معداته متاحة للأعضاء المتبقين بعد الآن وبالتالي يجب إزالتها من جدول <code>clubEquipment</code>. وفي هذا الصدد يُعدّ خيار <code>ON DELETE CASCADE</code> هو الأنسب لهذا السياق.
</p>

<p>
	لإضافة قيد <code>FOREIGN KEY</code> يعمل وفق آلية <code>ON DELETE CASCADE</code>، نفّذ أمر <a href="https://wiki.hsoub.com/SQL/alter_table" rel="external"><code>ALTER TABLE</code></a> التالي لتعديل الجدول. ستنشئ هذه التعليمة قيدًا جديدًا باسم <code>newfk_ownerID</code> يعكس تعريف القيد السابق ولكن مع إضافة خيار <code>ON DELETE CASCADE</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_51" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE clubEquipment
mysql</span><span class="pun">&gt;</span><span class="pln"> ADD CONSTRAINT newfk_ownerID
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">ownerID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> REFERENCES clubMembers</span><span class="pun">(</span><span class="pln">memberID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ON DELETE CASCADE</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 7 rows affected (0.07 sec)
Records: 7  Duplicates: 0  Warnings: 0
</pre>

<p>
	تشير هذه النتائج إلى أن العملية قد أثرت على جميع السجلات السبعة المتبقية في جدول <code>clubEquipment</code>.
</p>

<p>
	<strong>ملاحظة</strong>: بدلًا من تغيير تعريف جدول مُعرّف مسبقًا لتعديل كيفية تفاعل قيد المفتاح الخارجي مع عمليات <code>DELETE</code>، يُمكنك من البداية تحديد هذا السلوك عند إنشاء الجدول بواسطة تعليمة إنشاء الجدول <a href="https://wiki.hsoub.com/SQL/create_table" rel="external"><code>CREATE TABLE</code></a> ، وبذلك تُعيّن السلوك المطلوب مُسبقًا، على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_53" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE clubEquipment </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> equipmentID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> equipmentType varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> brand varchar</span><span class="pun">(</span><span class="lit">15</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ownerID </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CONSTRAINT fk_ownerID
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">ownerID</span><span class="pun">)</span><span class="pln"> REFERENCES clubMembers</span><span class="pun">(</span><span class="pln">memberID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ON DELETE CASCADE
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	عقب ذلك، ستكون قادرًا على حذف أي سجل من جدول <code>clubMembers</code>، وستُحذف جميع السجلات المرتبطة به في جدول <code>clubEquipment</code> تلقائيًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1897_55" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE FROM clubMembers
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE memberID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">6</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.00 sec)
</pre>

<p>
	رغم أن هذا الخرج يشير إلى تأثر سجل واحد فقط، إلا أنّ العملية قد حذفت أيضًا كافة سجلات المعدات في جدول <code>clubEquipment</code> ذات القيمة <code>6</code> في عمود <code>ownerID</code>.
</p>

<h2 id="-3">
	الخلاصة
</h2>

<p>
	باطلاعك على هذا المقال، اكتسبت المعرفة حول كيفية حذف البيانات الموجودة في جدول واحد أو أكثر باستخدام تعليمة <code>DELETE</code> في SQL. كما تعرفت على كيفية تعامل SQL مع عمليات الحذف التي تتعارض مع قيود المفتاح الخارجي وطرق تغيير هذا السلوك الافتراضي.
</p>

<p>
	ومن المفترض أن تعمل الأوامر المشروحة في هذا المقال مع أي نظام لإدارة قواعد البيانات يستخدم SQL. لكن تذكر أن لكل قاعدة بيانات SQL تقديمها الخاص للغة، لذا ينبغي مراجعة التوثيق الرسمي لنظام إدارة قواعد البيانات الخاص بك للحصول على وصف أكثر تفصيلاً لكيفية التعامل مع عمليات الحذف والخيارات المتاحة لها.
</p>

<p>
	وللمزيد حول SQL، نشجعك على متابعة <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">المقالات المنشورة تحت وسم سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-delete-data-in-sql" rel="external nofollow">How To Delete Data in SQL</a> لصاحبه Mark Drake.
</p>

<h2 id="-4">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%A7%D9%84%D8%A8%D9%86%D9%8A%D9%88%D9%8A%D8%A9-sql-r2242/" rel="">كيفية تحديث البيانات في لغة الاستعلام البنيوية SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%A7-%D9%87%D9%8A-%D8%AA%D9%82%D9%86%D9%8A%D8%A9-sql%D8%9F-r1651/" rel="">ما هي تقنية SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D8%B8%D9%8A%D9%85-%D8%B4%D9%8A%D9%81%D8%B1%D8%A7%D8%AA-sql-%D9%88%D8%AA%D8%A3%D9%85%D9%8A%D9%86%D9%87%D8%A7-r860/" rel="">تنظيم شيفرات SQL وتأمينها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول ومعلومات المخطط وترتيب تنفيذ الاستعلامات في SQL</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2246</guid><pubDate>Thu, 15 Feb 2024 12:09:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62A;&#x62D;&#x62F;&#x64A;&#x62B; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645; &#x627;&#x644;&#x628;&#x646;&#x64A;&#x648;&#x64A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%A7%D9%84%D8%A8%D9%86%D9%8A%D9%88%D9%8A%D8%A9-sql-r2242/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_02/-------SQL-.png.08e13e1ffa5e47197755763eda558e6f.png" /></p>
<p>
	لدى التعامل مع قاعدة بيانات، قد تضطر أحيانًا لتعديل بيانات كانت مدرجة من قبل في جدول أو أكثر. كأن تُضطر مثلًا لتصحيح خطأ إملائي في إدخال معين أو إضافة معلومات جديدة إلى سجل غير مكتمل. وتوفّر لغة الاستعلام البنيوية المعروفة بـ SQL الكلمة المفتاحية <code>UPDATE</code>، التي تُمكّن المستخدمين من تعديل البيانات الموجودة في جدول ما.
</p>

<p>
	يشرح هذا المقال كيفية استعمال الصيغة <code>UPDATE</code> في SQL لتعديل البيانات في جدول واحد أو عدة جداول مرتبطة ببعضها. كما يتناول الطريقة التي تتعامل بها SQL مع عمليات <code>UPDATE</code> التي قد تتعارض مع <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D9%81%D9%8A-sql-r2225/" rel="">قيود المفتاح الخارجي</a>.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز حاسوب يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العلاقية RDBMS التي تستخدم <a href="https://academy.hsoub.com/programming/sql/" rel="">SQL</a>. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، ويمكنك إعداد الخادم بالاستعانة بمقالنا  <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		MySQL مثبتة ومؤمنة على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، ومُنشأ وفق الطريقة الموضحة في الخطوة 3 من هذا المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-%D8%A8%D9%8A%D9%86-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-sqlite-%D9%85%D8%B9-mysql-%D9%85%D8%B9-postgresql-r72/" rel="">إدارة قواعد البيانات العلاقية</a> لها تقديماتها الفريدة من لغة <a href="https://wiki.hsoub.com/SQL" rel="external">SQL</a>. فبالرغم من كون الأوامر المُقدمة في هذا المقال ستعمل مع معظم هذه الأنظمة، ولكن قد تجد بعض الاختلافات في الصيغة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، ستحتاج أيضًا إلى <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">قاعدة بيانات</a> مع بعض الجداول المُحمّلة ببعض البيانات التجريبية النموذجية لتتمكن من التدرب على تحديث بيانات SQL. وإذا لم تكن متوفرة لديك، يمكنك مراجعة مقال الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية للمزيد من التفاصيل حول كيفية الاتصال بخادم MySQL وإنشاء قاعدة البيانات التجريبية المُستخدمة في أمثلة هذا المقال.
</p>

<h2 id="mysql">
	الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم عن بُعد، اتصل بالخادم مُستخدمًا بروتوكول <a href="https://academy.hsoub.com/devops/security/ssh/" rel=""><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr></a> من جهازك المحلي على النحو:
</p>

<pre class="ipsCode">$ ssh user@your_server_ip
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode">$ mysql -u user -p
</pre>

<p>
	أنشئ قاعدة بيانات باسم <code>updateDB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_20" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE updateDB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>updateDB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_18" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE updateDB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	وبعد اختيارك لقاعدة البيانات <code>updateDB</code>، أنشئ بعض الجداول ضمنها. ولتوضيح الأمثلة في هذا المقال، تخيّل أنّك تدير وكالة مواهب، وقد قررت تتبّع عملائك وأدائهم عبر قاعدة بيانات SQL، وبأنّك تعتزم البدء بجدولين: الجدول الأوّل لتخزين معلومات عن عملائك. وقد حددت أنّ هذا الجدول يحتاج إلى أربعة أعمدة:
</p>

<ul>
	<li>
		<code>clientID</code>: مُعرّف كل عميل، مُعبرًا عنه بنمط بيانات الأعداد الصحيحة <code>int</code>، كما سيُمثّل هذا العمود المفتاح الرئيسي للجدول، بحيث تمثل كل قيمة منه دور المُعرف الفريد للسجل المُرتبط بها.
	</li>
	<li>
		<code>name</code>: اسم كل عميل، مُعبرًا عنه بنمط بيانات <code><a href="https://wiki.hsoub.com/SQL/datatype#.D8.A3.D9.86.D9.88.D8.A7.D8.B9_.D8.A7.D9.84.D8.B3.D9.84.D8.A7.D8.B3.D9.84_String" rel="external">varchar</a></code> بحد أقصى <code>20</code> محرفًا.
	</li>
	<li>
		<code>routine</code>: وصف مُختصر لنوع الأداء الرئيسي لكل عميل، مُعبرًا عنه بنمط بيانات <code>varchar</code> بحد أقصى 30 محرفًا.
	</li>
	<li>
		<code>performanceFee</code>: عمود لتسجيل رسوم الأداء القياسية لكل عميل، يستخدم نمط البيانات <code>decimal</code> وتُحدد القيم في هذا العمود بحد أقصى قدره خمسة أرقام، بواقع رقمين على يمين الفاصلة العشرية. وبالتالي، تتراوح القيم المسموح بها من <code>-999.99</code> إلى <code>999.99</code>.
	</li>
</ul>

<p>
	أنشئ جدولًا باسم <code>clients</code> يشمل هذه الأعمدة الأربعة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_16" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">clientID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> routine varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> standardFee </span><span class="kwd">decimal</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	أمّا الجدول الثاني فسيكون مخصصًا لتخزين بيانات حول أداء عملائك في مكان عرض محدد محليًا. وبفرض أنك ارتأيت بأنّ هذا الجدول يتطلّب خمسة أعمدة:
</p>

<ul>
	<li>
		showID<code>: بمثابة عمود </code>clientID<code>، </code>إذ سيحتفظ هذا العمود بمُعرّف فريد لكل عرض، مُعبرًا عنه بنمط بيانات الأعداد الصحيحة int<code>. </code>كما سيمُثّل هذا العمود المفتاح الرئيسي لجدول العروض shows.
	</li>
	<li>
		showDate<code>: </code>تاريخ كل عرض. يُعبر عن قيم هذا العمود باستخدام نمط بيانات التواريخ date الذي يستخدم الصيغة YYYY-MM-DD (خانتين لليوم وخانتين للشهر وأربع خانات للسنة).
	</li>
	<li>
		clientID: مُعرّف العميل الذي يؤدي في العرض، مُعبرًا عنه كعدد صحيح.
	</li>
	<li>
		attendance: عدد الحضور في كل عرض، مُعبرًا عنه كعدد صحيح.
	</li>
	<li>
		ticketPrice<code><span>:</span></code>سعر تذكرة الدخول لكل عرض. يستخدم هذا العمود نمط البيانات decimal<code> </code>وتُحدد القيم في هذا العمود بحد أقصى قدره خمسة أرقام، بواقع رقمين على يمين الفاصلة العشرية. وبالتالي، تتراوح القيم المسموح بها من- 999.99 إلى 999.99.
	</li>
</ul>

<p>
	ولضمان أنّ عمود <code>clientID</code> لن يتضمّن سوى قيم تُمثّل مُعرّفات عملاء صالحة، قررتَ تطبيق قيد مفتاح خارجي عليه بحيث يُشير إلى عمود <code>clientID</code> في جدول <code>clients</code>. يُعد قيد المفتاح الخارجي طريقة لتحديد <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r590/" rel="">علاقة بين جدولين</a>، إذ يفرض أن تكون القيم في العمود المُطبّق عليه موجودة بالفعل في العمود المُشار إليه. في المثال القادم، يشترط قيد <code>FOREIGN KEY</code> أن تكون كل قيمة تُضاف إلى عمود <code>clientID</code> في جدول <code>shows</code> مُسجلة مسبقًا في عمود <code>clientID</code> بجدول <code>clients</code>.
</p>

<p>
	أنشئ جدولًا باسم <code>clients</code> يتضمن هذه الأعمدة الخمسة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_25" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE shows
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">showID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> showDate date</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> clientID </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> attendance </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ticketPrice </span><span class="kwd">decimal</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CONSTRAINT client_fk
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> REFERENCES clients</span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	ومن الجدير بالملاحظة أنّ هذا المثال يوفّر اسمًا لقيد المفتاح الخارجي، ألا وهو: <code>client_fk</code>. إذ تُنشئ MySQL تلقائيًا اسمًا لأي قيد تضيفه، إلّا أنّ تحديد اسم من قبلنا في هذه الحالة سيكون مفيدًا عندما نحتاج للإشارة إلى هذا القيد لاحقًا.
</p>

<p>
	بعد ذلك، نفّذ تعليمة <code>INSERT INTO</code> التالية لملء جدول العملاء <code>clients</code> بخمسة سجلات من البيانات النموذجية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_27" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO clients
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Fares'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'song and dance'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">180</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Camal'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'standup'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">99.99</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Karam'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'standup'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">45</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Wael'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'song and dance'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">200</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Ahmad'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'trained squirrel'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">79.99</span><span class="pun">);</span></pre>

<p>
	ثم نفّذ تعليمة <code>INSERT INTO</code> أخرى لملء جدول <code>shows</code> بعشرة سجلات من البيانات النموذجية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_29" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO shows
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2019-12-25'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">124</span><span class="pun">,</span><span class="pln"> </span><span class="lit">15</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-01-11'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">84</span><span class="pun">,</span><span class="pln"> </span><span class="lit">29.50</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-01-17'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">170</span><span class="pun">,</span><span class="pln"> </span><span class="lit">12.99</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-01-31'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">234</span><span class="pun">,</span><span class="pln"> </span><span class="lit">14.99</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-02-08'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">86</span><span class="pun">,</span><span class="pln"> </span><span class="lit">25</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-02-14'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">102</span><span class="pun">,</span><span class="pln"> </span><span class="lit">39.5</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-02-15'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">101</span><span class="pun">,</span><span class="pln"> </span><span class="lit">26.50</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-02-27'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">186</span><span class="pun">,</span><span class="pln"> </span><span class="lit">19.99</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">9</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-03-06'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">202</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2020-03-07'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">250</span><span class="pun">,</span><span class="pln"> </span><span class="lit">8.99</span><span class="pun">);</span></pre>

<p>
	وبذلك، غدوتَ جاهزًا لمتابعة باقي المقال وبدء تعلم كيفية تحديث البيانات باستخدام لغة الاستعلام البنيوية SQL.
</p>

<h2 id="-1">
	تحديث البيانات في جدول واحد
</h2>

<p>
	تبدو الصيغة العامّة لتعليمة <code>UPDATE</code> على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_31" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE table_name
mysql</span><span class="pun">&gt;</span><span class="pln"> SET column_name </span><span class="pun">=</span><span class="pln"> value_expression
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE conditions_apply</span><span class="pun">;</span></pre>

<p>
	تُتبع الكلمة المفتاحية <code>UPDATE</code> باسم الجدول الذي يحتوي على البيانات المُراد تحديثها. ثم تأتي بنية <code>SET</code>، والتي تُحدّد بيانات العمود المُراد تحديثها وكيفية التحديث. تُعدّ بنية <code>SET</code> وكأنها تعيين لقيم العمود المُحدد لتُصبح مطابقة لأي تعبير قيمة تُقدّمه.
</p>

<p>
	يُعرّف تعبير القيمة — الذي يُعرف أحيانًا بالتعبير ذو القيمة المفردة — بأنّه أي تعبير يُعيد قيمة واحدة لكل سجل يُراد تحديثه. يمكن أن تكون القيمة المُعادة عبارة عن سلسلة نصية مجردة، أو عملية رياضية تُجرى على قيم رقمية موجودة في العمود. ولا بُدّ من تضمين عملية إسناد لقيمة واحدة على الأقل في كل تعليمة <code>UPDATE</code>، كما يُمكنك تضمين أكثر من تعليمة واحدة بغية تحديث البيانات في عدة أعمدة.
</p>

<p>
	تُتبع بنية <code>SET</code> ببنية <code>WHERE</code>. فإضافة بنية <code>WHERE</code> إلى تعليمة <code>UPDATE</code> كما في صيغة المثال هذه يُمكنّك من تصفية أي سجلات لا ترغب في تحديثها. إنّ بنية <code>WHERE</code> اختيارية تمامًا في تعليمات <code>UPDATE</code>، ولكن إذا لم تُضمنها، ستُحدّث العملية كل سجل في الجدول.
</p>

<p>
	لتوضيح كيفية تعامل SQL مع عمليات التحديث <code>UPDATE</code>، ابدأ بالاطلاع على كافة البيانات في جدول العملاء <code>clients</code>. يشتمل الاستعلام التالي على علامة النجمة (<code>*</code>)، وهي اختصار في SQL يُمثّل كل عمود في الجدول، لذا سيُعيد هذا الاستعلام جميع البيانات من كل عمود في جدول <code>clients</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_33" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM clients</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+----------+------------+------------------+-------------+
| clientID | name       | routine          | standardFee |
+----------+------------+------------------+-------------+
|        1 | Fares     | song and dance   |      180.00 |
|        2 | Camal  | standup          |       99.99 |
|        3 | Karam | standup          |       45.00 |
|        4 | Wael      | song and dance   |      200.00 |
|        5 | Ahmad        | trained squirrel |       79.99 |
+----------+------------+------------------+-------------+
5 rows in set (0.00 sec)
</pre>

<p>
	لنفترض على سبيل المثال أنّك لاحظت وجود خطأ في تهجئة الاسم Kamal، إذ يجب أن يبدأ بحرف K ولكنه في الجدول يبدأ بحرف C، ولذا قررت تغيير هذه القيمة عبر تنفيذ تعليمة <code>UPDATE</code> التالية. هذه العملية تُحدّث القيم في عمود الاسم <code>name</code> عن طريق تغيير قيمة عمود الاسم <code>name</code> في أي سجل يحتوي على الاسم <code>Camal</code> لتصبح <code>Kamal</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_35" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> SET name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Kamal'</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Camal'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
</pre>

<p>
	يُظهر هذا الخرج أن سجلًا واحدًا فقط قد حُدّث. يمكنك التأكد من ذلك بتشغيل استعلام <code>SELECT</code> السابق مجددًا، على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_37" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM clients</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+----------+------------+------------------+-------------+
| clientID | name       | routine          | standardFee |
+----------+------------+------------------+-------------+
|        1 | Fares     | song and dance   |      180.00 |
|        2 | Kamal  | standup          |       99.99 |
|        3 | Karam | standup          |       45.00 |
|        4 | Wael      | song and dance   |      200.00 |
|        5 | Ahmad        | trained squirrel |       79.99 |
+----------+------------+------------------+-------------+
5 rows in set (0.00 sec)
</pre>

<p>
	تُظهر هذه النتائج أن القيمة المُدخلة سابقًا على أنّها <code>Camal</code> قد عُدلت الآن إلى <code>Kamal</code>.
</p>

<p>
	لقد حُدثّت قيمة واحدة فقط في عمود الاسم <code>name</code> في هذا المثال. ولكن، يمكنك تحديث عدة قيم باستخدام بنية <code>WHERE</code> أشمل.
</p>

<p>
	لإيضاح هذه الفكرة، بفرض أنّك تفاوضت على أجور أداء موحدة لجميع عملائك الذين يؤدون فقرات محددة. ستُحدّث التعليمة التالية القيم في عمود <code>standardFee</code> وتعينها لتكون <code>140</code>.
</p>

<p>
	يرجى ملاحظة أن بنية <code>WHERE</code> في هذا المثال تتضمن <a href="https://wiki.hsoub.com/SQL/like" rel="external">المعامل LIKE</a>، لذا فهي تُحدّث قيمة <code>performanceFee</code> لكل عميل تُطابق قيمة <code>routine</code> له النمط المحدد <a href="https://academy.hsoub.com/programming/general/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-r1374/" rel="">بالمحرف البديل</a> 's%'. بمعنى آخر، سيُحدّث أجر الأداء لأي مؤدي يبدأ نوع عرضه بالحرف "s":
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_40" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> SET standardFee </span><span class="pun">=</span><span class="pln"> </span><span class="lit">140</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE routine LIKE </span><span class="str">'s%'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0
</pre>

<p>
	والآن إذا استعلمت مجددًا عن محتويات جدول العملاء <code>clients</code>، فستؤكد مجموعة النتائج أن أربعة من عملائك غدا لديهم الآن رسوم أداء متطابقة:
</p>

<pre class="ipsCode">$ SELECT * FROM clients;
</pre>

<pre class="ipsCode">الخرج
+----------+------------+------------------+-------------+
| clientID | name       | routine          | standardFee |
+----------+------------+------------------+-------------+
|        1 | Fares     | song and dance   |      140.00 |
|        2 | Kamal  | standup          |      140.00 |
|        3 | Karam | standup          |      140.00 |
|        4 | Wael      | song and dance   |      140.00 |
|        5 | Ahmad        | trained squirrel |       79.99 |
+----------+------------+------------------+-------------+
5 rows in set (0.00 sec)
</pre>

<p>
	في حالة وجود أعمدة بالجدول تحمل قيمًا رقمية، فيُمكن تحديثها بتنفيذ عملية حسابية ضمن بنية <code>SET</code>. لتوضيح الأمر، بفرض أنّك توصلّت لاتفاق على زيادة رسوم الأداء لكل عميل بنسبة أربعين بالمئة، ولتطبيق هذا التغيير على جدول العملاء <code>clients</code>، يمكن تنفيذ عملية <code>UPDATE</code> كالآتي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_42" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> SET standardFee </span><span class="pun">=</span><span class="pln"> standardFee </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.4</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 5 rows affected, 1 warning (0.00 sec)
Rows matched: 5  Changed: 5  Warnings: 1
</pre>

<p>
	ملاحظة: لاحظ أن الخرج يشير إلى أنّ التحديث قد نتج عنه تحذير. ففي كثير من الأحيان، تُصدر MySQL تحذيرًا عندما تُجبر على إجراء تغيير على بياناتك يتعارض والخصائص أو المحددات القياسية لعمود أو جدول معين.
</p>

<p>
	وتوفّر MySQL الاختصار <code>SHOW WARNINGS</code> الذي قد يساعد في شرح أي تحذيرات تتلقاها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_44" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW WARNINGS</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------+------+--------------------------------------------------+
| Level | Code | Message                                          |
+-------+------+--------------------------------------------------+
| Note  | 1265 | Data truncated for column 'standardFee' at row 5 |
+-------+------+--------------------------------------------------+
1 row in set (0.00 sec)
</pre>

<p>
	يُخبرنا هذا الخرج بأن نظام قاعدة البيانات أصدر التحذير لأنه اضطر إلى اقتطاع إحدى قيم العمود <code>standardFee</code> الجديدة حتى تتوافق مع تنسيق الرقم العشري - خمسة أرقام مع وجود رقمين على يمين الفاصلة العشرية - المُعرّف مسبقًا.
</p>

<p>
	لنستعلم عن جدول العملاء <code>clients</code> مجددًا للتأكد من أن رسوم الأداء لكل من العملاء قد ارتفعت بنسبة أربعين بالمئة بالفعل.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_46" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM clients</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+----------+------------+------------------+-------------+
| clientID | name       | routine          | standardFee |
+----------+------------+------------------+-------------+
|        1 | Fares     | song and dance   |      196.00 |
|        2 | Kamal  | standup          |      196.00 |
|        3 | Karam | standup          |      196.00 |
|        4 | Wael      | song and dance   |      196.00 |
|        5 | Ahmad        | trained squirrel |      111.99 |
+----------+------------+------------------+-------------+
5 rows in set (0.00 sec)
</pre>

<p>
	كما ذكرنا سابقًا، يمكنك أيضًا تحديث البيانات في عدة أعمدة دفعة واحدة باستخدام تعليمة <code>UPDATE</code> واحدة. للقيام بذلك، يجب تحديد كل عمود ترغب في تحديثه، متبوعًا بالتعبير الخاص بالقيمة المراد تعيينها، ثم تفصل بين كل زوج من اسم عمود وتعبير قيمة بعلامة فاصلة.
</p>

<p>
	على سبيل المثال، بفرض أنّك اكتشفت بأنّ القاعة التي يقدم فيها عملاؤك عروضهم قد أخطأت في الإبلاغ عن عدد الحضور لجميع عروض Karam و Wand. وبالصدفة، تبين أيضًا أنك قمت بإدخال أسعار تذاكر خاطئة لكل من عروضهما.
</p>

<p>
	قبل الشروع في تحديث البيانات في جدول العروض <code>shows</code>، نفّذ الاستعلام التالي لاسترجاع كافة البيانات الحالية المُخزنة به حاليًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_48" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM shows</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+--------+------------+----------+------------+-------------+
| showID | showDate   | clientID | attendance | ticketPrice |
+--------+------------+----------+------------+-------------+
|      1 | 2019-12-25 |        4 |        124 |       15.00 |
|      2 | 2020-01-11 |        5 |         84 |       29.50 |
|      3 | 2020-01-17 |        3 |        170 |       12.99 |
|      4 | 2020-01-31 |        5 |        234 |       14.99 |
|      5 | 2020-02-08 |        1 |         86 |       25.00 |
|      6 | 2020-02-14 |        3 |        102 |       39.50 |
|      7 | 2020-02-15 |        2 |        101 |       26.50 |
|      8 | 2020-02-27 |        2 |        186 |       19.99 |
|      9 | 2020-03-06 |        4 |        202 |       30.00 |
|     10 | 2020-03-07 |        5 |        250 |        8.99 |
+--------+------------+----------+------------+-------------+
10 rows in set (0.01 sec)
</pre>

<p>
	ولتصحيح أعداد الحضور والأسعار لتعبّر عن تلك الفعلية، سنحدّث الجدول لإضافة عشرين حاضرًا إلى كل عرض لهما وزيادة قيم سعر التذكرة <code>ticketPrice</code> لكل عرض بنسبة خمسين في المئة. يمكنك القيام بذلك من خلال عملية على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_50" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE shows
mysql</span><span class="pun">&gt;</span><span class="pln"> SET attendance </span><span class="pun">=</span><span class="pln"> attendance </span><span class="pun">+</span><span class="pln"> </span><span class="lit">20</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ticketPrice </span><span class="pun">=</span><span class="pln"> ticketPrice </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE clientID IN 
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT clientID
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM clients
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Karam'</span><span class="pln"> OR name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Wael'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 4 rows affected, 1 warning (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 1
</pre>

<p>
	لاحظ أن هذا المثال يستخدم استعلامًا فرعيًا في بنية <code>WHERE</code> لإرجاع قيم <code>clientID</code> لكل من Karam و Wael من جدول العملاء <code>clients</code>. وغالبًا ما يكون من الصعب تذكر القيم المجردة من قبيل أرقام التعريف، إلّا أنّ هذه الطريقة التي تستخدم فيها استعلامًا فرعيًا للعثور على قيمة يمكن أن تكون مفيدة في حال معرفتك لبعض السمات فقط حول السجلات المعنية.
</p>

<p>
	بعد تحديث جدول العروض <code>shows</code>، لنستعلم عنه مجددًا للتأكد من أن التغييرات قد تمّت كما هو متوقع:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_52" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM shows</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+--------+------------+----------+------------+-------------+
| showID | showDate   | clientID | attendance | ticketPrice |
+--------+------------+----------+------------+-------------+
|      1 | 2019-12-25 |        4 |        144 |       22.50 |
|      2 | 2020-01-11 |        5 |         84 |       29.50 |
|      3 | 2020-01-17 |        3 |        190 |       19.49 |
|      4 | 2020-01-31 |        5 |        234 |       14.99 |
|      5 | 2020-02-08 |        1 |         86 |       25.00 |
|      6 | 2020-02-14 |        3 |        122 |       59.25 |
|      7 | 2020-02-15 |        2 |        101 |       26.50 |
|      8 | 2020-02-27 |        2 |        186 |       19.99 |
|      9 | 2020-03-06 |        4 |        222 |       45.00 |
|     10 | 2020-03-07 |        5 |        250 |        8.99 |
+--------+------------+----------+------------+-------------+
10 rows in set (0.00 sec)
</pre>

<p>
	يشير هذا الخرج إلى أن تعليمة <code>UPDATE</code> قد اكتملت بنجاح.
</p>

<h2 id="join">
	استخدام بنية JOIN لتحديث البيانات في جداول متعددة
</h2>

<p>
	ركّز هذا المقال حتى الآن على عرض طرق تحديث البيانات في جدول واحد فقط في كل مرة. ولكن، تُتيح بعض الإصدارات من SQL إمكانية تحديث أعمدة متعددة في جداول متعددة من خلال دمج الجداول مؤقتًا باستخدام بنية <code><a href="https://wiki.hsoub.com/SQL/join" rel="external">JOIN</a></code>.
</p>

<p>
	فيما يلي الصيغة العامة التي بإمكانك استخدامها لتحديث عدة جداول دفعة واحدة مستخدمًا بنية <code>JOIN</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_55" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE table_1 JOIN table_2
mysql</span><span class="pun">&gt;</span><span class="pln"> ON table_1</span><span class="pun">.</span><span class="pln">related_column </span><span class="pun">=</span><span class="pln"> table_2</span><span class="pun">.</span><span class="pln">related_column
mysql</span><span class="pun">&gt;</span><span class="pln"> SET table_1</span><span class="pun">.</span><span class="pln">column_name </span><span class="pun">=</span><span class="pln"> value_expression</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> table_2</span><span class="pun">.</span><span class="pln">column_name </span><span class="pun">=</span><span class="pln"> value_expression
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE conditions_apply</span><span class="pun">;</span></pre>

<p>
	تبدأ صيغة هذا المثال بالكلمة المفتاحية <code>UPDATE</code> متبوعة بأسماء جدولين، يفصل بينهما صيغة <code>JOIN</code>. يلي ذلك صيغة <code>ON</code>، التي توضّح كيف ينبغي للاستعلام أن يدمج الجدولين معًا.
</p>

<p>
	في معظم تقديمات SQL، يمكنك دمج الجداول عن طريق إيجاد تطابقات ما بين أي مجموعة من الأعمدة تحتوي على ما يُعرف في معيار SQL باسم "أنواع البيانات المؤهلة للدمج" (<code>JOIN</code> eligible). بمعنى آخر، يُمكن بشكل عام دمج أي عمود يحتوي على بيانات عددية مع أي عمود آخر يحتوي على بيانات عددية، بغض النظر عن أنماط البيانات المحددة لكل منهما. وبالمثل، يمكن دمج أي أعمدة تحتوي على قيم محرفية مع أي عمود آخر يحتوي على بيانات محرفية.
</p>

<p>
	لاحظ أنه نظرًا لقدرة بنى <code>JOIN</code> على مقارنة البيانات من عدة جداول، فإن صيغة هذا المثال تُوضّح الجدول المُستهدف لكل عمود بوضع اسم الجدول متبوعًا بنقطة قبل اسم العمود، وهذا ما يُعرف بالإشارة الكاملة والمؤهلة للعمود. يُمكنك تحديد الجدول المصدر لكل عمود بهذه الطريقة في أي عملية، وهي غالبًا ما تُستخدم لزيادة الوضوح عند العمل مع أكثر من جدول.
</p>

<p>
	لتوضيح كيفية تنفيذ ذلك باستخدام جداول <code>clients</code> و<code>shows</code> المُنشأة مسبقًا، نفذ تعليمة <code>UPDATE</code> التالية. ما سيدمج جدولي <code>clients</code> و<code>shows</code> بناءً على أعمدة <code>clientID</code> المتطابقة في كلا الجدولين، ومن ثم تحديث قيم <code>routine</code> و<code>ticketPrice</code> لسجل Fares في جدول <code>clients</code> وكل عروضها المدرجة في جدول <code>shows</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_57" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients JOIN shows
mysql</span><span class="pun">&gt;</span><span class="pln"> USING </span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> SET clients</span><span class="pun">.</span><span class="pln">routine </span><span class="pun">=</span><span class="pln"> </span><span class="str">'mime'</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> shows</span><span class="pun">.</span><span class="pln">ticketPrice </span><span class="pun">=</span><span class="pln"> </span><span class="lit">30</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Fares'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0
</pre>

<p>
	لاحظ أنّ هذا المثال يدمج الجداول باستخدام الكلمة المفتاحية <code>USING</code> بدلاً من <code>ON</code> المُستخدمة في صيغة المثال السابق. وهذا ممكن لأنّ كل من الجدولين لديهما عمود <code>clientID</code> يتشاركان فيه نفس نوع البيانات.
</p>

<p>
	لمزيد من التفاصيل حول عمليات الدمج باستخدام <code>JOIN</code>، ننصحك بقراءة المقال التالي كيفية استخدام عمليات الدمج في SQL.
</p>

<h2 id="update">
	تغيير سلوك تعليمة UPDATE للمفاتيح الخارجية
</h2>

<p>
	ستفشل أي تعليمة <code>UPDATE</code> قد تسبب تعارضًا مع قيد <code>FOREIGN KEY</code> افتراضيًا.
</p>

<p>
	بالعودة إلى فقرة <strong>الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية</strong> في مستلزمات العمل وبتذكّر أنّ العمود <code>clientID</code> في جدول العروض <code>shows</code> هو مفتاح خارجي يشير إلى عمود <code>clientID</code> في جدول العملاء <code>clients</code>. فهذا يعني أنّ أي قيمة مُدخلة في عمود <code>clientID</code> الخاص بجدول العروض يجب أن تكون موجودة بالفعل في جدول العملاء.
</p>

<p>
	فإذا حاولت تحديث قيمة <code>clientID</code> لسجل ما في جدول العملاء والتي تظهر أيضًا في عمود <code>clientID</code> لجدول العروض، فسيؤدي ذلك إلى حدوث خطأ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_59" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> SET clientID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">9</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Ahmad'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
</pre>

<p>
	يمكنك تجنب هذا الخطأ بتغيير قيد المفتاح الخارجي الحالي بآخر يتعامل مع عمليات التحديث على نحوٍ مختلف.
</p>

<p>
	<strong>ملاحظة</strong>: لا تسمح كافة أنظمة إدارة <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">قواعد البيانات العلاقية</a> أو محركات قواعد البيانات بإضافة أو إزالة قيد من جدول موجود بالفعل كما هو موضح في الفقرات التالية. فإذا كنت تستخدم نظام RDBMS غير MySQL، يجب عليك الرجوع إلى الوثائق الرسمية الخاصة به لفهم القيود الموجودة بخصوص إدارة القيود.
</p>

<p>
	بالعودة إلى موضوعنا، ولاستبدال القيد الحالي، عليك بدايةً إزالته باستخدام تعليمة <code><a href="https://wiki.hsoub.com/SQL/alter_table" rel="external">ALTER TABLE</a></code>. تذكّر أننا في تعليمة <code>CREATE TABLE</code> الخاصة بجدول العروض <code>shows</code>، حددنا <code>client_fk</code> كاسم لقيد المفتاح الخارجي <code>FOREIGN KEY</code> للجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_64" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE shows
mysql</span><span class="pun">&gt;</span><span class="pln"> DROP FOREIGN KEY client_fk</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
</pre>

<p>
	بعد ذلك، أنشئ قيد مفتاح خارجي جديد مُعدّ ليتعامل مع عمليات التحديث <code>UPDATE</code> بطريقة تتناسب مع الحالة الاستخدامية المعطاة. بصرف النظر عن الإعداد الافتراضي الذي يمنع تعليمات <code>UPDATE</code> التي تخالف المفتاح الخارجي، هناك خياران آخران متاحان في معظم أنظمة إدارة قواعد البيانات العلاقية:
</p>

<ul>
	<li>
		<code>ON UPDATE SET NULL</code>: يسمح لك هذا الخيار بتحديث السجلات من الجدول الأب، وسيعيد تعيين أي قيم مرتبطة بها في الجدول الابن على أنها قيم فارغة <code>NULL</code>.
	</li>
	<li>
		<code>ON UPDATE CASCADE</code>: عند تحديث سجل في الجدول الأب، سيدفع هذا الخيار SQL لتحديث أي سجلات في الجدول الابن مرتبطة بذلك السجل من الجدول الأب لتتماشى مع القيمة الجديدة المُحدّثة.
	</li>
</ul>

<p>
	في سياق هذا المثال، لا يُعد استخدام خيار <code>ON UPDATE SET NULL</code> منطقيًا، فلو غيّرت مُعرّف لأحد العملاء دون حذفه من جدول <code>clients</code>، ينبغي أن يبقى مرتبطًا بعروضه في الجدول <code>shows</code>. ويجب أن يظهر المُعرّف الجديد ضمن سجلات عروضه، وبالتالي يكون استخدام الخيار <code>ON UPDATE CASCADE</code> هو الأنسب لهذا السياق.
</p>

<p>
	لإضافة قيد <code>FOREIGN KEY</code> يعمل وفق آلية <code>ON UPDATE CASCADE</code>، نفّذ أمر <code>ALTER TABLE</code> التالي. ستنشئ هذه التعليمة قيد جديد باسم <code>new_client_fk</code> يعكس تعريف القيد السابق ولكن مع إضافة خيار <code>ON UPDATE CASCADE</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_66" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE shows
mysql</span><span class="pun">&gt;</span><span class="pln"> ADD CONSTRAINT new_client_fk
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> REFERENCES clients </span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ON UPDATE CASCADE</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 10 rows affected (0.02 sec)
Records: 10  Duplicates: 0  Warnings: 0
</pre>

<p>
	تشير هذه النتائج إلى أن العملية قد أثرت على جميع السجلات العشرة وقامت بتعديلها في جدول العروض <code>shows</code>.
</p>

<p>
	<strong>ملاحظة</strong>: بدلًا من تغيير تعريف جدول مُعرّف مسبقًا لتعديل كيفية تفاعل قيد المفتاح الخارجي مع عمليات <code>UPDATE</code>، يُمكنك من البداية تحديد هذا السلوك عند إنشاء الجدول بواسطة تعليمة <code>CREATE TABLE</code>، وبذلك تُعيّن السلوك المطلوب مُسبقًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_68" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE shows
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">showID </span><span class="kwd">int</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> showDate date</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> clientID </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> attendance </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ticketPrice </span><span class="kwd">decimal</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CONSTRAINT client_fk
mysql</span><span class="pun">&gt;</span><span class="pln"> FOREIGN KEY </span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> REFERENCES clients</span><span class="pun">(</span><span class="pln">clientID</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> ON UPDATE CASCADE
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	عقب ذلك، ستكون قادرًا على تحديث قيمة <code>clientID</code> لأي سجل في جدول <code>clients</code>، وستنتقل هذه التغييرات بشكل تلقائي إلى جميع السجلات المرتبطة بها في جدول <code>shows</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_70" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> UPDATE clients
mysql</span><span class="pun">&gt;</span><span class="pln"> SET clientID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">9</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Ahmad'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
</pre>

<p>
	رغم أن هذا الخرج يشير إلى تأثر سجل واحد فقط، إلا أنّ العملية قد حدّثت في الواقع قيمة <code>clientID</code> لكل سجلات جدول العروض المرتبطة بـ Ahmad في جدول <code>shows</code>. وللتحقق من ذلك، نفّذ الاستعلام التالي لاسترجاع كافة البيانات من الجدول <code>shows</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3095_72" style=""><span class="pln">$ SELECT </span><span class="pun">*</span><span class="pln"> FROM shows</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+--------+------------+----------+------------+-------------+
| showID | showDate   | clientID | attendance | ticketPrice |
+--------+------------+----------+------------+-------------+
|      1 | 2019-12-25 |        4 |        144 |       22.50 |
|      2 | 2020-01-11 |        9 |         84 |       29.50 |
|      3 | 2020-01-17 |        3 |        190 |       19.49 |
|      4 | 2020-01-31 |        9 |        234 |       14.99 |
|      5 | 2020-02-08 |        1 |         86 |       30.00 |
|      6 | 2020-02-14 |        3 |        122 |       59.25 |
|      7 | 2020-02-15 |        2 |        101 |       26.50 |
|      8 | 2020-02-27 |        2 |        186 |       19.99 |
|      9 | 2020-03-06 |        4 |        222 |       45.00 |
|     10 | 2020-03-07 |        9 |        250 |        8.99 |
+--------+------------+----------+------------+-------------+
10 rows in set (0.00 sec)
</pre>

<p>
	كما هو متوقع، تسبب التحديث الذي أُجري على عمود <code>clientID</code> في جدول <code>clients</code> في تحديث السجلات المرتبطة في جدول <code>shows</code>.
</p>

<h2 id="-2">
	الخلاصة
</h2>

<p>
	بوصولك إلى نهاية هذا المقال، ستكون قد اكتسبت المعرفة حول كيفية تعديل السجلات الموجودة في جدول واحد أو أكثر باستخدام تعليمة <code>UPDATE</code> في SQL. كما تعرفت على كيفية تعامل SQL مع عمليات التحديث التي تتعارض مع قيود المفتاح الخارجي وطرق تغيير هذا السلوك الافتراضي.
</p>

<p>
	ومن المفترض أن تعمل الأوامر المشروحة في هذا المقال مع أي نظام لإدارة قواعد البيانات يستخدم SQL. لكن تذكر أن لكل قاعدة بيانات SQL تقديمها الخاص للغة، لذا ينبغي مراجعة التوثيق الرسمي لنظام إدارة قواعد البيانات الخاص بك للحصول على وصف أكثر تفصيلاً لكيفية التعامل مع عمليات التحديث والخيارات المتاحة لها.
</p>

<p>
	وللمزيد حول SQL، نشجعك على متابعة <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">المقالات المنشورة تحت وسم سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-update-data-in-sql" rel="external nofollow">How To Update Data in SQL</a> لصاحبه Mark Drake.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%AF%D8%B1%D8%A7%D8%AC-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r2226/" rel="">كيفية إدراج البيانات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D9%82%D8%AF%D9%85-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sql-r961/" rel="">المرجع المتقدم إلى لغة SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول ومعلومات المخطط وترتيب تنفيذ الاستعلامات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/" rel="">حذف الجداول وقواعد البيانات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%87%D9%85%D9%8A%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أهمية قواعد البيانات</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2242</guid><pubDate>Wed, 07 Feb 2024 12:04:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x625;&#x62F;&#x631;&#x627;&#x62C; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%AF%D8%B1%D8%A7%D8%AC-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r2226/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/----SQL.png.2a0f4200b1093799b645460bb634de51.png" /></p>
<p>
	تُقدّم لغة الاستعلامات البنيوية SQL، مرونةً هائلةً من حيث الطرق الممكنة لإدراج البيانات في الجداول. فعلى سبيل المثال، يمكنك تحديد سجلات بيانات فردية باستخدام الكلمة المفتاحية <code>VALUES</code>، أو نسخ مجموعات كاملة من البيانات من الجداول الحالية باستخدام الاستعلامات <code>SELECT</code>. كما يمكن تعريف الأعمدة بأساليب تسمح للغة SQL بإدراج البيانات فيها تلقائيًا.
</p>

<p>
	في هذا المقال، سنستعرض كيفية استخدام الصيغة <code>INSERT INTO</code> في SQL لإضافة البيانات إلى الجداول وفق كل من هذه الأساليب.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز حاسوب يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العلاقيَّة RDBMS التي تستخدم SQL. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، كما هو موضح في مقال <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		نظام إدارة قواعد البيانات MySQL مثبت على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في سياق المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقيَّة تستخدم تقديمات فريدة خاصة بها للغة SQL. فعلى الرغم من أن الأوامر المُوضحة في هذا المقال ستعمل على نحوٍ سليم في معظم هذه الأنظمة، ولكن قد تختلف الصياغة الدقيقة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، ستحتاج أيضًا إلى قاعدة بيانات يمكنك استخدامها للتدرّب على إدراج البيانات. إذا لم تكن لديك قاعدة بيانات للتجربة، اطلع على فقرة الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية** التالي للحصول على تفاصيل حول كيفية إنشائها.
</p>

<h2 id="mysql">
	الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم بعيد، اتصل بالخادم مُستخدمًا بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr> من جهازك المحلي على النحو التالي:
</p>

<pre class="ipsCode">$ mysql -u user -p
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode">$ mysql -u user -p
</pre>

<p>
	أنشئ قاعدة بيانات باسم <code>insertDB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_6" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE insertDB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>insertDB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_8" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE insertDB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	بعد اختيار قاعدة البيانات <code>insertDB</code>، أنشئ جدولًا داخلها. فعلى سبيل المثال، بفرض لديك مصنع وترغب في إنشاء جدول لتخزين بعض المعلومات عن موظفيك. سيحتوي هذا الجدول على الأعمدة الخمسة التالية:
</p>

<ul>
	<li>
		<code>name</code>: اسم كل موظف، ويُعبّر عنه باستخدام نمط البيانات <code>varchar</code> مع حد أقصى للطول قدره 30 محرفًا.
	</li>
	<li>
		<code>position</code>: يخزن هذا العمود الموقع الوظيفي لكل موظف، ويُعبّر عنه أيضًا باستخدام نمط البيانات <code>varchar</code> مع حد أقصى للطول قدره 30 محرفًا.
	</li>
	<li>
		<code>department</code>: يمثل القسم الذي يعمل فيه كل موظف، ويُعبّر عنه باستخدام نمط البيانات <code>varchar</code> ولكن بحد أقصى للطول قدره 20 محرفًا فقط.
	</li>
	<li>
		<code>hourlyWage</code>: عمود لتسجيل أجر كل موظف بالساعة، ويستخدم نمط البيانات <code>decimal</code>، إذ تقتصر أي قيم في هذا العمود على حد أقصى قدره أربعة أرقام، مع وجود رقمين من هذه الأرقام على يمين الفاصلة العشرية. وبالتالي، تتراوح القيم المسموح بها في هذا العمود من ‎-99.99 إلى 99.99.
	</li>
	<li>
		<code>startDate</code>: تاريخ تعيين كل موظف، ويُعبّر عنه باستخدام نمط البيانات <code>date</code>. ويجب أن تتوافق القيم من هذا النوع مع التنسيق YYYY-MM-DD.
	</li>
</ul>

<p>
	أنشئ جدولًا باسم <code>factoryEmployees</code> يحتوي على هذه الأعمدة الخمسة، على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_10" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE factoryEmployees </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> position varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> department varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> hourlyWage </span><span class="kwd">decimal</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> startDate date
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	وبهذا، أصبحت جاهزًا لمتابعة الخطوات في المقال وبدء التعلم حول كيفية إدراج البيانات باستخدام SQL.
</p>

<h2 id="-1">
	إدراج البيانات يدويًا
</h2>

<p>
	تبدو الصيغة العامة لإدراج البيانات في SQL كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_12" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO table_name
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> columnN</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">value1</span><span class="pun">,</span><span class="pln"> value2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> valueN</span><span class="pun">);</span></pre>

<p>
	للتوضيح، نفّذ الأمر <code>INSERT INTO</code> التالي لتحميل جدول <code>factoryEmployees</code> مع سجل واحد من البيانات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_14" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> department</span><span class="pun">,</span><span class="pln"> hourlyWage</span><span class="pun">,</span><span class="pln"> startDate</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Agnes'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'thingamajig foreman'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'management'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">26.50</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2017-05-01'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.00 sec)
</pre>

<p>
	يبدأ هذا الأمر بالكلمات المفتاحية <code>INSERT INTO</code>، يليها اسم الجدول الذي ترغب في إدراج البيانات فيه. وبعد اسم الجدول، تأتي قائمة بأسماء الأعمدة التي ستضيف البيانات إليها والتي تكون محصورة ضمن أقواس هلالية. وبعد قائمة الأعمدة، تأتي الكلمة المفتاحية <code>VALUES</code>، ومن ثم مجموعة من القيم محاطة بأقواس هلالية ومفصولة برموز فاصلة.
</p>

<p>
	الترتيب الذي تُدرج فيه الأعمدة ليس بالأمر المُلزم، ولكن من الأساسي ضمان تطابق ترتيب القيم مع ترتيب الأعمدة المُدرجة. إذ ستُدرج SQL القيمة الأولى في العمود الأول المُحدد، والقيمة الثانية في العمود الثاني، وهكذا. وللتوضيح لاحظ أن الأمر <code>INSERT</code> في المثال التالي سيضيف سجلًا جديدًا من البيانات، ولكن بترتيب مختلف للأعمدة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_16" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">department</span><span class="pun">,</span><span class="pln"> hourlyWage</span><span class="pun">,</span><span class="pln"> startDate</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> position</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'production'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">15.59</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2018-04-28'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Jim'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'widget tightener'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.00 sec)
</pre>

<p>
	إذا لم تتطابق القيم على نحوٍ صحيح مع ترتيب الأعمدة، قد تُدرج SQL البيانات في الأعمدة الخاطئة. ناهيك عن إمكانية حدوث خطأ في حال تعارضت أي من القيم مع نوع البيانات المحدد للعمود، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_18" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> hourlyWage</span><span class="pun">,</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> startDate</span><span class="pun">,</span><span class="pln"> department</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Louise'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'doodad tester'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">16.50</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2017-05-01'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'quality assurance'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
ERROR 1366 (HY000): Incorrect decimal value: 'doodad tester' for column 'hourlyWage' at row 1
</pre>

<p>
	وعلى الرغم من ضرورة توفير قيمة لكل عمود تحدده، ولكن بالمقابل ليس من الضروري تحديد كل عمود في الجدول عند إضافة سجل جديد من البيانات. ففي حال عدم وجود <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">قيود</a> على الأعمدة التي تتجاهلها (كالقيد <code>NOT NULL</code>)، ستضع MySQL القيمة الفارغة <code>NULL</code> في الأعمدة غير المُحددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_20" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> position</span><span class="pun">,</span><span class="pln"> hourlyWage</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Harry'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'whatzit engineer'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">26.50</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	فإذا كنت تخطط لإدخال سجل يتضمّن قيمًا لكل عمود في الجدول، فليس من الضروري تضمين أسماء الأعمدة على الإطلاق. ومع ذلك، عليك التأكد من أن القيم المُدخلة تتوافق مع الترتيب الذي عُرّفت الأعمدة وفقًا له لدى تعريف الجدول.
</p>

<p>
	في هذا المثال، تتوافق القيم المدرجة مع الترتيب الذي عُرّفت الأعمدة وفقًا له في تعليمة <code>CREATE TABLE</code> الخاصة بالجدول <code>factoryEmployee</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_22" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Marie'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'doodad welder'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'production'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">27.88</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2018-03-29'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.00 sec)
</pre>

<p>
	كما يمكنك إضافة سجلات متعددة في وقت واحد عبر فصل كل سجل بعلامة فاصلة، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_24" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Giles'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'gizmo inspector'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'quality assurance'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">26.50</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2019-08-06'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Daphne'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'gizmo presser'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'production'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">32.45</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2017-11-12'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Joan'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'whatzit analyst'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'quality assurance'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">29.00</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2017-04-29'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
</pre>

<h2 id="select">
	نسخ البيانات باستخدام تعليمات <code>SELECT</code>
</h2>

<p>
	يمكنك نسخ سجلات البيانات المتعددة من جدول ما وإدراجها في جدول آخر باستخدام استعلام <code>SELECT</code> بدلًا من تحديد البيانات سجلًا تلو الآخر. تبدو صيغة هذه العملية كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_26" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO table_A </span><span class="pun">(</span><span class="pln">col_A1</span><span class="pun">,</span><span class="pln"> col_A2</span><span class="pun">,</span><span class="pln"> col_A3</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT col_B1</span><span class="pun">,</span><span class="pln"> col_B2</span><span class="pun">,</span><span class="pln"> col_B3
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM table_B</span><span class="pun">;</span></pre>

<p>
	فبدلًا من إلحاق قائمة الأعمدة بالكلمة المفتاحية <code>VALUES</code>، ألحقنا الصيغة ضمن هذا المثال بتعليمة <code>SELECT</code>. إذ تشمل تعليمة <code>SELECT</code> في هذه الصيغة بنية <code>FROM</code> فقط، ولكن يمكن لأي استعلام صالح أن يعمل هنا على نحوٍ صحيح.
</p>

<p>
	لتوضيح ذلك، نفّذ العملية <code>CREATE TABLE</code> التالية لإنشاء جدول جديد باسم <code>showroomEmployees</code>. لاحظ أن أعمدة هذا الجدول لها نفس الأسماء وأنماط البيانات كما في ثلاثة أعمدة من الجدول <code>factoryEmployees</code> المُستخدم في القسم السابق:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_28" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE showroomEmployees </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> hourlyWage </span><span class="kwd">decimal</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">2</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> startDate date
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.02 sec)
</pre>

<p>
	الآن يمكنك ملء هذا الجدول الجديد ببعض البيانات من الجدول <code>factoryEmployees</code> المُنشأ سابقًا عن طريق إضافة استعلام <code>SELECT</code> ضمن تعليمة <code>INSERT INTO</code>.
</p>

<p>
	إذا أعاد استعلام <code>SELECT</code> نفس عدد الأعمدة وبنفس الترتيب كما في أعمدة الجدول الهدف، وكان لها أيضًا نفس أنماط البيانات، فيمكنك حينها تجاهل قائمة الأعمدة في تعليمة <code>INSERT INTO</code>، على النحو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_30" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO showroomEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">name</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">hourlyWage</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">startDate
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Agnes'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0
</pre>

<p>
	<strong>ملاحظة:</strong> كل من الأعمدة المدرجة في الاستعلام <code>SELECT</code> الخاص بالعملية أعلاه مسبوقة باسم الجدول <code>factoryEmployees</code> متبوعًا برمز النقطة. وعندما نُحدد اسم جدول بهذه الطريقة عند الإشارة إلى عمود، فيُطلق عليها مصطلح الإشارة الكاملة للعمود fully qualified column reference. الأمر غير الضروري في هذه الحالة الخاصة في المثال أعلاه. ففي الواقع، ستعطي التعليمة <code>INSERT INTO</code> في الأمثلة التالية نفس النتيجة كالتعليمة السابقة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_32" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO showroomEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT
mysql</span><span class="pun">&gt;</span><span class="pln"> name</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> hourlyWage</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> startDate
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Agnes'</span><span class="pun">;</span></pre>

<p>
	وقد استخدمنا في الأمثلة ضمن هذا القسم طريقة الإشارة الكاملة للعمود من باب التوضيح، ولكن من المستحسن استخدامها دائمًا. فهي لا تساعد في جعل لغة الاستعلام SQL أكثر وضوحًا فحسب، ولكنها تغدو كضرورة في العمليات التي تتضمن الإشارة إلى أكثر من جدول، كالاستعلامات التي تحتوي على بنية الدمج <code>JOIN</code>.
</p>

<p>
	تشمل تعليمة الاستعلام <code>SELECT</code> في هذه العملية البنية <code>WHERE</code>، وبوجودها سيُعيد الاستعلام من الجدول <code>factoryEmployees</code> السجلات التي تحتوي على القيمة <code>Agnes</code> في العمود <code>name</code> فقط. وبما أن هناك سجلًا واحدًا فقط في الجدول المصدر موافق لهذه القيمة، فينسخ هذا السجل فقط إلى الجدول <code>showroomEmployees</code>.
</p>

<p>
	لتأكيد ذلك، نفّذ الاستعلام التالي لاسترجاع جميع السجلات في جدول <code>showroomEmployees</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_34" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM showroomEmployees</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+-------+------------+------------+
| name  | hourlyWage | startDate  |
+-------+------------+------------+
| Agnes |      26.50 | 2017-05-01 |
+-------+------------+------------+
1 row in set (0.00 sec)
</pre>

<p>
	يمكنك إدراج عدة سجلات من البيانات باستخدام أي استعلام يُعيد أكثر من سجل من الجدول المصدر. فعلى سبيل المثال، سيُعيد الاستعلام في التعليمة التالية جميع سجلات قاعدة البيانات <code>factoryEmployees</code> التي لا تبدأ قيمها ضمن العمود <code>name</code> بالحرف <code>J</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_36" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO showroomEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">name</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">hourlyWage</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> factoryEmployees</span><span class="pun">.</span><span class="pln">startDate
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM factoryEmployees
mysql</span><span class="pun">&gt;</span><span class="pln"> WHERE name NOT LIKE </span><span class="str">'J%'</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0
</pre>

<p>
	نفّذ هذا الاستعلام مجددًا لاسترجاع جميع السجلات في الجدول <code>showroomEmployees</code>:
</p>

<pre class="ipsCode">mysql&gt; SELECT * FROM showroomEmployees;
</pre>

<pre class="ipsCode">+--------+------------+------------+
| name   | hourlyWage | startDate  |
+--------+------------+------------+
| Agnes  |      26.50 | 2017-05-01 |
| Agnes  |      26.50 | 2017-05-01 |
| Harry  |      26.50 | NULL       |
| Marie  |      27.88 | 2018-03-29 |
| Giles  |      26.50 | 2019-08-06 |
| Daphne |      32.45 | 2017-11-12 |
+--------+------------+------------+
6 rows in set (0.00 sec)
</pre>

<p>
	نلاحظ وجود سجلين متطابقين يحملان القيمة <code>Agnes</code> في العمود <code>name</code>. فعند تنفيذ تعليمة <code>INSERT INTO</code> التي تستخدم الاستعلام <code>SELECT</code>, تُعامل SQL نتيجة الاستعلام هذا كمجموعة جديدة من البيانات. فبدون فرض قيود محددة على الجدول أو الاعتماد على استعلامات أدق وأكثر تحديدًا، لن يكون هناك ما يمنع وجود تكرار في السجلات عند إضافة البيانات بهذه الطريقة.
</p>

<h2 id="-2">
	إدراج البيانات تلقائيًا
</h2>

<p>
	يمكن تطبيق بعض السمات على الأعمدة لدى إنشاء جدول، والتي تجعل نظام إدارة قواعد البيانات العلاقيّ يملؤها بالبيانات تلقائيًا.
</p>

<p>
	للتوضيح، نفّذ التعليمة التالية لتعريف جدول باسم <code>interns</code>. إذ ستُنشئ هذه العملية جدولًا باسم <code>interns</code> يحتوي على ثلاثة أعمدة. العمود الأول في هذا المثال، وهو <code>internID</code>، يحتوي على بيانات من النمط int. ولكن لاحظ أنه يشمل أيضًا سمة <code>AUTO_INCREMENT</code>. هذه السمة ستجعل SQL تُنشئ قيمة رقمية فريدة تلقائيًا لكل سجل جديد، تبدأ افتراضيًا بالرقم 1 وتزداد تلقائيًا بخطوة مقدارها واحد مع كل سجل تالي.
</p>

<p>
	وبالمثل، يشمل تعريف العمود الثاني الذي يُدعى <code>department</code> الكلمة المفتاحية <code>DEFAULT</code>. ما سيجعل نظام إدارة قواعد البيانات العلاقيّ يدرج القيمة الافتراضية – وهي الكلمة 'production' في مثالنا - تلقائيًا وذلك في حال حذف العمود <code>department</code> من قائمة الأعمدة ضمن تعليمة <code>INSERT INTO</code>، على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_38" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE interns </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> internID </span><span class="kwd">int</span><span class="pln"> AUTO_INCREMENT PRIMARY KEY</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> department varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> DEFAULT </span><span class="str">'production'</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	<strong>ملاحظة:</strong> تعدّ السمة <code>AUTO_INCREMENT</code> ميزة خاصة <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-mysql-r28/" rel="">بنظام إدارة قواعد البيانات MySQL</a>، ولكن العديد من أنظمة إدارة قواعد البيانات العلاقيّة لديها طريقتها الخاصة لتحقيق التزايد في الأرقام الصحيحة. وللحصول على فهم أفضل حول كيفية تعامل نظام إدارة قواعد البيانات العلاقي مع مسألة الزيادة التلقائية، يُفضل الرجوع إلى التوثيق الرسمي الخاص بهذا النظام.
</p>

<p>
	وإليك التوثيق الرسمي بخصوص هذا الموضوع لبعض قواعد البيانات المفتوحة المصدر الشهيرة:
</p>

<ul>
	<li>
		<a href="https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html" rel="external nofollow">توثيق سمة <code>AUTO_INCREMENT</code> لـ MySQL</a>
	</li>
	<li>
		<a href="https://www.postgresql.org/docs/9.1/datatype-numeric.html" rel="external nofollow">توثيق نمط البيانات <code>serial</code> لـ PostgreSQL </a>
	</li>
	<li>
		<a href="https://www.sqlite.org/autoinc.html" rel="external nofollow">توثيق الكلمة المفتاحية <code>Autoincrement</code> لـ SQLite. </a>
	</li>
</ul>

<p>
	ولتوضيح هذه الميزات، لنحمّل الجدول <code>interns</code> ببعض البيانات، وذلك بتنفيذ تعليمة <code>INSERT INTO</code> التالية. إذ تُحدّد هذه العملية القيم للعمود <code>name</code> فقط:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_41" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO interns </span><span class="pun">(</span><span class="pln">name</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="str">'Pierre'</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Sheila'</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Francois'</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0
</pre>

<p>
	ومن ثمّ شغّل هذا الاستعلام ليعيد كافّة السجلات من الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_43" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM interns</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+----------+------------+----------+
| internID | department | name     |
+----------+------------+----------+
|        1 | production | Pierre   |
|        2 | production | Sheila   |
|        3 | production | Francois |
+----------+------------+----------+
3 rows in set (0.00 sec)
</pre>

<p>
	يُظهر هذا الخرج أنّه وبسبب تعريفات الأعمدة فإنّ التعليمة <code>INSERT INTO</code> السابقة أضافت قيمًا إلى العمودين <code>internID</code> و<code>department</code>، على الرغم من عدم تحديدهما.
</p>

<p>
	لإضافة قيمة مختلفة عن تلك الافتراضية لعمود <code>department</code>، يجب تحديد ذلك العمود ضمن تعليمة <code>INSERT INTO</code>، كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_45" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> INSERT INTO interns </span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> department</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> VALUES
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Jacques'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'management'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Max'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'quality assurance'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Edith'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'management'</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="str">'Daniel'</span><span class="pun">,</span><span class="pln"> DEFAULT</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
</pre>

<p>
	لاحظ أن السجل الأخير من القيم المُقدمة في هذا المثال يشتمل على الكلمة المفتاحية <code>DEFAULT</code> بدلًا من قيمة نصية. سيؤدي ذلك إلى جعل قاعدة البيانات تدرج القيمة الافتراضية (<code>'production'</code>).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2236_47" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM interns</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
+----------+-------------------+----------+
| internID | department        | name     |
+----------+-------------------+----------+
|        1 | production        | Pierre   |
|        2 | production        | Sheila   |
|        3 | production        | Francois |
|        4 | management        | Jacques  |
|        5 | quality assurance | Max      |
|        6 | management        | Edith    |
|        7 | production        | Daniel   |
+----------+-------------------+----------+
7 rows in set (0.00 sec)
</pre>

<h2 id="-3">
	الخلاصة
</h2>

<p>
	تعرفت في هذا المقال على العديد من طرق إدراج البيانات في الجداول، بما في ذلك تحديد سجلات البيانات على نحوٍ فرديّ باستخدام الكلمة المفتاحية <code>VALUES</code>، ونسخ مجموعات كاملة من البيانات باستخدام استعلامات <code>SELECT</code>، وتعريف الأعمدة التي ستُدرج فيها SQL البيانات تلقائيًا.
</p>

<p>
	ومن الجدير بالذكر أن الأوامر التي شرحناها هنا يجب أن تعمل على أي نظام لإدارة قواعد البيانات يستخدم SQL. لكن عليك مراعاة أن كل قاعدة بيانات SQL تستخدم تقديمًا فريدًا للّغة، لذلك يُفضّل الرجوع إلى التوثيقات الرسمية لنظام إدارة قواعد البيانات الخاص بك للحصول على توصيف أدق لكيفية التعامل مع تعليمة <code>INSERT INTO</code> والخيارات المتاحة لها.
</p>

<p>
	للمزيد حول كيفية التعامل مع SQL، ننصحك بالاطلاع على <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-use-constraints-in-sql" rel="external nofollow">How To Use Constraints in SQL</a> لصاحبه Mark Drake.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D9%81%D9%8A-sql-r2225/" rel="">كيفية استخدام القيود في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">جلب الاستعلامات عبر SELECT في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%D8%8C-%D8%A7%D9%84%D8%AD%D8%B0%D9%81-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D9%81%D9%8A-sql-r587/" rel="">التعامل مع البيانات (الإدخال، الحذف والتعديل) في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/" rel="">مدخل إلى SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/" rel="">تحديث الجداول في SQL</a>
	</li>
</ul>

<p>
	 
</p>
]]></description><guid isPermaLink="false">2226</guid><pubDate>Tue, 30 Jan 2024 12:03:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x642;&#x64A;&#x648;&#x62F; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D9%81%D9%8A-sql-r2225/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/----SQL.png.5d6dc2411574d71bd3bb6f503ad9b4b9.png" /></p>
<p>
	عند تصميم قاعدة بيانات باستخدام SQL، قد تُضطر أحيانًا إلى فرض قيود على نمط البيانات التي يمكن إضافتها إلى أعمدة معينة ضمن جدول. إذ توفّر لك SQL هذه الإمكانية من خلال ما يُعرف بالقيود constraints. فبمجرد تطبيق قيد على عمود أو جدول، ستفشل أي محاولة لإضافة بيانات لا تتوافق مع هذا القيد. ولعلّ لكل نظام من أنظمة قواعد البيانات التي تستخدم SQL طريقته الخاصة في التعامل مع القيود.
</p>

<p>
	يهدف هذا المقال إلى تقديم نظرة عامة حول الصيغة المُتبعة في العديد من أنظمة إدارة قواعد البيانات للتعامل مع القيود، مع التركيز على <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a> كمثال رئيسي<br>
	في هذا الإطار.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز حاسوب يُشغّل أحد أنواع أنظمة إدارة قواعد البيانات العِلاقيَّة RDBMS التي تستخدم <a href="https://wiki.hsoub.com/SQL" rel="external">SQL</a>. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة أوبنتو، مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، كما هو موضح في مقال <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		MySQL مثبتة ومؤمنة على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">قواعد البيانات العلاقيَّة</a> تستخدم تقديمات فريدة خاصة بها للغة SQL. فعلى الرغم من أن الأوامر المُوضحة في هذا المقال ستعمل على نحوٍ سليم في معظم هذه الأنظمة، ولكن قد تختلف الصياغة الدقيقة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، فمن المفيد أيضًا أن يكون لديك فهم عام حول قيود SQL وكيفية عملها. وللحصول على نظرة عامة حول هذا المفهوم، يمكنك الرجوع إلى مقال <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">فهم قيود SQL</a>.
</p>

<p>
	كما ستحتاج إلى قاعدة بيانات يمكنك استخدامها للتدرّب على إنشاء الجداول مع القيود. إذا لم تكن لديك قاعدة بيانات للتجربة، اطلع على القسم <strong>إعداد قاعدة بيانات تجريبية نموذجية والاتصال بها</strong> التالي للحصول على تفاصيل حول كيفية إنشائها.
</p>

<h2 id="-1">
	إعداد قاعدة بيانات تجريبية نموذجية والاتصال بها
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم عن بُعد، اتصل بالخادم مُستخدمًا بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr> من جهازك المحلي على النحو:
</p>

<pre class="ipsCode">$ ssh user@your_server_ip
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_8" style=""><span class="pln">$ mysql </span><span class="pun">-</span><span class="pln">u user </span><span class="pun">-</span><span class="pln">p</span></pre>

<p>
	أنشئ قاعدة بيانات باسم <code>constraintsDB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_10" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE constraintsDB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>constraintsDB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_12" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE constraintsDB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	وبذلك تغدو جاهزًا للخوض في الخطوات التالية من مقالنا هذا لتنطلق في تعلّم كيفية إنشاء وإدارة الجداول في SQL.
</p>

<h2 id="-2">
	إنشاء الجداول مع القيود
</h2>

<p>
	عادةً ما تُعرّف القيود أثناء إنشاء الجدول. فمثلًا تُنشئ الصيغة التالية لتعليمة <code>CREATE TABLE</code> جدولًا باسم <code>employeeInfo</code> (معلومات الموظفين) يحتوي على ثلاثة أعمدة: <code>empId</code> (لتخزين مُعرّف الموظف) و<code>empName</code> (لتخزين اسم الموظف) و <code>empPhoneNum</code> (لتخزين رقم هاتف الموظف). كما تُطبّق هذه التعليمة أيضًا القيد <code>UNIQUE</code> على العمود <code>empId</code>. ما سيمنع وجود أي قيم متطابقة فيه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_14" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE employeeInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> empId </span><span class="kwd">int</span><span class="pln"> UNIQUE</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> empName varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> empPhoneNum </span><span class="kwd">int</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	تُعرّف هذه التعليمة القيد <code>UNIQUE</code> مباشرةً بعد العمود <code>empId</code>، ما يعني أن القيد ينطبق فقط على هذا العمود. فإذا حاولت إضافة أي بيانات إلى هذا الجدول، سيراقب نظام إدارة قواعد البيانات المحتوى الحالي للعمود <code>empId</code> للتأكد من أنّ القيم الجديدة التي تضيفها إليه فريدة بالفعل. وهذا ما يُسمّى بالقيد على مستوى العمود.
</p>

<p>
	كما من الممكن تطبيق القيد خارج تعريفات العمود. ففي المثال التالي، نُنشئ جدولًا باسم <code>racersInfo</code> (معلومات المتسابقين) يحتوي على ثلاثة أعمدة: <code>racerId</code> (لتخزين مُعرّف المتسابق) و<code>racerName</code> (لتخزين اسم المتسابق) و<code>finish</code> (لتخزين ترتيب إنهاء المتسابق للسباق). وأسفل تعريفات الأعمدة، نُطبّق القيد <code>CHECK</code> على العمود <code>finish</code> لضمان أن ترتيب كل متسابق أكبر من أو يساوي <code>1</code> (إذ لا يمكن أن يكون ترتيب أي متسابق أقل من المركز الأول):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_16" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE racersInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> racerId </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> finish </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> racerName varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CHECK </span><span class="pun">(</span><span class="pln">finish </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	ونظرًا لتطبيق القيد خارج تعريف أي من الأعمدة الفردية، فيتعين عليك تحديد اسم الأعمدة التي ترغب بتطبيق القيد عليها بين قوسين هلاليين.
</p>

<p>
	دائمًا في حال تحديد قيد خارج تعريفات الأعمدة الفردية، نُسمّي هذا القيد بقيد على مستوى الجدول. فالقيود على مستوى العمود تنطبق فقط على الأعمدة الفردية، في حين قد تُطبّق قيود الجدول على عدة أعمدة.
</p>

<h2 id="-3">
	تسمية القيود
</h2>

<p>
	عندما تحدد قيدًا، يولد نظام إدارة قواعد البيانات العِلاقيَّة اسمًا له تلقائيًا. يُستخدم هذا الاسم للإشارة إلى القيد في رسائل الخطأ وفي الأوامر المستخدمة لإدارة القيود.
</p>

<p>
	قد يكون من المريح لمدراء قواعد البيانات في بعض الأحيان توفير اسماء خاصة للقيود. فعادةً لا تكون أسماء القيود المُنشأة تلقائيًا وصفية، لذلك قد يساعد توفير الاسم بنفسك في تذكر الغرض من القيد.
</p>

<p>
	لتسمية قيد، ضع الكلمة المفتاحية <code>CONSTRAINT</code> متبوعة بالاسم الذي تختاره وذلك قبل نوع القيد. فمثلًا تعيد التعليمات التالية إنشاء جدول <code>racersInfo</code> مع تسميته <code>newRacersInfo</code> وإضافة الاسم <code>noNegativeFinish</code> للقيد <code>CHECK</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_18" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE newRacersInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> racerId </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> finish </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> racerName varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CONSTRAINT noNegativeFinish 
mysql</span><span class="pun">&gt;</span><span class="pln"> CHECK </span><span class="pun">(</span><span class="pln">finish </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	<strong>ملاحظة:</strong> إذا لم تُحدّد اسمًا للقيد، أو حددته ونسيته لاحقًا، فمن المحتمل أن تعثر عليه بالرجوع إلى <a href="https://en.wikipedia.org/wiki/Information_schema" rel="external nofollow">تخطيطات معلومات قاعدة البيانات information schemas</a> لنظام إدارة قواعد البيانات الخاص بك. إذ توفّر العديد من أنظمة قواعد البيانات الحديثة وعملاؤها اختصارًا لعرض تعليمات <code>CREATE</code> الداخلية والتي تشير إلى اسم القيد.
</p>

<p>
	وفيما يلي روابط التوثيقات الرسمية لهذه الاختصارات لكل من MySQL وPostgreSQL:
</p>

<ul>
	<li>
		<a href="https://dev.mysql.com/doc/refman/8.0/en/show-create-table.html" rel="external nofollow">MySQL</a>: تتضمّن MySQL التعليمة <code>SHOW CREATE TABLE</code>، والتي تعيد كامل تعليمة <code>CREATE TABLE</code> التي أنشأت الجدول المطوب، على النحو:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_20" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW CREATE TABLE table_name</span><span class="pun">;</span></pre>

<ul>
	<li>
		<a href="https://www.postgresql.org/docs/current/app-psql.html" rel="external nofollow">PostgreSQL</a>: يتضمن عميل PostgreSQL المُسمّى <a href="https://academy.hsoub.com/devops/servers/databases/postgresql/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B5%D8%AF%D9%81%D8%A9-psql-r473/" rel=""><code>psql</code></a> على العديد من الخيارات التي يمكنك استخدامها للكشف عن معلومات حول جدول معين. فالخيار <code>d\</code> مثلًا يعيد بياناتٍ وصفية حول الجدول المطلوب:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_22" style=""><span class="typ">Postgres</span><span class="pun">=#</span><span class="pln"> \d table_name</span></pre>

<h2 id="-4">
	إدارة القيود
</h2>

<p>
	يمكنك إضافة القيود إلى الجداول الموجودة أصلًا في MySQL أو حذفها باستخدام أوامر <code>ALTER TABLE</code>.
</p>

<p>
	على سبيل المثال، الأمر التالي يضيف قيد <code>UNIQUE</code> إلى العمود <code>empName</code> في الجدول <code>employeeInfo</code> المُنشأ مسبقًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_24" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE employeeInfo ADD UNIQUE </span><span class="pun">(</span><span class="pln">empName</span><span class="pun">);</span></pre>

<p>
	عند إضافة قيد إلى جدول موجود، يمكنك أيضًا استخدام الكلمة المفتاحية <code>CONSTRAINT</code> لتوفير اسم لتعريف القيد. فالأمر في المثال التالي يضيف قيد <code>UNIQUE</code> باسم <code>uID</code> إلى العمود <code>racerId</code> من الجدول <code>racersInfo</code> المُنشأ مسبقًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_26" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE racersInfo ADD CONSTRAINT uID UNIQUE </span><span class="pun">(</span><span class="pln">racerId</span><span class="pun">);</span></pre>

<p>
	وستفشل التعليمة <code>ALTER TABLE</code> إذا أدخلت أي سجلات قد تنتهك شرط القيد الجديد قبل إضافته وفق هذه الطريقة.
</p>

<p>
	لحذف قيد، استخدم الصيغة <code>DROP CONSTRAINT</code>، متبوعة باسم القيد الذي ترغب في حذفه. فمثلًا الأمر التالي سيحذف القيد <code>uID</code> المُنشأ في الأمر السابق:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1075_28" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE racersInfo DROP CONSTRAINT uID</span><span class="pun">;</span></pre>

<h2 id="-5">
	الخلاصة
</h2>

<p>
	تعلمت في هذا المقال كيفية إضافة وحذف القيود للأعمدة والجداول باستخدام SQL. ومن الجدير بالذكر أن الأوامر التي شرحناها هنا يجب أن تعمل على أي نظام لإدارة قواعد البيانات يستخدم SQL. لكن عليك مراعاة أن كل قاعدة بيانات SQL تستخدم تقديمًا فريدًا للّغة، لذلك يُفضّل الرجوع إلى التوثيقات الرسمية لنظام إدارة قواعد البيانات الخاص بك للحصول على توصيف أدق لكل أمر والخيارات المتاحة.
</p>

<p>
	للمزيد حول كيفية التعامل مع SQL، ننصحك بالاطلاع على <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-use-constraints-in-sql" rel="external nofollow">How To Use Constraints in SQL</a> لصاحبه Mark Drake.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%88%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r2224/" rel="">كيفية إنشاء وإدارة الجداول في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%8A%D9%83%D9%84%D9%8A%D8%A9-sql-r1368/" rel="">نظرة سريعة على لغة الاستعلامات الهيكلية SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D9%87%D9%85-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-queries-%D9%81%D9%8A-mysql-r295/" rel="">مدخل إلى أهم الاستعلامات (queries) في MySQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-mysql-r28/" rel="">مدخل إلى برنامج إدارة قواعد البيانات MySQL</a>
	</li>
</ul>

<p>
	 
</p>
]]></description><guid isPermaLink="false">2225</guid><pubDate>Tue, 23 Jan 2024 12:09:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x625;&#x646;&#x634;&#x627;&#x621; &#x648;&#x625;&#x62F;&#x627;&#x631;&#x629; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%88%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r2224/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/-----SQL.png.26f1907c6877b99b1fdfc83db7c54dbe.png" /></p>
<p>
	الجداول هي الهياكل التنظيمية الأساسية في قواعد بيانات SQL. وهي تتكون من عدد من الأعمدة التي تعكس السمات الفردية لكل صف أو سجل في الجدول. ولعلّ من المهم لكل من يعمل مع قواعد البيانات العلاقية أن يفهم كيفية إنشاء وتغيير وحذف الجداول حسب الحاجة كونها جزءًا أساسيًا من آلية تنظيم البيانات.
</p>

<p>
	سنتناول في هذا المقال كيفية إنشاء الجداول في SQL، بالإضافة إلى كيفية تعديل وحذف الجداول الموجودة أصلًا في قاعدة البيانات.
</p>

<h2 id="">
	مستلزمات العمل
</h2>

<p>
	لمتابعة الخطوات في هذا المقال، ستحتاج إلى جهاز كمبيوتر يُشغّل أحد أنواع أنظمة إدارة <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">قواعد البيانات العلاقية</a> RDBMS التي تستخدم SQL. وقد اختبرنا الأوامر البرمجية والأمثلة في هذا المقال مستخدمين البيئة التالية:
</p>

<ul>
	<li>
		خادم عامل على توزيعة <span ipsnoautolink="true">أوبنتو،</span> مع مستخدم ذو صلاحيات مسؤول مختلف عن المستخدم الجذر، وجدار حماية مكوّن باستخدام UFW، كما هو موضح في مقال <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AA%D9%88%D8%B2%D9%8A%D8%B9%D8%A9-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%85%D9%86-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A3%D8%A8%D8%B3%D8%B7-%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-r575/" rel="">كيفية تثبيت توزيعة أوبنتو من لينكس بأبسط طريقة</a>.
	</li>
	<li>
		نظام إدارة قواعد البيانات MySQL مثبت على الخادم، كما هو موضح في المقال <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيفية تثبيت MySQL على أوبونتو</a>. وقد نفذنا خطوات هذا المقال باستخدام مستخدم MySQL مختلف عن المستخدم الجذر، مُنشأ وفق الطريقة الموضحة في الخطوة 3 من هذا المقال.
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقية لها تقديماتها الفريدة من <a href="https://academy.hsoub.com/programming/sql/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%8A%D9%83%D9%84%D9%8A%D8%A9-sql-r1368/" rel="">لغة SQL</a>. فبالرغم من كون الأوامر المُقدمة في هذا المقال ستعمل مع معظم هذه الأنظمة، ولكن قد تجد بعض الاختلافات الطفيفة في الصيغة أو الناتج عند تنفيذها على أنظمة مختلفة عن <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a>.
</p>

<p>
	وبالعودة إلى مستلزمات العمل، ستحتاج أيضًا إلى <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">قاعدة بيانات</a> وجدول مُحمّل ببعض البيانات التجريبية النموذجية لتتمكن من التدرب على استخدام محارف البدل. وإذا لم تكن متوفرة لديك، يمكنك مراجعة الفقرة التالية <strong>الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية</strong> للمزيد من التفاصيل حول كيفية إعداد قاعدة بيانات وجدول لاستخدامهما في الأمثلة خلال هذا المقال.
</p>

<h2 id="mysql">
	الاتصال بـ MySQL وإعداد قاعدة بيانات تجريبية نموذجية
</h2>

<p>
	إذا كان نظام قاعدة بيانات SQL الخاص بك يعمل على خادم بعيد، فاتصل بالخادم مُستخدمًا بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></abbr> من جهازك المحلي على النحو التالي:
</p>

<pre class="ipsCode">$ ssh user@your_server_ip
</pre>

<p>
	ثم افتح واجهة سطر الأوامر في خادم MySQL، مُستبدلًا <code>user</code> باسم حساب مستخدم MySQL الخاص بك:
</p>

<pre class="ipsCode">$ mysql -u user -p
</pre>

<p>
	الآن أنشئ قاعدة بيانات باسم <code>tablesDB</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_10" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE tablesDB</span><span class="pun">;</span></pre>

<p>
	وبمجرّد إنشاء قاعدة البيانات بنجاح ستحصل على خرجٍ كالتالي:
</p>

<pre class="ipsCode">الخرج
Query OK, 1 row affected (0.01 sec)
</pre>

<p>
	ولاختيار قاعدة البيانات <code>tablesDB</code>، نفّذ تعليمة <code>USE</code> التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_19" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> USE tablesDB</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Database changed
</pre>

<p>
	وبذلك تغدو جاهزًا لتجربة الخطوات التالية من مقالنا هذا لتنطلق في تعلّم كيفية إنشاء وإدارة الجداول في SQL.
</p>

<h2 id="-1">
	إنشاء الجداول
</h2>

<p>
	لإنشاء جدول في SQL، استخدم الأمر <code>CREATE TABLE</code> متبوعًا بالاسم الذي ترغب بتسمية الجدول به:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_21" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE table_name</span><span class="pun">;</span></pre>

<p>
	وكما هو الحال مع كل تعليمات SQL، انتبه إلى وجوب انتهاء تعليمات <code>CREATE TABLE</code> برمز الفاصلة المنقوطة <code>;</code>.
</p>

<p>
	تُنشئ الصيغة في المثال السابق جدولًا فارغًا بدون أي أعمدة. أمّا لإنشاء جدول يتضمّن أعمدة محددة، فيجب أن نُتبع اسم الجدول بقائمة تتضمن أسماء الأعمدة وأنماط البيانات الموافقة لكل منها <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">والقيود</a> المتعلقة بها، محصورةً بين أقواس هلالية ومفصولة برمز الفاصلة، على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_23" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE table_name </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> column1_name column1_data_type</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> column2_name column2_data_type</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> columnN_name columnN_data_type
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	كمثال، لنفترض أنك ترغب بإنشاء جدول لتسجيل بعض المعلومات حول المنتزهات التي تفضلها في مدينة نيويورك. فبعد اتخاذ قرار بشأن السمات التي تود تسجيلها حول كل منتزه، ستحدّد أسماء الأعمدة لكل من تلك السمات وكذلك نمط البيانات المناسب لكل منها:
</p>

<ul>
	<li>
		<code>parkName</code>: اسم كل منتزه. ونظرًا لوجود تباين واسع في أطوال أسماء المنتزهات، سيكون استخدام نمط البيانات <code>varchar</code> بطول أعظمي يبلغ <code>30</code> محرفًا مناسبًا.
	</li>
	<li>
		<code>yearBuilt</code>: السنة التي بُني فيها المنتزه. على الرغم من أنّ MySQL تتضمّن نمط بيانات يُسمّى <code>year</code> (لتخزين السنوات الميلادية)، إلّا أنّه يسمح فقط بقيم تتراوح بين <code>1901</code> و <code>2155</code>. ولأن هناك عدة منتزهات في مدينة نيويورك بُنيت قبل عام 1901، لذلك من الأفضل استخدام نمط بيانات الأعداد الصحيحة <code>int</code> كبديل.
	</li>
	<li>
		<code>firstVisit</code>: تاريخ أول زيارة لك لكل منتزه. تتضمّن MySQL نمط بيانات <code>date</code> لتخزين التواريخ، ومن المناسب استخدامه لهذا العمود، إذ يُخزّن البيانات بالتنسيق <code>YYYY-MM-DD</code> (اليوم بخانتين-الشهر بخانتين-السنة بأربع خانات).
	</li>
	<li>
		<code>lastVisit</code>: تاريخ زيارتك الأخيرة لكل منتزه. ويمكنك هنا استخدام نمط البيانات <code>date</code> مجددًا.
	</li>
</ul>

<p>
	ولإنشاء جدول باسم <code>faveParks</code> يحتوي على أعمدة بهذه الأسماء وأنماط البيانات، نفّذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_25" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE faveParks </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> parkName varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> yearBuilt </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> firstVisit date</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> lastVisit date
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.01 sec)
</pre>

<p>
	ومن الجدير بالملاحظة أن الأمر أعلاه يُنشئ هيكلية الجدول فقط، إذ أنّك لم تُضف أي بيانات إلى الجدول بعد.
</p>

<p>
	كما يمكنك إنشاء جداول جديدة استنادًا إلى جداول موجودة أصلًا باستخدام الصيغة <code>CREATE TABLE AS</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_31" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE new_table_name AS </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> columnN
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM old_table_name
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	فبدلًا من إلحاق اسم الجدول الجديد (new_table_name) بقائمة من أسماء الأعمدة وأنماط البيانات الموافقة، نُتبعه بتعليمه <code>AS</code> ومن ثم تعليمة <code>SELECT</code> بين قوسين هلاليين والتي تُرجع الأعمدة والبيانات التي نرغب في نسخها من الجدول الأصلي (old_table_name) إلى الجدول الجديد.
</p>

<p>
	ومن الجدير بالملاحظة أنّه إذا كانت أعمدة الجدول الأصلي تتضمّن أي بيانات، فسيتم نسخ تلك البيانات إلى الجدول الجديد أيضًا. وللتوضيح، تشمل صيغة المثال أعلاه استعلام باستخدام <code>SELECT</code> والذي يحتوي فقط على بنية <code>FROM</code> المطلوبة. ولكن أي تعليمة صحيحة من تعليمات <code>SELECT</code> ستعمل على نحوٍ سليم في هذا المكان.
</p>

<p>
	ولمزيد من التوضيح، يُنشئ الأمر التالي جدولًا باسم <code>parkInfo</code> من خلال استخدام عمودين من الجدول <code>faveParks</code> المُنشأ سابقًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_29" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE parkInfo AS </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT parkName</span><span class="pun">,</span><span class="pln"> yearBuilt
mysql</span><span class="pun">&gt;</span><span class="pln"> FROM faveParks
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
</pre>

<p>
	فإذا كان الجدول <code>faveParks</code> يحتوي على أي بيانات، فستنسخ البيانات الموجودة في أعمدة <code>parkName</code> و<code>yearBuilt</code> إلى جدول <code>parkInfo</code> أيضًا. ولكن في حالتنا، كلا الجدولين سيكون فارغًا.
</p>

<p>
	أمّا إذا حاولت إنشاء جدول مُستخدمًا اسم جدول موجود مُسبقًا من خلال التعليمات التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_33" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE parkInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> squareFootage </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> designer varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
ERROR 1050 (42S01): Table 'parkInfo' already exists
</pre>

<p>
	فسيؤدي ذلك إلى وقوع خطأ يشير إلى أنّ الاسم <code>parkinfo</code> موجود أصلًا.
</p>

<p>
	ولتجنب هذا الخطأ، يمكنك إضافة الخيار <code>IF NOT EXISTS</code> ضمن أمر <code>CREATE TABLE</code> الخاص بك. إذ سيُخبر هذا الخيار قاعدة البيانات بالتحقق من وجود جدول موجود مسبقًا بنفس الاسم المحدد، ففي حال كان موجودًا، سيظهر تحذير بدلًا من رسالة الخطأ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_35" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE IF NOT EXISTS parkInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> squareFootage </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> designer varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected, 1 warning (0.00 sec)
</pre>

<p>
	سيفشل هذا الأمر في إنشاء جدول جديد، إذ أنّ الجدول بالاسم <code>parkInfo</code> ما زال موجودًا أصلًا. ولكن نلاحظ أن الخرج يشير إلى كون تعليمة <code>CREATE TABLE</code> أدت إلى ظهور تحذير. ولعرض رسالة التحذير، نفّذ الأمر التشخيصي <code>SHOW WARNINGS</code> كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_38" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW WARNINGS</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
| Level | Code | Message                         |
+-------+------+---------------------------------+
| Note  | 1050 | Table 'parkInfo' already exists |
+-------+------+---------------------------------+
1 row in set (0.00 sec)
</pre>

<p>
	وكما يشير هذا الخرج، فقد سُجّل نفس الخطأ الذي تلقيته سابقًا على أنه تحذير، ذلك لأنك قد ضمّنت الخيار <code>IF NOT EXISTS</code>. وهذا الأمر قد يكون مفيدًا في بعض الحالات، كما هو الحال عند تنفيذ المعاملات Transactions التي تمثل سلسلة من عمليات SQL تُجرى على قاعدة بيانات وتعامل كما لو كانت عملية واحدة، بحيث إما أن تُنفَّذ جميعها أو لا تنفذ بأكملها، في حين يشير التحذير إلى فشل التعليمة الذي تسببت به فقط.
</p>

<h2 id="-2">
	تعديل الجداول
</h2>

<p>
	قد تضطر في بعض الحالات إلى تغيير تعريف جدول معين وهذا الأمر مختلف عن تحديث البيانات ضمن الجدول فهو يعني تغيير هيكلية الجدول نفسه. وللقيام بذلك، يمكنك استخدام الصيغة <code>ALTER TABLE</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_40" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE table_name ALTER_OPTION sub_options </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">;</span></pre>

<p>
	وبعد تضمين تعليمة <code>ALTER TABLE</code>، حدّد اسم الجدول الذي تود تعديله. ومن ثم مرّر الخيارات المتاحة بناءً على نظام إدارة قواعد البيانات الخاص بك لإجراء التعديل المطلوب.
</p>

<p>
	على سبيل المثال، قد ترغب في تغيير اسم الجدول أو إضافة عمود جديد أو حذف عمود قديم أو تغيير تعريف أحد الأعمدة.
</p>

<p>
	لنطبق بعض الأمثلة على جدول المنتزهات المُفضّلة <code>faveParks</code> الذي أنشأناه سابقًا في قسم إنشاء الجداول لمزيد من التدريب على كتابة تعليمات التعامل مع الجداول.
</p>

<p>
	لتغيير اسم الجدول <code>faveParks</code>، يمكنك استخدام صيغة <code>RENAME TO</code>. يغير المثال التالي اسم جدول <code>faveParks</code> إلى <code>faveNYCParks</code>:
</p>

<p>
	<strong>تحذير:</strong> كن حذرًا عند تغيير اسم جدول. فالقيام بذلك قد يسبب مشكلات في حال كان هناك تطبيق يستخدم الجدول أو إذا كانت هناك جداول أخرى في قاعدة البيانات تشير إليه.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_42" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE faveParks RENAME TO faveNYCParks</span><span class="pun">;</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.01 sec)
</pre>

<p>
	لإضافة عمود جديد للجدول، استخدم الخيار <code>ADD COLUMN</code>. يضيف المثال التالي عمود بالاسم <code>borough</code>، والذي يُخزّن بيانات من النمط <code>varchar</code>، ولكن بطول أقصى يبلغ <code>20</code> محرفًا إلى الجدول <code>faveNYCParks</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_44" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE faveNYCParks ADD COLUMN borough varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">);</span></pre>

<pre class="ipsCode">الخرج
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
</pre>

<p>
	لحذف عمود من جدول مع أي بيانات يحتوي عليها، يمكنك استخدام الصيغة <code>DROP TABLE</code>. يحذف الأمر في المثال التالي العمود <code>borough</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_46" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE faveNYCParks DROP COLUMN borough</span><span class="pun">;</span></pre>

<p>
	تسمح العديد من تقديمات SQL بتغيير تعريف العمود باستخدام الصيغة <code>ALTER TABLE</code>. ويستخدم المثال التالي بنية <code>MODIFY COLUMN</code> في MySQL، إذ يقوم بتغيير العمود <code>yearBuilt</code> لاستخدام بيانات من النمط <code>smallint</code> بدلًا من النمط <code>int</code> الأصلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_48" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> ALTER TABLE faveNYCParks MODIFY COLUMN yearBuilt smallint</span><span class="pun">;</span></pre>

<p>
	ومما يجب أخذه في الحسبان أنّ كل نظام إدارة قواعد بيانات يتضمّن خيارات مختلفة بخصوص ما يمكنك تغييره باستخدام تعليمة <code>ALTER TABLE</code>. ولتحقيق فهمٍ كامل حول ما يمكنك تنفيذه باستخدام <code>ALTER TABLE</code>, راجع التوثيق الرسمي لنظام إدارة قواعد البيانات الذي تستخدمه لمعرفة الخيارات المتاحة للتعليمة.
</p>

<p>
	إليك التوثيق الرسمي حول هذا الموضوع لبعضٍ من أشهر قواعد البيانات مفتوحة المصدر:
</p>

<ul>
	<li>
		<a href="https://dev.mysql.com/doc/refman/8.0/en/alter-table.html" rel="external nofollow">توثيق <code>ALTER TABLE</code> في MySQL</a>
	</li>
	<li>
		<a href="https://www.postgresql.org/docs/12/sql-altertable.html" rel="external nofollow">توثيق <code>ALTER TABLE</code> في PostgreSQL</a>
	</li>
	<li>
		<a href="https://www.sqlite.org/lang_altertable.html" rel="external nofollow">توثيق <code>ALTER TABLE</code> في SQLite</a>
	</li>
</ul>

<h2 id="-3">
	حذف الجداول
</h2>

<p>
	لحذف جدول وجميع البيانات الموجودة فيه، استخدم الصيغة <code>DROP TABLE</code>:
</p>

<p>
	<strong>تحذير:</strong> كن حذرًا عند تنفيذ الأمر <code>DROP TABLE</code>، إذ سيقوم بحذف الجدول وجميع بياناته نهائيًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_50" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DROP TABLE table_name</span><span class="pun">;</span></pre>

<p>
	كما يمكنك حذف عدة جداول باستخدام تعليمة <code>DROP</code> واحدة وذلك بفصل أسماء الجداول برمز فاصلة ومحرف مسافة، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_52" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DROP TABLE table1</span><span class="pun">,</span><span class="pln"> table2</span><span class="pun">,</span><span class="pln"> table3</span><span class="pun">;</span></pre>

<p>
	للتوضيح، سيحذف الأمر التالي كل من جدولي <code>faveNYCParks</code> و <code>parkInfo</code> المُنشأين سابقًا في هذا المقال:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5943_54" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DROP TABLE IF EXISTS faveNYCParks</span><span class="pun">,</span><span class="pln"> parkInfo</span><span class="pun">;</span></pre>

<p>
	لاحظ أن هذا المثال يتضمن الخيار <code>IF EXISTS</code>، والذي يؤدي الوظيفة المعاكسة لخيار <code>IF NOT EXISTS</code> المتاح لأمر إنشاء الجداول <code>CREATE TABLE</code>. إذ سيجعل خيار <code>IF EXISTS</code> تعليمة <code>DROP TABLE</code> تعيد تحذيرًا بدلًا من رسالة خطأ في حال لم يكن أحد الجداول المُحدّدة موجودًا.
</p>

<h2 id="-4">
	الخلاصة
</h2>

<p>
	تعلمت في هذا المقال كيفية إنشاء وتغيير وحذف الجداول في قواعد البيانات المبنية على SQL. ومن الجدير بالذكر أن الأوامر التي شرحناها هنا يجب أن تعمل على أي نظام لإدارة قواعد البيانات يستخدم SQL. لكن عليك مراعاة أن كل قاعدة بيانات SQL تستخدم تقديمًا فريدًا للّغة، لذلك يُفضّل الرجوع إلى التوثيقات الرسمية لنظام إدارة قواعد البيانات الخاص بك للحصول على توصيف أدق لكل أمر والخيارات المتاحة.
</p>

<p>
	للمزيد حول كيفية التعامل مع SQL، ننصحك بالاطلاع على <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-create-and-manage-tables-in-sql" rel="external nofollow">How To Create and Manage Tables in SQL</a> لصاحبه Mark Drake.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">فهم قيود SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D9%82%D8%AF%D9%85-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sql-r961/" rel="">المرجع المتقدم إلى لغة SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول ومعلومات المخطط وترتيب تنفيذ الاستعلامات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/" rel="">حذف الجداول وقواعد البيانات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%87%D9%85%D9%8A%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أهمية قواعد البيانات</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2224</guid><pubDate>Thu, 18 Jan 2024 12:07:00 +0000</pubDate></item><item><title>&#x641;&#x647;&#x645; &#x642;&#x64A;&#x648;&#x62F; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/--SQL.png.31a72b51f818a89ab7c8d68a376b9997.png" /></p>
<p>
	لدى تصميمك لقاعدة بيانات، قد تحتاج أحيانًا إلى وضع قيود على البيانات المسموح إدخالها ضمن أعمدة معينة في هذه القاعدة. على سبيل المثال، إذا كنت تنوي تصميم جدول لتخزين معلومات حول ناطحات سحاب، فلا بدّ من أنك سترغب في منع إدخال قيم سالبة في العمود الخاص بارتفاع كل مبنى.
</p>

<p>
	تُمكنّك أنظمة إدارة قواعد البيانات العلاقية RDBMSs من التحكّم بالبيانات التي يُسمح بإضافتها إلى الجدول من خلال ما يُسمّى بالقيود constraints. والقيد عبارة عن قاعدة خاصة تُفرض على عمود واحد أو أكثر، أو حتى على الجدول كاملًا، وتحدد هذه القاعدة التغييرات المتاح إجراؤها على بيانات الجدول، سواء كان هذا التغيير من هو أمر إدراج بيانات جديدة <code>INSERT</code>، أو تحديث بيانات موجوة <code>UPDATE</code>، أو حذف بيانات معينة <code>DELETE</code>.
</p>

<p>
	سنعرض في هذا المقال مفهوم القيود وكيفية استخدامها في أنظمة RDBMS بالتفصيل، كما سنستعرض القيود الخمسة المُعرفّة في معايير SQL ونشرح الوظيفة الأساسية لكل منها.
</p>

<h2 id="">
	ما هي القيود؟
</h2>

<p>
	القيد constraint في SQL هو أي قاعدة تُطبق على عمود أو جدول بهدف تحديد طبيعة البيانات التي يمكن إدخالها فيه. فعند كل محاولة لإجراء عملية من شأنها تغيير البيانات الموجودة في جدول – من خلال أمر إدراج <code>INSERT</code> أو تحديث <code>UPDATE</code> أو حذف <code>DELETE</code> للبيانات مثلًا – ستتحقق نظم إدارة قواعد البيانات العلاقية فيما إذا كانت هذه البيانات تخالف أي من القيود الموجودة أم لا، وستعيد خطأ إذا كانت تخالفها بالفعل أو ستنفذها في حال كانت تحقق المعايير المطلوبة.
</p>

<p>
	يعتمد مسؤولو قواعد البيانات على القيود لضمان اتباع قاعدة البيانات لمجموعة مُحددة من قواعد وتوجيهات العمل، وفي إطار قواعد البيانات، تُعرّف القاعدة بأنها أي سياسة أو إجراء تتبعه الشركة أو أي منظمة أخرى لتحدد من خلالها كيفية تخزين البيانات في قاعدة البيانات، إذ يجب أن تتوافق بياناتها مع هذه القواعد تمامًا.
</p>

<p>
	على سبيل المثال، إذا كنت تعمل على تطوير قاعدة بيانات لرصد مخزون متجر لأحد العملاء وطلب منك هذا العميل التأكد من وجود رقم تعريف فريد لكل سجل (منتج)، فبإمكانك وضع القيد <code>UNIQUE</code> (المُعبّر عن كون كل سجل في العمود المعني فريد) على العمود المُخصص للرقم التعريفي لضمان عدم وجود أي تكرار في القيم المدخلة لأرقام المنتجات المختلفة.
</p>

<p>
	تلعب القيود دورًا مهمًا في الحفاظ على دقة وصحة البيانات أو ما يعرف بسلامة البيانات <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D9%88%D9%82%D9%8A%D9%88%D8%AF%D9%87%D8%A7-%D9%84%D8%B6%D9%85%D8%A7%D9%86-%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r544/" rel="">data integrity</a>. إذ يُشير مصطلح سلامة البيانات إلى مدى دقة واتساق ومنطقية البيانات المحفوظة في قاعدة البيانات وفقًا لسياق استخدامها. فغالبًا ما تكون الجداول ضمن قاعدة البيانات مرتبطة ببعضها البعض، فقد تعتمد بعض الأعمدة في جدول معين على القيم الموجودة في جدول آخر. ونظرًا لأن الأخطاء البشرية واردة الحدوث أثناء إدخال البيانات، فإن وضع القيود أمر أساسي في مثل هذه الحالات، إذ أنها تضمن عدم تأثير البيانات المُدخلة على نحوٍ خاطئ على هذه العلاقات بما قد يؤثّر سلبًا بالنتيجة على سلامة البيانات.
</p>

<p>
	بفرض أنك <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">تُصمّم قاعدة بيانات</a> تتضمّن جدولين: الأول لإدراج الطلاب الحاليين في مدرسة ما، والثاني لإدراج أعضاء فريق كرة السلة في تلك المدرسة. يمكنك في هذه الحالة تطبيق قيد <code>FOREIGN KEY</code> (قيد المفتاح الخارجي) على أحد أعمدة جدول فريق كرة السلة ليشير إلى أحد أعمدة جدول الطلاب. وهذا ما سينشئ علاقة بين الجدولين، إذ يتطلب أي إدخال جديد في جدول الفريق أن يشير إلى إدخال موجود بالفعل في جدول الطلاب.
</p>

<p>
	ولدى تصميم جدول في قاعدة البيانات، يمكن للمستخدمين تحديد القيود أثناء إنشاء هذا الجدول أو إضافتها لاحقًا باستخدام إحدى تعليمات <code><a href="https://wiki.hsoub.com/SQL/alter_table" rel="external">ALTER TABLE</a></code>، بشرط ألّا تتعارض هذه القيود المُضافة مع البيانات الموجودة أصلًا في الجدول. وعند إنشاء قيد جديد، سيولّد نظام قاعدة البيانات تلقائيًا اسمًا له، ولكن وفي العديد من تطبيقات SQL يمكنك تحديد اسم مُخصّص للقيد. إذ يُستخدم هذا الاسم للإشارة إلى القيد ضمن مجموعة التعليمات <code>ALTER TABLE</code> المُتعلّقة بتعديل القيد أو إزالته.
</p>

<p>
	يُعرّف المعيار الرسمي للغة SQL خمس قيود فقط وهي:
</p>

<ul>
	<li>
		قيد المفتاح الأساسي <code>PRIMARY KEY</code>
	</li>
	<li>
		قيد المفتاح الخارجي <code>FOREIGN KEY</code>
	</li>
	<li>
		قيد القيم الفريدة <code>UNIQUE</code>
	</li>
	<li>
		قيد التحقق <code>CHECK</code>
	</li>
	<li>
		القيد غير فارغ <code>NOT NULL</code>
	</li>
</ul>

<p>
	<strong>ملاحظة:</strong> تتضمّن العديد من نظم إدارة قواعد البيانات العلاقية الكلمة المفتاحية <code>DEFAULT</code> لتحديد قيمة ابتدائية افتراضية غير فارغة <code>NULL</code> تسند لسجلات العمود في حال عدم تحديد قيمة لحظة إضافة السجل. وتصف توثيقات بعض قواعد البيانات <code>DEFAULT</code> على أنها قيد، نظرًا لأن طريقة استخدامها تشابه لطريقة استخدام القيود الأخرى مثل <code>UNIQUE</code> أو <code>CHECK</code>. ولكن ومن الناحية التقنية، لا تعدّ <code>DEFAULT</code> قيدًا حقيقيًا لأنها لا تُحدّد أو تقيّد القيم التي يمكن إدخالها في العمود.
</p>

<p>
	بالعودة إلى موضوعنا، وبعد حصولك على فهمٍ عام حول كيفية استخدام القيود، لنلقِ نظرة أعمق على كل من هذه القيود الخمسة.
</p>

<h2 id="primarykey">
	القيد PRIMARY KEY
</h2>

<p>
	يتطلب قيد المفتاح الأساسي <code>PRIMARY KEY</code> أن يكون كل مُدخل في العمود المعني غير فارغ وغير مكرر، سامحًا لك باستخدام هذا العمود لتعريف كل سجل في الجدول على نحوٍ فريد.
</p>

<p>
	والمفتاح <a href="https://wiki.hsoub.com/SQL/keys" rel="external">key</a> عمومًا في النموذج العلاقي عبارة عن عمود أو مجموعة من الأعمدة في جدول تضمن أن كل قيمة فيها فريدة وغير فارغة. أمّا المفتاح الأساسي فهو مفتاح خاص يستخدم لتعريف وتمييز سجلات الجدول على نحوٍ فردي، ويمكن استخدام العمود أو الأعمدة التي تكوّن مفتاح أساسي لتعريف الجدول وتحديده في باقي أجزاء قاعدة البيانات.
</p>

<p>
	وهذا جانب مهم في <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">قواعد البيانات العلاقية</a> فبوجود المفتاح الأساسي، لا يُضطر المستخدمون لمعرفة مكان تخزين البيانات فيزيائيًا على الجهاز، إذ يمكن لنظام إدارة قاعدة البيانات أن يتتبّع كل سجل ويسترجعه حسب الطلب. ما يعني بدوره عدم وجود ترتيب منطقي محدد للسجلات، وبالتالي يتمكّن المستخدمون من استرجاع بياناتهم بأي ترتيب يفضلونه أو وفق أي مُرشحات (عوامل تصفية) يختارونها.
</p>

<p>
	يمكنك إنشاء مفتاح أساسي في SQL باستخدام القيد <code>PRIMARY KEY</code>، والذي يُعدّ بالأصل مزيجًا من القيدين <code>UNIQUE</code> و <code>NOT NULL</code>. وبعد تعريف مفتاح أساسي، يُنشئ نظام إدارة قاعدة البيانات تلقائيًا فهرس index مرتبط به. والفهرس هو هيكلية في قاعدة البيانات تساعد في استرجاع البيانات من جدول ما بسرعة أكبر، وما على الاستعلامات إلّا استعراض الإدخالات الموافقة للعمود المُفهرس للعثور على القيم المترابطة (التابعة لسجل واحد) بآلية مُشابهة لاستخدام الفهرس في الكتب النصيّة العادية. الأمر الذي يسمح للمفتاح الأساسي بلعب دور المُعرّف لكل سجل في الجدول.
</p>

<p>
	يمكن لكل جدول أن يتضمّن <strong>مفتاح أساسي واحد فقط</strong>، والذي قد يشتمل على عدّة أعمدة كما هو الحال بالنسبة للمفاتيح النمطية regular keys، ولكن من مميزات المفاتيح الأساسية هو استعانتها بأقل عدد ممكن من السمات لتمييز كل سجل في الجدول على نحوٍ فريد. ولتبسيط هذه الفكرة، تخيل جدولًا يُخزّن معلومات الطلاب في مدرسة ما من خلال ثلاثة أعمدة كالتالي:
</p>

<ul>
	<li>
		<code>studentID</code>: يُستخدم لتخزين رقم التعريف (مُعرّف) الخاص بكل طالب.
	</li>
	<li>
		<code>firstName</code>: يُستخدم لتخزين الاسم الأول لكل طالب.
	</li>
	<li>
		<code>lastName</code>: يُستخدم لتخزين اسم العائلة لكل طالب.
	</li>
</ul>

<p>
	ولكن قد تتطابق الأسماء الأولى لبعض الطلاب في المدرسة، ما يجعل من العمود <code>firstName</code> خيارًا غير مناسب للاستخدام كمفتاح أساسي. وينطبق الأمر نفسه على العمود <code>lastName</code>. وبالتالي، قد يكون من المناسب استخدام مفتاح أساسي يتكون من الاسم الأول والأخير معًا، ولكن يبقى احتمال وجود طلاب بنفس الاسم الكامل قائمًا.
</p>

<p>
	وبالتالي، يمكن الاعتماد على مفتاح أساسي يتألف من عمود رقم تعريف الطالب <code>studentID</code> بالإضافة إلى عمود الاسم الأول <code>firstName</code> أو عمود الاسم الأخير <code>lastName</code>. ولكن وبما أنّ رقم تعريف كل طالب هو قيمة فريدة، فإنّ إضافة أحد أعمدة الأسماء للمفتاح الأساسي لا يُمثّل أي قيمة مُضافة. ولهذا، يعدّ استخدام عمود رقم تعريف الطالب وحده الخيار الأمثل ليكون المفتاح الأساسي لهذا الجدول.
</p>

<p>
	إذا كان المفتاح مكوّنًا من بيانات تطبيقية واقعية (أي بيانات تُمثّل كيانات أو أحداث أو سمات من العالم الواقعي)، فيُطلق عليه اسم مفتاح طبيعي natural key. أمّا إذا أُنشئ المفتاح داخليًا دون أن يُمثّل أي شيء خارج قاعدة البيانات، فيُعرف حينها باسم مفتاح بديل surrogate أو مفتاح مُصنّع synthetic key. تُوصي بعض أنظمة قواعد البيانات بتجنب استخدام المفاتيح الطبيعية، فحتى البيانات التي تبدو ثابتة قد تتغير بطرق غير متوقعة.
</p>

<h2 id="foreignkey">
	القيد FOREIGN KEY
</h2>

<p>
	يفرض القيد <code>FOREIGN KEY</code> أن تكون كل قيمة في العمود المعني موجودة بالفعل في عمود معين من جدول آخر.
</p>

<p>
	بفرض لديك جدولين، ووددت ربطهما ببعضهما البعض، فإحدى الطرق التي يمكنك استخدامها لهذا الغرض هي تعريف مفتاح خارجي باستخدام القيد <code>FOREIGN KEY</code>. والمفتاح الخارجي هو عمود في جدول معين (ويطلق عليه الجدول "الابن") تأتي قيمه من مفتاح في جدول آخر (ويطلق عليه "الأب" أو الجدول الرئيسي). وهذا ما يُعبّر عن علاقة بين الجدولين: فالقيد <code>FOREIGN KEY</code> يفرض أن تكون القيم في العمود المعني موجودة بالفعل في العمود المُشار إليه من الجدول الآخر.
</p>

<p>
	يُظهر المخطط التالي هذا النوع من العلاقة بين جدولين: إذ يُستخدم الأول لتسجيل معلومات حول الموظفين في شركة، ويُستخدم الثاني لتتبع مبيعات الشركة، وقد استخدمنا في هذا المثال مفتاح خارجي في جدول المبيعات <code>SALES</code> يشير إلى المفتاح الأساسي من جدول الموظفين <code>EMPLOYEES</code><span>:</span>
</p>

<p style="text-align: center;">
	<img alt="01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="141349" data-ratio="72.27" data-unique="gchrsdchv" width="512" src="https://academy.hsoub.com/uploads/monthly_2024_01/01.png.8684a99d68eba4f5250f3d716cc5ba9f.png">
</p>

<p>
	فإذا حاولت إضافة سجل إلى الجدول الابن مع كون القيمة المُدخلة في عمود المفتاح الخارجي من هذا السجل غير موجودة في عمود المفتاح الأساسي للجدول الأب فستكون تعليمة الإدراج هذه غير صالحة. الأمر الذي يضمن الحفاظ على نزاهة مستوى العلاقة بين الجدولين، بضمان ربط السجلات في الجدولين على النحو الصحيح دائمًا.
</p>

<p>
	فغالبًا ما يكون المفتاح الخارجي للجدول الابن هو المفتاح الأساسي للجدول الأب، ولكن الحال ليس على هذا النحو دائمًا. ففي معظم أنظمة إدارة قواعد البيانات العلاقية يمكن للمفتاح الخارجي في الجدول الابن الإشارة إلى أي عمود مُطبّق عليه أحد القيدين <code>PRIMARY KEY</code> أو <code>UNIQUE</code> في الجدول الأب.
</p>

<h2 id="unique">
	القيد UNIQUE
</h2>

<p>
	يمنع القيد <code>UNIQUE</code> إضافة قيم مكررة إلى العمود المعني، وكما يوحي اسمه، يتطلب هذا القيد أن تكون كل قيمة تقوم بإدخالها في العمود المعني فريدةـ وأي محاولة لإضافة قيمة موجودة بالفعل فيه ستؤدي إلى ظهور خطأ.
</p>

<p>
	تفيد القيود <code>UNIQUE</code> في فرض علاقات من نوع واحد-إلى-واحد one-to-one بين الجداول. فرغم إمكانية تكوين علاقات بين الجداول باستخدام المفتاح الخارجي كما أشرنا سابقًا، إلّا أنّ هناك عدّة أنواع من العلاقات التي قد تظهر بين الجداول:
</p>

<ul>
	<li>
		واحد-إلى-واحد: نقول بأنّ علاقة من نوع واحد-إلى-واحد تربط بين جدولين إذا كان كل سجل في الجدول الأب مرتبط بسجل واحد فقط في الجدول الابن.
	</li>
	<li>
		واحد-إلى-عديد: في علاقة واحد-إلى-عديد، يمكن أن يرتبط كل سجل في الجدول الأب مع عدة سجلات في الجدول الابن، لكن كل سجل في الجدول الابن يمكن أن يرتبط بسجل واحد فقط من الجدول الأب.
	</li>
	<li>
		عديد-إلى-عديد: نقول بأنّ علاقة من نوع عديد-إلى-عديد تربط بين الجدولين إذا كان بإمكان السجلات في الجدول الأب أن ترتبط مع عدّة سجلات من الجدول الابن، والعكس صحيح.
	</li>
</ul>

<p>
	بإضافة القيد <code>UNIQUE</code> إلى عمود قد طُبّق عليه القيد <code>FOREIGN KEY</code> أيضًا، يمكنك التأكد من أن كل مُدخل في الجدول الأب يظهر مرة واحدة فقط في الجدول الابن، وبذلك تكون قد أنشأت علاقة من نوع واحد-إلى-واحد بين الجدولين.
</p>

<p>
	ومن الجدير بالذكر أنّه يمكن تعريف القيود <code>UNIQUE</code> على مستوى الجدول أو على مستوى العمود. فعند تعريف القيد <code>UNIQUE</code> على مستوى الجدول، يمكن أن يشمل حينها أكثر من عمود. وفي مثل هذه الحالات، يمكن لكل عمود مُدرج ضمن القيد أن يحتوي على قيم مكررة، ولكن يجب أن تكون لكل سجل مجموعة فريدة من القيم في الأعمدة الخاضعة للقيد.
</p>

<h2 id="check">
	القيد CHECK
</h2>

<p>
	يُعرّف القيد <code>CHECK</code> قاعدة يجب أن تُطبق على عمود معين على هيئة عبارة شرطية predicate ويجب أن تُحقق جميع القيم المُدخلة في ذلك العمود الشرط المسند لهذا العمود. حيث تُكتب شروط القيد <code>CHECK</code> بشكل تعبير شرطي يأخذ القيمة <code>TRUE</code> (صحيح/مُحقق) أو <code>FALSE</code> (خاطئ/غير مُحقق)، أو حتى <code>UNKNOWN</code> (غير معروف وهو ما يحدث في حالة وجود قيم فارغة <code><a href="https://wiki.hsoub.com/SQL#.D8.A7.D9.84.D9.82.D9.8A.D9.85.D8.A9_NULL" rel="external">NULL</a></code> في العمود). فإذا حاولت إدخال قيمة في عمود خاضع للقيد <code>CHECK</code> وتسببت هذه القيمة في تقييم الشرط إلى <code>TRUE</code> أو <code>UNKNOWN</code> فستنجح العملية وتخزن القيمة في العمود، وإذا تم تقييم التعبير إلى <code>FALSE</code> ستفشل ولن يسمح لك بإدخالها.
</p>

<p>
	وتعتمد شروط القيد <code>CHECK</code> في كثير من الأحيان على عامل مقارنة رياضي (من قبيل <code>&lt;</code>، <code>&gt;</code>، <code>&lt;=</code>، أو <code>&gt;=</code>) لتحديد نطاق البيانات المسموح بإدخالها في العمود المُحدّد. فعلى سبيل المثال، من الاستخدامات الشائعة للقيود <code>CHECK</code> هي منع استقبال قيم سالبة في بعض الأعمدة وذلك في الحالات التي لا تكون فيها القيم السالبة مقبولة، كما سنوضح في المثال التالي.
</p>

<p>
	سنكتب تعليمة <code>CREATE TABLE</code> لإنشاء جدول يخزن بيانات المنتجات وسنطلق عليه اسم <code>productInfo</code>، يحتوي هذا الجدول على أعمدة لتخزين اسم كل منتج ورقم التعريف الخاص به وسعره. ونظرًا لأن سعر المنتج لا يمكن أن يكون سالبًا من الناحية المنطقية، فنكتب قيد <code>CHECK</code> على عمود السعر <code>price</code> لضمان احتوائه على قيم موجبة فقط بالشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9576_6" style=""><span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE TABLE productInfo </span><span class="pun">(</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> productID </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> name varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> price </span><span class="kwd">decimal</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> CHECK </span><span class="pun">(</span><span class="pln">price </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
mysql</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">);</span></pre>

<p>
	لا يُشترط استخدام عامل مقارنة رياضي في كل شرط من الشروط المنطقية الإسنادية الخاصة بالقيد <code>CHECK</code>. إذ يُمكنك استخدام أي معامل من معاملات SQL التي يمكن تقييمها في عبارة الشرط المنطقي إلى <code>TRUE</code> أو <code>FALSE</code> أو <code>UNKNOWN</code>، مثل <a href="https://wiki.hsoub.com/SQL/like" rel="external" target="_blank"><code>LIKE</code></a> و <a href="https://wiki.hsoub.com/SQL/Interval_Operators" rel="external" target="_blank"><code>BETWEEN</code></a> و <a href="https://wiki.hsoub.com/SQL/is_null" rel="external" target="_blank"><code>IS NOT NULL</code></a> وغيرها. وتسمح بعض تقديمات SQL -ولكن ليس كلها- بإضافة استعلام فرعي داخل العبارة الشرطية. في حين لا تسمح معظم التقديمات بالإشارة إلى جدول آخر داخل هذه العبارة الشرطية.
</p>

<h2 id="notnull">
	القيد NOT NULL
</h2>

<p>
	يحظرك القيد <code>NOT NULL</code> من إضافة أي قيم فارغة <code>NULL</code> إلى العمود المعني، فإذا أضفت سجل من البيانات ولم تُحدد فيه قيمة لعمود معين، فسوف يُمثّل نظام قواعد البيانات في معظم تقديمات SQL البيانات المفقودة افتراضيًا على أنها قيمة فارغة <code>NULL</code>. وفي لغة SQL تعد كلمة <code><a href="https://wiki.hsoub.com/SQL#.D8.A7.D9.84.D9.82.D9.8A.D9.85.D8.A9_NULL" rel="external">NULL</a></code> مصطلحًا خاصًّا يُستخدم لتمثيل قيمة مجهولة أو مفقودة أو غير مُحددة. ولكن <code>NULL</code> ليست قيمة بحد ذاتها، بل هي حالة تُعبّر عن قيمة مجهولة أو غير متوفرة.
</p>

<p>
	ولتوضيح هذا الفارق، تخيل جدولًا يُستخدم لتتبع العملاء في شركة لاستقطاب المواهب ويحتوي هذا الجدول على أعمدة لأسماء العملاء الأولى والأخيرة. فإذا كان العميل معروفًا باسمٍ واحدٍ فقط، فسيُدخل مدير قاعدة البيانات هذا الاسم في عمود الاسم الأول فقط، مما يتسبب في إدخال قيمة فارغة <code>NULL</code> في عمود الاسم الأخير.
</p>

<p>
	في مثل هذه الحالة لا تعدّ قاعدة البيانات أن الاسم الأخير للعميل هو حرفيًا "فارغ". بل يعني ذلك فقط أن القيمة الموجودة في عمود الاسم الأخير لذلك السجل مجهولة أو غير متوفرة.
</p>

<p>
	وبالتالي، وكما يوحي اسمه، يمنعك القيد <code>NOT NULL</code> من إدخال قيم فارغة <code>NULL</code> أو تجاهل إدخال قيمة في العمود المعني. وبالتالي ستكون مجبورًا على تحديد قيمة لأي عمود طُبِّق عليه قيد <code>NOT NULL</code> عند إضافة سجل جديد، وإلا ستفشل عملية الإدراج.
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-controller="core.front.core.autosizeiframe" data-embedauthorid="3889" data-embedcontent="" data-embedid="embed5710037664" src="https://academy.hsoub.com/files/26-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/?do=embed" style="overflow: hidden; height: 469px; max-width: 500px; margin:auto"></iframe>

<h2 id="-1">
	الخلاصة
</h2>

<p>
	تعرفنا في مقال اليوم على مفهوم القيود التي تعد أحد المفاهيم الأساسية لأي شخص يرغب في تصميم قاعدة بيانات بمستوى عالٍ من نزاهة وأمان البيانات وسلامتها. إذ يمكنك التأكد من الحفاظ على <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r590/" rel="">العلاقات بين الجداول</a> على النحو الصحيح من خلال تحديد البيانات التي يُسمح بإدخالها ضمن عمود معين، ما يضمن توافق قاعدة البيانات مع القواعد المطلوبة التي تحدد الغرض من إنشائها.
</p>

<p>
	للمزيد حول كيفية إنشاء وإدارة القيود في SQL، يمكنك مراجعة مقالنا <a href="https://academy.hsoub.com/programming/sql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D9%81%D9%8A-sql-r2225/" rel="">كيفية استخدام القيود في SQL</a>. وللمزيد حول SQL عمومًا، نشجعك على متابعة <a href="https://academy.hsoub.com/tags/%D8%B3%D9%84%D8%B3%D9%84%D8%A9%20%D8%AA%D8%B9%D9%84%D9%85%20sql/" rel="">سلسلة تعلم SQL</a> في أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/conceptual-articles/understanding-sql-constraints" rel="external nofollow" target="_blank">Understanding SQL Constraints</a> لصاحبه Mark Drake.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%84%D9%85%D8%A7%D8%B0%D8%A7-%D9%8A%D8%AC%D8%A8-%D8%B9%D9%84%D9%8A%D9%83-%D8%AA%D8%B9%D9%84%D9%85-sql-r2215/" rel="">لماذا يجب عليك تعلم SQL؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%88%D8%AA%D8%B5%D9%85%D9%8A%D9%85%D9%87%D8%A7-r519/" rel="">المفاهيم الأساسية في قواعد البيانات وتصميمها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">دليلك الشامل إلى قواعد البيانات DataBase</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-%D9%88%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D8%B9%D9%84%D9%8A%D9%87%D8%A7-r586/" rel="">البيانات في SQL: أنواعها والقيود عليها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">ما هي محركات قواعد البيانات؟</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2217</guid><pubDate>Fri, 12 Jan 2024 12:00:00 +0000</pubDate></item><item><title>&#x644;&#x645;&#x627;&#x630;&#x627; &#x64A;&#x62C;&#x628; &#x639;&#x644;&#x64A;&#x643; &#x62A;&#x639;&#x644;&#x645; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%84%D9%85%D8%A7%D8%B0%D8%A7-%D9%8A%D8%AC%D8%A8-%D8%B9%D9%84%D9%8A%D9%83-%D8%AA%D8%B9%D9%84%D9%85-sql-r2215/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/----SQL.png.f7386b9a45f82d895faaf4c8eb612042.png" /></p>
<p>
	قد تبدو لغة SQL أو لغة الاستعلام الهيكلية مُعقدة ومربكة للبعض في البداية، لكن مع التعلم والتعمق في اللغة ستصبح الأمور أوضح وأبسط فلغة SQL هي لغة سهلة التعلم بالعموم، وهي تُستخدم بشكل أساسي لتعريف ومعالجة والاستعلام عن البيانات المُخزنّة في قواعد البيانات العلاقية Relational، التي تعد أحد أشهر أنواع قواعد البيانات والتي تُنظّم البيانات فيها بدقة لتُناسب هيكلية أسطر (سجلات) وأعمدة (حقول) مُحدّدة مُسبقًا بشكل محدد وواضح.
</p>

<p>
	<strong>ملاحظة:</strong> يمكنك الاطلاع على تفاصيل أكثر حول قواعد البيانات العلاقية، بما في ذلك تاريخها والمفاهيم الرئيسية المُتعلّقة بها واستخداماتها الشائعة، بالعودة إلى المقال السابق <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">فهم قواعد البيانات العلاقية</a>.
</p>

<p>
	وبالعودة إلى موضوعنا، فقد ازدادت شهرة وشعبية لغة <a href="https://wiki.hsoub.com/SQL" rel="external">SQL</a> منذ ظهورها في السبعينيات، وتوسّعت مجالات استخدامها على نحوٍ كبير منذ ذلك الحين. وتعدّ SQL في أيامنا من أبرز وأنضج اللغات المستخدمة في الاستعلام عن البيانات ومعالجتها في معظم القطاعات ومن أكثر الأدوات شهرةً. وبالتالي، فإن فرصة استخدام لغة SQL في مجال <a href="https://academy.hsoub.com/programming/general/%D9%88%D8%B8%D8%A7%D8%A6%D9%81-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D9%83%D8%AB%D8%B1-%D8%B7%D9%84%D8%A8%D9%8B%D8%A7/" rel="">وظيفتك البرمجية</a> كبيرة، فسواء كنت تعمل كمدير لقاعدة بيانات أو مصممًا لها أو <a href="https://academy.hsoub.com/programming/general/%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA/" rel="">مهندس برمجيات</a> أو <a href="https://academy.hsoub.com/programming/general/%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">محلل بيانات</a>، وحتى لو لم تكن تعمل في أي من الوظائف آنفة الذكر فستستفيد بالفعل من فهمك لأساسيات هذه اللغة وإن لم تستخدمها بشكل مباشر.
</p>

<p>
	يُبرز هذا المقال أهمية تعلم لغة SQL، ويشرح كيف وأين يمكنك تطبيق معرفتك لهذه اللغة والاستفادة منها.
</p>

<h2 id="sql">
	لغة SQL منتشرة بشكل واسع في عالم قواعد البيانات العلاقية
</h2>

<p>
	إذا تعاملت مع أي قاعدة بيانات علاقية مثل <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a> أو <a href="https://academy.hsoub.com/devops/servers/databases/postgresql/" rel="">PostgreSQL</a> أو <a href="https://en.wikipedia.org/wiki/Microsoft_SQL_Server" rel="external nofollow" target="_blank">Microsoft SQL</a> أو <a href="https://www.oracle.com/database/technologies/appdev/sql.html" rel="external nofollow" target="_blank">Oracle SQL</a> أو غيرها الكثير، فستصادف بالتأكيد تعليمات SQL. إذ تُستخدم هذه اللغة على نطاق واسع لتعريف ومعالجة والاستعلام عن البيانات في هذا النوع من قواعد البيانات، فهي الوسيلة الأساسية للتفاعل مع <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">محرك قاعدة البيانات</a>.
</p>

<p>
	وبالرغم من أنّ العديد من أنظمة قواعد البيانات تُقدّم واجهات رسومية سهلة الاستخدام للتعامل مع بنية قاعدة البيانات وتعديل البيانات المُخزّنة فيها، إلا أن هذا لا يقلل من أهمية <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%A7-%D9%87%D9%8A-%D8%AA%D9%82%D9%86%D9%8A%D8%A9-sql%D8%9F-r1651/" rel="">تقنية SQL</a> أو يجعلها غير ضرورية. فبالرغم من إمكانية إنجاز المهام البسيطة بسرعة دون الحاجة إلى كتابة تعليمات SQL، ستتطلّب المهام الأعقد في معالجة البيانات أو الاستعلام عنها استخدام <a href="https://academy.hsoub.com/programming/sql/" rel="">لغة SQL</a> لبناء الاستعلامات وجلب البيانات التي تحتاجها بكفاءة مستفيدًا من قوة <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">محرك قاعدة البيانات</a>.
</p>

<p>
	وبالتالي بفهمك للغة SQL، ستتمكن من التعامل بسرعة مع أي نظام قاعدة بيانات علاقية مُستخدم اليوم تقريبًا، ولن تقتصر مهاراتك على برنامج محدد أو جهة عمل معينة.
</p>

<h2 id="sql-1">
	SQL مُستخدمة أيضًا على نحو واسع في مجالات عديدة أخرى
</h2>

<p>
	استطاعت SQL بفضل شهرتها واستخدامها في أنظمة قواعد البيانات العلاقية المُعتَمَدة على نحوٍ متزايد، أن تجد طريقها إلى أنظمة قواعد بيانات وأدوات تحليل بيانات أخرى.
</p>

<p>
	إذ تتمتّع SQL والعديد من اللغات المُشتقّة منها بالدعم في العديد من أنظمة التخزين ومحركات تحليل البيانات وأدوات ذكاء الأعمال وأدوات التنقيب عن البيانات، وحتى في العديد من قواعد البيانات غير العلاقية وقواعد البيانات التحليلية Online analytical processing - OLAP وحلول <a href="https://academy.hsoub.com/programming/general/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B6%D8%AE%D9%85%D8%A9-big-data-r1579/" rel="">البيانات الضخمة</a>.
</p>

<p>
	وبغض النظر عن البرمجيات التي قد تصادفها لدى تحليل مجموعات البيانات الكبيرة، فهناك احتمالية عالية بأن تستفيد من معرفتك بلغة SQL للتعامل مع البيانات ضمن تلك الأدوات. إذ ستتمكن من اتباع منهجية مشابهة مع قواعد البيانات المتنوعة، الأمر الذي سيسهل عليك العمل ويجعله أشمل عبر مصادر البيانات المختلفة. وبالتالي تعدّ معرفة SQL من الأدوات الأساسية والضرورية التي يعتمد عليها محللو البيانات <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">وعلماء البيانات</a> على الدوام.
</p>

<p>
	كما تُعد لغة SQL ضمن أول عشر لغات برمجة وفق <a href="https://www.tiobe.com/tiobe-index/" rel="external nofollow" target="_blank">مؤشر مجتمع البرمجة TIOBE</a>، وهو مؤشر يُظهر شعبية لغات البرمجة وانتشارها.
</p>

<h2 id="sql-2">
	تساعدك لغة SQL في التواصل مع الآخرين بخصوص البيانات
</h2>

<p>
	لربما تُمثّل مناقشة البيانات تحديًا في العديد من الأحيان، فقد يفهم الأشخاص اللغة المحكية بطرق مختلفة قليلًا عما هو مطلوب، ما يُنشئ غموضًا قد يؤدي بدوره إلى سوء الفهم وأخطاء في التواصل. ولكن بمعرفتك لأساسيات SQL، كفهم كيفية هيكلة البيانات وكيفية <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r588/" rel="">الاستعلام عنها بنفسك</a>، وستكون أدق لدى التواصل مع زملائك وأعضاء فريقك.
</p>

<p>
	فحتى إن لم تكن تنوي كتابة تعليمات SQL بنفسك، يمكنك استخدام خبرتك فيها لتوضيح متطلباتك وتوقعاتك بدقة. كما ستكون قادرًا على تحديد المشكلات المتعلقة بالبيانات التي تتلقاها، وتقديم تغذية راجعة واضحة وعملية لمحللي البيانات الذين يساعدونك في إعداد تلك البيانات.
</p>

<p>
	وبالتالي، يمكنك النظر إلى SQL على أنها <strong>لغة مشتركة</strong> يفهمها الجميع في عالم البيانات. فحتى إن لم تستخدمها على نحوٍ مباشر، فإن الاستناد إلى المفاهيم المُستمدّة منها ستجعل تواصلك بخصوص البيانات أدق وأوضح.
</p>

<h2 id="sql-3">
	تساعدك لغة SQL في تصميم قواعد بيانات أفضل
</h2>

<p>
	من الضروري لدى تكليفك <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">بتصميم قاعدة بيانات</a>، أن تأخذ أنماط البيانات التي ستُخزّن وكيفية الوصول إليها أو التعامل معها مُستقبلًا في الحسبان. فبالرغم أنّه من الممكن بالطبع تصميم قواعد البيانات اعتمادًا على الفهم الجيد لنظرية تصميم قواعد البيانات فقط، إلّا أنّ الانتقال من التصميم النظري إلى قاعدة البيانات الفعلية قد يكون صعبًا، وستعترض المصمم مفاجآت غير متوقعة في الغالب.
</p>

<p>
	إذ سيُستخدم نوع من استعلامات SQL مع كل عملية استرجاع بيانات من قاعدة البيانات، وسواءً كتبت هذه الاستعلامات من قبل مُحلل البيانات أو أُنشئت عبر برمجيات مُتخصّصة. فإن فهمك لأنماط الاستخدام المطلوبة ومعرفتك لكيفية ترجمتها إلى استعلامات SQL قابلة للتنفيذ، سيمكنك من فهم كيفية وصول SQL إلى قاعدة البيانات الأساسية لاسترداد البيانات، وما الذي سيتعين على محرّك قاعدة البيانات إنجازه كاستجابةً لهذا الاستعلام.
</p>

<p>
	وبالتالي، يمكنك تصميم قواعد بيانات تلبي الغرض المطلوب باستخدام المعرفة التي اكتسبتها. وبمراعاتك لحالات الاستخدام التي يجب أن تدعمها قاعدة البيانات، يمكنك اختيار هيكلية لها تُسهّل إجراء استعلامات أبسط وأكفأ تُناسب سيناريوهات الاستخدام الشائعة.
</p>

<p>
	كما يمكنك <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">هيكلة الجداول</a> على نحوٍ مدروس، مُسهلًا الوصول إلى البيانات باستخدام أنماط البيانات والعلاقات المُعتمدة على <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%8A%D9%88%D8%AF-sql-r2217/" rel="">المفاتيح الخارجية</a> و<a href="#" rel="">الفهارس</a>. بمعنى أنّك ستتعلم كيفية تصميم قواعد بيانات تُناسب أهدافك على نحوٍ أفضل.
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-controller="core.front.core.autosizeiframe" data-embedauthorid="3889" data-embedcontent="" data-embedid="embed3634687251" src="https://academy.hsoub.com/files/26-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/?do=embed" style="overflow: hidden; height: 470px; max-width: 500px;margin:auto"></iframe>

<h2 id="sql-4">
	تساعدك لغة SQL في كتابة تطبيقات أفضل
</h2>

<p>
	تستفيد العديد من أطُر التطوير الحديثة مثل أطُر تطوير الويب المشهورة <a href="https://academy.hsoub.com/programming/php/laravel/" rel="">لارافيل Laravel</a> أو <a href="https://symfony.com/" rel="external nofollow" target="_blank">Symfony</a> أو <a href="https://academy.hsoub.com/programming/python/django/" rel="">جانغو Django</a> أو <a href="https://academy.hsoub.com/programming/ruby/" rel="">Ruby on Rails</a> من طبقات تجريد البيانات، لاسيما <a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping" rel="external nofollow">أدوات التخطيط بين الكائنات وقواعد البيانات العلاقيَّة object-relational mappers</a> إذ تهدف هذه الأدوات إلى تبسيط عملية الوصول إلى البيانات وتقديمها بشكل مبسّط للمبرمج. فبينما توفر هذه الأطُر طرقًا بديلة للتفاعل مع البيانات اعتمادًا على التعليمات البرمجية البسيطة الخاصّة بها موفرّةً البيانات التي تطلبها بسلاسة، إلا أن فهمك للغة SQL سيمكّنك من التعامل مع البيانات بشكل أكثر فعالية ودقة، حتى وإن لم تستخدم SQL مباشرة في عملية التطوير.
</p>

<p>
	فبغض النظر عن العديد من الاختصارات والسهولة الكبيرة التي تقدمها <a href="https://academy.hsoub.com/programming/general/%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-framework/" rel="">أطر العمل</a>، فإنها تُبنى استعلامات في محرك قاعدة البيانات الأساسي باستخدام جمل SQL خلف الكواليس من المدخلات الخاصة بك. وبالتالي فإن فهم كيفية عمل SQL يمكن أن يساعدك في استخدام ميزات الإطار البرمجي الذي اخترته لجعل الاستعلامات أسرع وأكثر فعالية، وبهذا يمكنك الاعتماد على معرفتك بكيفية بناء الإطار للاستعلامات في توجيه بنائها وتنفيذها على نحوٍ أمثل وصولًا إلى البيانات المطلوبة.
</p>

<p>
	ناهيك عن إمكانية تصحيح أي مشكلات في الاستعلام عن البيانات ومعالجتها على نحوٍ أسهل. فغالبًا ما تُعيد محركات قواعد البيانات أخطاء تُشير إلى الجزء الذي فشل من الاستعلام المُنفّذ فعليًا باستخدام SQL. وبالرغم من دقة هذه الأخطاء، يبقى تحديد مصدر المشكلة ضمن الصياغة الخاصة بالإطار المستخدم أمرًا صعبًا، ولكن فهمك <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">لأخطاء قواعد البيانات</a> سيمكنك من تحديد المشكلة بدقة.
</p>

<p>
	وأخيرًا وليس آخرًا، ستكون أكثر وعيًا بالمخاطر الأمنية الناتجة عن استخدام استعلامات SQL على نحوٍ غير صحيح وخطير، مثل <a href="https://academy.hsoub.com/devops/security/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%AF%D9%85-%D8%A7%D9%84%D8%B3%D8%AD%D8%A7%D8%A8%D9%8A%D8%A9-%D8%B6%D8%AF-%D9%87%D8%AC%D9%85%D8%A7%D8%AA-%D8%AD%D9%82%D9%86-sql-r98/" rel="">هجمات حقن SQL</a>، كما ستكون قادرًا على مواجهتها والتصدي لها.
</p>

<p>
	فبفضل معرفتك بلغة SQL، ستمتلك السيطرة الكاملة على كيفية الوصول إلى البيانات، سواء قررت استخدام SQL مباشرةً أو اخترت العمل مع طبقات التجريد وأدوات التخطيط بين الكائنات وقواعد البيانات العلاقية ضمن الأطُر البرمجية.
</p>

<h2 id="sql-5">
	لغة SQL سهلة التعلم للمبتدئين
</h2>

<p>
	هناك العديد من الفوائد المرتبطة بفهم وتطبيق لغة الاستعلام الهيكلية في الواقع العملي. ولعلّ أحد أبرز ما يميزها هو سهولة تعلمها للمبتدئين. إذ تمتاز هذه اللغة بوضوحها ودقتها واستخدامها لكلمات إنجليزية شائعة كأسماء للعمليات والمُرشحات (عوامل التصفية) وغيرها من الواصفات (العناصر التي تغير أو تحدد سلوك الاستعلام). فيمكنك قراءة استعلامات SQL في كثير من الأحيان على هيئة جمل مكتوبة باللغة الإنجليزية، ما يجعلها مفهومة حتى دون وجود خلفية برمجية.
</p>

<p>
	ربما تجد بعض الجوانب الصعبة والمعقدة في اللغة والتي تحتاج إلى جهد لفهمها والتمرن عليها. ولكن بالمقابل يمكنك فهم وتعلم أساسيات لغة SQL بشكل ميسر. ومع استخدامك المتواصل لها في عملك اليومي، ستصبح عملية تعلم الأمور الأصعب أكثر فعالية لأنها تتم وفقًا لاحتياجاتك الفعلية للبيانات. وبالتالي يمكنك البدء مع <a href="https://academy.hsoub.com/programming/sql/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D9%91%D8%A7%D8%AA-%D9%84%D8%BA%D8%A9-sql-r585/" rel="">أساسيات SQL</a>، ومن ثم تطوير فهمك للغة تدريجيًا كلما احتجت لاستخدام طرق استعلام جديدة. والجيد في الأمر أنّ إجراء التجارب والتعامل مع SQL أثناء الاستعلام عن البيانات أمر سهل وخالٍ من المخاطر من ناحية فقدان البيانات، ما يوفّر لك الشعور بالأمان والراحة أثناء رحلة التعلّم.
</p>

<p>
	ستحصل بتعلمك للغة SQL على فوائد تتجاوز بكثير الوقت المستغرق في ذلك، وتكتسب طرقًا جديدة لاسترجاع البيانات من عدة المصادر وتحليلها وتحقق الاكتفاء الذاتي في حاجتك لتحليل البيانات، ما يفتح آفاق وظيفية جديدة في مجالات متعددة.
</p>

<h2 id="">
	الخلاصة
</h2>

<p>
	غدت لغة SQL أكثر لغات الاستعلام عن البيانات ومعالجتها شيوعًا وشهرة بفضل مرونتها وسهولة استخدامها وتطبيقها في مجالات متعددة ذات صلة بالبيانات. وبالتالي، سيوفر لك تعلمها العديد من الفوائد الجليّة، حتى وإن لم تكن وظيفتك الرئيسية مرتبطة مباشرةً بقواعد البيانات أو بتطوير البرمجيات.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/conceptual-articles/why-you-should-learn-sql" rel="external nofollow" target="_blank">Why You Should Learn SQL</a> لصاحبه Mateusz Papiernik.
</p>

<h2 id="-1">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/" rel="">فهم قواعد البيانات العلاقية</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%A7-%D9%87%D9%8A-%D8%AA%D9%82%D9%86%D9%8A%D8%A9-sql%D8%9F-r1651/" rel="">ما هي تقنية SQL؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%87%D9%85%D9%8A%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أهمية قواعد البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أنواع قواعد البيانات وأهم مميزاتها واستخداماتها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">تعرف على مكونات قاعدة البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">ما هي محركات قواعد البيانات؟</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2215</guid><pubDate>Thu, 11 Jan 2024 12:04:01 +0000</pubDate></item><item><title>&#x641;&#x647;&#x645; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x627;&#x644;&#x639;&#x644;&#x627;&#x642;&#x64A;&#x629;</title><link>https://academy.hsoub.com/programming/sql/%D9%81%D9%87%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-r2216/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2024_01/---.png.70e20c8331fa03daba8abe9f5c093e11.png" /></p>
<p>
	تعدّ أنظمة إدارة قواعد البيانات Relational database management system أو اختصارًا DMBS برامج حاسوبية تسمح للمستخدمين بالتفاعل مع قاعدة البيانات وتتيح لهم إمكانية التحكّم بالوصول إلى قاعدة البيانات وكتابة البيانات فيها وتنفيذ الاستعلامات Queries التي تستخلص البيانات أو تعدلها وإنجاز أي مهمّة أخرى ذات صلة بإدارة قواعد البيانات.
</p>

<p>
	وبالتالي كي تتمكن من إنجاز أي من هذه المهام، يجب أن تمتلك أنظمة DMBS نموذجًا أساسيًا يُعرّف كيفية تنظيم البيانات. وإحدى منهجيات تنظيم البيانات التي لاقت استخدامًا واسعًا في برمجيات قواعد البيانات منذ ابتكارها في أواخر ستينيات القرن الماضي هي النموذج العلاقيّ أو العلائقي Relational، لدرجة أنّه وحتى وقت كتابة هذا المقال فإنّ <a href="https://db-engines.com/en/ranking" rel="external nofollow">أربعة من بين أكثر خمسة أنظمة لإدارة قواعد البيانات شيوعًا</a> هي من النمط العلاقيّ.
</p>

<p>
	يوضّح هذا المقال المفاهيمي النظري تاريخ النموذج العلاقيّ وكيفية تنظيم البيانات في قواعد البيانات العلاقيَّة وكيفية استخدامها في تطبيقاتنا المختلفة.
</p>

<h2 id="-1">
	تاريخ النموذج العلاقي
</h2>

<p>
	<a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قواعد البيانات</a> عبارة عن مجموعات من المعلومات أو البيانات المُنظّمة منطقيًا. إذ تُعدّ أي مجموعة من البيانات كقاعدة بيانات، بغض النظر عن كيفية أو مكان تخزينها. فحتى درج الملفات المُتضمّنة لمعلومات الرواتب يُعدّ قاعدة بيانات، كذلك الأمر بالنسبة لأي مجموعة مُكدّسة من البيانات مثل نماذج المرضى في مستشفى، أو معلومات مجموعة من عملاء شركة موزعة عبر عدّة مواقع. فقبل أن تغدو عملية تخزين وإدارة البيانات باستخدام الحواسيب شائعة، كانت قواعد البيانات المادية كهذه في الأمثلة السابقة هي الوحيدة المتاحة للحكومات والمنظمات التجارية التي كانت بحاجة لتخزين المعلومات.
</p>

<p>
	وفي منتصف القرن العشرين تقريبًا، شهدت <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">علوم الحاسوب</a> تطورات كبيرة أفضت إلى ظهور أجهزة ذات قدرة معالجة أعلى وسعات تخزين محلية وخارجية أكبر. جعلت هذه التطورات علماء الحاسوب يُدركون القدرات الهائلة لهذه الأجهزة في تخزين وإدارة كميات أكبر من البيانات.
</p>

<p>
	ولكن لم تكن هناك حينها نظريات مُحدّدة حول كيفية تنظيم البيانات في الحواسيب بطرق منطقية ذات معنى فقد كان من السهل تخزين البيانات عشوائيًا على جهاز ما، لكن تصميم أنظمة قواعد البيانات سيتيح إمكانية إضافة واسترجاع وترتيب وإدارة هذه البيانات بطرق عملية وثابتة هو تحدٍ أكبر. فقد أسفرت الحاجة إلى وجود نظام منطقي لتخزين وتنظيم البيانات إلى ظهور العديد من الاقتراحات حول كيفية استخدام الحواسيب في إدارة البيانات.
</p>

<p>
	ولعلّ أحد النماذج الأولية لقواعد البيانات كان <a href="https://ar.wikipedia.org/wiki/%D9%86%D9%85%D9%88%D8%B0%D8%AC_%D9%82%D8%A7%D8%B9%D8%AF%D8%A9_%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA_%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A%D8%A9" rel="external nofollow">النموذج الهرمي</a>، حيث تنظم البيانات وفق هذا النموذج ضمن هيكلية أو بنية شبيهة بالشجرة بأسلوب مماثل لأنظمة الملفات. ويوضّح المثال التالي الشكل الذي قد يبدو عليه جزء من مخطط قاعدة بيانات هرمية تستخدم لتصنيف الحيوانات:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="141325" href="https://academy.hsoub.com/uploads/monthly_2024_01/01.png.d5bc7c5e8763335c401633009ede174c.png" rel=""><img alt="01" class="ipsImage ipsImage_thumbnailed" data-fileid="141325" data-ratio="57.17" data-unique="f12jex4am" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2024_01/01.thumb.png.035e05031e35915bac94a19637e03213.png"> </a>
</p>

<p>
	لقد طُبِّق النموذج الهرمي على نحوٍ واسع في أنظمة إدارة قواعد البيانات الأولية، لكنه أظهر بالمقابل بعض الصعوبات من حيث المرونة. ففي هذا النموذج يمكن للسجل الواحد امتلاك عدّة أبناء Children، لكن لا يمكنه أن يتبع سوى لأب Parent واحد ضمن الهيكلية الهرمية، الأمر الذي يجعل قواعد البيانات الهرمية قادرة على التعبير فقط عن علاقات من نوع "واحد-إلى-واحد (one-to-one)" و"واحد-إلى-عديد (one-to-many)" ولا يسمح بالتعبير عن العلاقات من نوع "عديد-إلى-عديد (many-to-many)"، وهذا القصور قد يفضي إلى حدوث مشاكل لدى التعامل مع نقاط بيانات تتبع لأكثر من أب.
</p>

<p>
	إلى أن ابتكر عالم الحاسوب إدجار فرانك كود Edgar F. Codd والذي كان يعمل في شركة IBM النموذج العلاقيّ لإدارة قواعد البيانات وذلك في أواخر ستينيات القرن الماضي. إذ سمح نموذج Codd العلاقيّ هذا بربط السجل الواحد بأكثر من جدول، ما سمح بإمكانية التعبير عن العلاقات من نوع "عديد-إلى-عديد" بين نقاط البيانات ممكنة، بالإضافة إلى إمكانية التعبير عن العلاقات من نوع "واحد-إلى-عديد". الأمر الذي أتاح المزيد من المرونة مقارنةً بالنماذج الموجودة حينها لتصميم هياكل قواعد البيانات وأثبت قدرة أنظمة إدارة قواعد البيانات العِلاقيَّة (RDBMSs) على تلبية مجموعة أوسع بكثير من احتياجات الأعمال.
</p>

<p>
	كما اقترح العالم كود Codd لغة لإدارة البيانات العلاقيَّة عُرِفت باسم <a href="https://dl.acm.org/doi/pdf/10.1145/1734714.1734718" rel="external nofollow">ألفا (Alpha)</a>، والتي أثّرت في تطوير لغات قواعد البيانات اللاحقة. فقد أنشأ اثنان من زملائه في IBM وهما دونالد تشامبرلين Donald Chamberlin وريمون بويس Raymond Boyce لغة مستوحاة من لغة ألفا، أطلقا عليها اسم SEQUEL اختصارًا لعبارة Structured English Query Language (لغة الاستعلام الهيكلية بالإنجليزية)، ولكن بسبب وجود علامة تجارية موجودة مسبقًا بنفس الاسم، اختصروا اسم لغتهم إلى <a href="https://wiki.hsoub.com/SQL" rel="external">SQL</a> والتي يُشار إليها على نحوٍ أكثر رسمية باسم لغة الاستعلام الهيكلية Structured Query Language.
</p>

<p>
	كانت قواعد البيانات العلاقيَّة الأولية بطيئة للغاية وغير عملية بسبب قيود العتاد، واحتاجت بعض الوقت حتى تنتشر، ولكن ومع حلول منتصف الثمانينات، طُبّق نموذج Codd العِلاقيّ في العديد من المنتجات التجارية لإدارة قواعد البيانات، سواء من قبل شركة IBM أو منافسيها.
</p>

<p>
	إذ قام هؤلاء المُصنعّون أيضًا باتباع خطى IBM من خلال تطوير وتنفيذ لهجاتهم الخاصة من لغة SQL. وبحلول عام 1987، صادق كل من المعهد الوطني الأمريكي للمعايير American National Standards Institute والمنظمة الدولية للمعايير International Organization for Standardization على معايير لغة SQL ونشروها، ما جعل منها اللغة المعترف بها لإدارة أنظمة قواعد البيانات العلاقيَّة.
</p>

<p>
	ولعلّ انتشار استخدام النموذج العلاقيّ في مجموعة متنوعة من المجالات جعل منه النموذج المعياري لإدارة البيانات. وحتى مع ظهور العديد من <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%A7-%D9%87%D9%8A-%D8%AA%D9%82%D9%86%D9%8A%D8%A9-nosql%D8%9F-r640/" rel="">قواعد البيانات غير العلاقية NoSQL</a> في السنوات الأخيرة، تبقى قواعد البيانات العلاقية هي السائدة لتخزين وتنظيم البيانات.
</p>

<h2 id="-2">
	كيف تنظم قواعد البيانات العلاقية البيانات
</h2>

<p>
	الآن وبعد حصولك على فهمٍ عام لتاريخ النموذج العلاقيّ، لنلقِ نظرة أعمق على كيفية تنظيم البيانات وفق هذا النموذج.
</p>

<p>
	لعلّ أهم عناصر النموذج العلاقيّ هي العلاقات Relations، والتي تُعرف لدى المستخدمين وفي أنظمة إدارة قواعد البيانات العِلاقيَّة المعاصرة بمسمى الجداول Tabels. فالعلاقة هي مجموعة من الصفوف أو السجلات في جدول، ويشترك كل صف بمجموعة من السمات أو الأعمدة (الحقول):
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="141326" href="https://academy.hsoub.com/uploads/monthly_2024_01/02.png.8f25221501dd3070542afbf333620622.png" rel=""><img alt="02" class="ipsImage ipsImage_thumbnailed" data-fileid="141326" data-ratio="66.20" data-unique="y3hl9w9t5" style="width: 500px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2024_01/02.thumb.png.d1cf853826f7f87793b8517a063870fc.png"> </a>
</p>

<p>
	العمود هو أصغر هيكل تنظيمي في قاعدة البيانات العلاقيَّة، وهو يُمثّل الخصائص المختلفة التي تُعرّف السجلات ضمن الجدول. ولذا، تُعرف هذه الخصائص رسميًا باسم السمات. يمكن فهم كل صف على أنّه نسخة فريدة تًمثّل نوع ما من الأشخاص أو الكائنات أو الأحداث أو الروابط المحفوظة في الجدول. وقد تُمثّل هذه النسخ موظفي شركة أو مبيعات شركة تجارية عبر الإنترنت أو نتائج اختبارات مخبرية. على سبيل المثال، في جدول يحتوي على سجلات المدرسين في مدرسة ما، قد تتضمن الصفوف سمات مثل: الاسم <code>name</code> والمقررات الدراسية <code>subjects</code> وتاريخ بدء العمل <code>start_date</code>، وما إلى ذلك.
</p>

<p>
	ولدى إنشاء الأعمدة، يتعيّن عليك تحديد نمط البيانات الخاص بكل عمود، وهو ما يُحدّد القيم التي يمكن استقبالها فيه. وعادةً ما تُقدّم أنظمة إدارة قواعد البيانات العِلاقيَّة أنماطًا فريدة خاصة بها من البيانات والتي قد لا تكون متوافقة مباشرةً مع مثيلاتها في الأنظمة الأخرى. ومن أنماط البيانات شائعة الاستخدام كل من التواريخ، والسلاسل النصية، والأعداد الصحيحة، والقيم المنطقية.
</p>

<p>
	يتضمّن كل جدول في النموذج العِلاقيّ عمودًا واحدًا على الأقل يُستخدم لتمييز كل سجل على نحوٍ فريد، ويُعرف باسم المفتاح الأساسي <strong>Primary Key</strong>. وهو عمود مهم جدًا، إذ لا يحتاج المستخدمون لمعرفة مكان تخزين بياناتهم فيزيائيًا داخل الجهاز. وبدلاً من ذلك، يتولى نظام إدارة قواعد البيانات متابعة وتعقّب كل سجل واسترجاعه حسب الطلب. وبالتالي، لا يوجد ترتيب منطقي مُحدّد للسجلات، ويتمتّع المستخدمون بالحرية في استرجاع بياناتهم بالترتيب الذي يرغبون به أو باستخدام عوامل التصفية التي يختارونها.
</p>

<p>
	فبفرض كان لديك جدولين وتود ربطهما ببعضهما البعض، فإحدى الطرق لإنجاز ذلك هي باستخدام المفتاح الخارجي <strong>Foreign key</strong>، وهو نسخة من المفتاح الأساسي لجدول (يُعرف بالجدول "الأب") تُدرج في عمود داخل جدول آخر (يُعرف بالجدول "الابن").<br>
	يُظهر المثال التالي العلاقة بين جدولين، الأول يُستخدم لتسجيل المعلومات حول الموظفين في شركة، والثاني لتتبع مبيعات الشركة. وفي هذا المثال، يُستخدم المفتاح الأساسي لجدول الموظفين <code>EMPLOYEES</code> كمفتاح أجنبي لجدول المبيعات <code>SALES</code>:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="141330" href="https://academy.hsoub.com/uploads/monthly_2024_01/03.png.2bbdf8f4650bca012712b7d742dedeeb.png" rel=""><img alt="03" class="ipsImage ipsImage_thumbnailed" data-fileid="141330" data-ratio="72.50" data-unique="tsjhcqpc9" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2024_01/03.thumb.png.e8ba093cf398674922769827edb393d2.png"> </a>
</p>

<p>
	فإذا حاولت إضافة سجل إلى الجدول الابن وكانت القيمة المُدخلة في عمود المفتاح الأجنبي غير موجودة في المفتاح الأساسي للجدول الأب، فإن تعليمة الإدراج ستكون غير صالحة، وهذا يساعد في الحفاظ على صحّة مستوى العلاقة بين الجدولين (أو نزاهة العلاقة إن صح التعبير)، وبهذا ستكون السجلات في الجدولين مرتبطة على النحو الصحيح دائمًا.
</p>

<p>
	لقد ساعدت عناصر النموذج العلاقيّ الهيكلية في الحفاظ على تنظيم البيانات أثناء تخزينها، ولكن تخزين البيانات لن يكون مفيدًا إلا إذا كان من الممكن استرجاعها. ولاسترجاع البيانات من RDBMS، يُمكنك إنشاء ما يُسمّى بالاستعلام query وهو عبارة عن طلب منظّم لمجموعة من المعلومات. وتستخدم معظم قواعد البيانات العِلاقيَّة لغة SQL لإدارة البيانات والاستعلام عنها كما أشرنا سابقًا. إذ تتيح <a href="https://academy.hsoub.com/programming/sql/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%8A%D9%83%D9%84%D9%8A%D8%A9-sql-r1368/" rel="">لغة SQL</a> إمكانية تصفية نتائج الاستعلام ومعالجتها باستخدام مجموعة من البنى clauses، والجمل الشرطية predicates التي تقيم كصحيح TRUE أو خاطئ  FALSE أو غير معروف، والتعبيرات expressions، ما يمنحك التحكم الدقيق في البيانات التي ستظهر ضمن نتائج الاستعلام.
</p>

<h2 id="-3">
	مزايا وقيود قواعد البيانات العلاقية
</h2>

<p>
	لنفكّر في بعض مزايا وعيوب قواعد البيانات العلاقيَّة بأخذ هيكلها التنظيمي الأساسي في الحسبان.
</p>

<p>
	إنّ لغة SQL وقواعد البيانات التي تستخدمها في أيامنا هذه تختلف عما قدمه العالم كود Codd في نموذجه العلاقيّ الأول في عدة نواحٍ. فعلى سبيل المثال، يملي نموذج كود Codd بأنّ كل سجل في الجدول يجب أن يكون فريدًا. في حين تسمح العديد من قواعد البيانات العلاقيَّة المعاصرة بوجود سجلات مكررة. وهناك بالمقابل من يرى أن قواعد البيانات التي تستخدم لغة SQL ولا تتبع جميع مواصفات نموذج Codd لا يمكن عدها قواعد بيانات علاقيَّة حقيقية. ولكن وفي الواقع، أي نظام يستخدم SQL ويتبع نموذج Codd إلى حد معين يعدّ عادةً نظامًا لإدارة قواعد بيانات علاقيَّة.
</p>

<p>
	ورغم شهرة قواعد البيانات العِلاقيَّة التي ازدادت بسرعة، إلا أنّ بعض أوجه القصور المتعلقة في النموذج العِلاقيّ بدأت بالظهور مع تزايد قيمة البيانات وتوجه الشركات لتخزين كميات أكبر منها. ومن هذه التحديات والمعوقات، صعوبة توسيع قاعدة البيانات العلاقيَّة أفقيًا. والمقصود بالتوسع الأفقي أو الخارجي عملية إضافة المزيد من الأجهزة إلى نظام حالي لتوزيع الحمولة واستيعاب حركة مرور أكبر وتحقيق معالجة أسرع. وغالبًا ما تُقارن هذه العملية بالتوسع العمودي، الذي يتضمن تحسين مواصفات الخادم الحالي من خلال توسيع ذاكرة الوصول العشوائي <a href="https://academy.hsoub.com/apps/operating-systems/%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D9%88%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-r880/" rel="">RAM</a> أو وحدة المعالجة المركزية <a href="https://academy.hsoub.com/apps/operating-systems/%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-r879/" rel="">CPU</a>.
</p>

<p>
	والسبب وراء صعوبة توسيع قاعدة البيانات العلاقيَّة أفقيًا يعود إلى أنّ النموذج العلاقيّ مصمم لضمان الاتساق أو انسجام البيانات consistency، ما يعني أنّه عند استعلام العملاء ضمن قاعدة البيانات نفسها سيحصلون دائمًا على البيانات نفسها. فإذا قمت بتوسيع قاعدة البيانات العلاقيَّة أفقيًا عبر عدة أجهزة، سيصبح من الصعب ضمان هذا الاتساق، إذ قد يقوم العملاء بكتابة البيانات على عقدة معينة أو (جهاز) دون الباقي، وقد يكون هناك تأخير بين لحظة الكتابة الأولية والوقت الذي تُحدّث فيه العقد الأخرى لتعكس هذه التغييرات، ما يؤدي إلى عدم اتساق بينها.
</p>

<p>
	لقد واجهت أنظمة إدارة قواعد البيانات العلاقيَّة بعض التحديات، من بينها أن النموذج العلاقيّ قد صُمّم خصيصًا للتعامل مع البيانات المهيكلة structured data، أي البيانات التي تتوافق مع نمط بيانات مُحدد مسبقًا أو على الأقل تلك المُنظمّة على نحوٍ مُحدد. لكن مع انتشار الحواسيب الشخصية وظهور الإنترنت في أوائل التسعينات، أصبحت البيانات غير المهيكلة unstructured data، كالرسائل الإلكترونية والصور والفيديوهات أكثر شيوعًا.
</p>

<p>
	لا يعني كل ذلك أن قواعد البيانات العلاقيَّة باتت غير مفيدة. بل على العكس تمامًا، فالنموذج العلاقيّ ما زال هو الإطار السائد لإدارة البيانات منذ أكثر من 40 عامًا. وتدلّ شهرتها واستمراريتها على أنّ قواعد البيانات العلاقيَّة تقنية ناضجة، وهذا بحد ذاته من أبرز مزاياها.
</p>

<p>
	هناك العديد من التطبيقات التي صُممت للعمل مع النموذج العِلاقيّ، بالإضافة إلى وجود العديد من مدراء قواعد البيانات المحترفين الخبراء في مجال قواعد البيانات العلاقيَّة. كما تتوفر مجموعة واسعة من الموارد المطبوعة والإلكترونية متاحة لكل من يرغب في بدء التعامل مع قواعد البيانات العِلاقيَّة.
</p>

<p>
	ومن مميزات قواعد البيانات العلاقيَّة دعم معظمها لمجموعة من التعاملات transactions التي تضمن سلامة البيانات وتكاملها. والمعاملة transaction هي مجموعة من أوامر SQL التي تُنفذ وفق تسلسل معيّن كوحدة عمل مُنفصلة. إذ تعتمد المعاملات على مبدأ الكل أو لا شيء، بمعنى أنّ كل أمر في المعاملة يجب أن يكون صحيحًا، وإلا ستُلغى المعاملة بالكامل وبهذا نضمن صحّة البيانات ودقتها (نزاهة البيانات) عند التعديل على عدة سجلات أو جداول في الوقت نفسه.
</p>

<p>
	وأخيرًا، تعدّ قواعد البيانات العلاقيَّة مرنة للغاية. فقد استُخدمت في تطوير مجموعة واسعة من التطبيقات المختلفة، وتستمر في العمل بكفاءة حتى مع كميات ضخمة من البيانات. كما تعدّ لغة SQL قوية جدًا، إذ تتيح لك إمكانية إضافة وتعديل البيانات على نحوٍ فوري، بالإضافة إلى تغيير هيكلية تخطيط قواعد البيانات والجداول دون التأثير على البيانات الموجودة.
</p>

<h2 id="-4">
	الخلاصة
</h2>

<p>
	تعرفنا في مقال اليوم على قواعد البيانات العلاقيَّة التي لا تزال وسيلة أساسية لإدارة وتخزين البيانات بعد أكثر من خمسين عامًا على وضع التصور الأولي لها، وذلك بفضل مرونتها وتصميمها الذي يضمن صحة البيانات ودقتها. وحتى مع ظهور قواعد البيانات غير العِلاقيَّة NoSQL في السنوات الأخيرة، لا زال فهم النموذج العلاقيّ ومعرفة كيفية التعامل مع أنظمة إدارة قواعد البيانات العلاقيَّة أمر أساسي لأي شخص يرغب في بناء التطبيقات المُعتمدة على قوة البيانات.
</p>

<p>
	وللتعرّف على المزيد حول بعض من أنظمة إدارة قواعد البيانات العِلاقيَّة الأشهر، وقواعد البيانات عمومًا، ننصحكم بالرجوع إلى <a href="https://academy.hsoub.com/devops/servers/databases/" rel="">قسم قواعد البيانات</a> من أكاديمية حسوب.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/understanding-relational-databases" rel="external nofollow">Understanding Relational Databases</a> لصاحبه Mark Drake.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">مدخل إلى تصميم قواعد البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%83%D9%88%D9%86%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">تعرف على مكونات قاعدة البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%A7%D9%84%D9%83%D9%8A%D8%A7%D9%86-%D9%88%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A9-er-%D9%84%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%88%D8%AA%D8%AE%D8%B2%D9%8A%D9%86%D9%87%D8%A7-%D9%81%D9%8A-%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r543/" rel="">نموذج الكيان والعلاقة ER لتمثيل البيانات وتخزينها في قاعدة البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D8%AD%D8%B1%D9%83%D8%A7%D8%AA-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">ما هي محركات قواعد البيانات؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">أنواع قواعد البيانات وأهم مميزاتها واستخداماتها</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2216</guid><pubDate>Fri, 05 Jan 2024 09:06:01 +0000</pubDate></item><item><title>&#x627;&#x644;&#x641;&#x631;&#x642; &#x628;&#x64A;&#x646; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; SQL &#x648; NoSQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-sql-%D9%88-nosql-r2055/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_08/--sql--nosql.png.bd1519dbd2e9bb3bf68453b0e2d8fdad.png" /></p>
<p>
	لكي تستطيع استخدام قاعدة البيانات الأنسب لمشروعك، عليك أن تعرف ما هو الفرق بين قواعد بيانات العلائقية SQL، وقواعد بيانات NoSQL. ولهذا، سنستكشف معًا في هذا الفيديو الفروقات بينهما، وسنتحدث عن كيفية اختيار التقنية الأنسب لمشروعك.
</p>

<p>
	<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="603" id="ips_uid_8045_5" src="https://academy.hsoub.com/applications/core/interface/index.html" title="قواعد بيانات SQL و NoSQL" width="1072" data-embed-src="https://www.youtube.com/embed/1Sb2wC7S5Rw"></iframe>
</p>

<p>
	إذا أردت التعرف أكثر على قواعد البيانات، فننصحك بالانضمام إلى <a href="https://academy.hsoub.com/learn/computer-science/" rel="">دورة علوم الحاسوب</a>، ولا تنسَ الاستعانة خلال رحلة تعلمك وعملك بتوثيقات <a href="https://wiki.hsoub.com/%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9_%D8%A7%D9%84%D8%B1%D8%A6%D9%8A%D8%B3%D9%8A%D8%A9" rel="external">موسوعة حسوب</a> المجانية. وإذا أردت متابعة المعلومات البرمجية العلمية مكتوبة فيمكنك الاطلاع على <a href="https://academy.hsoub.com/programming/" rel="">قسم البرمجة في أكاديمية حسوب</a>، كما يمكنك متابعة جديد الفيديوهات التقنية المتاحة على <a href="https://www.youtube.com/@HsoubAcademy" rel="external nofollow">يوتيوب أكاديمية حسوب</a> مجانًا.
</p>
]]></description><guid isPermaLink="false">2055</guid><pubDate>Sun, 26 Mar 2023 15:00:00 +0000</pubDate></item><item><title>&#x645;&#x627; &#x647;&#x64A; &#x62A;&#x642;&#x646;&#x64A;&#x629; SQL&#x61F;</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D8%A7-%D9%87%D9%8A-%D8%AA%D9%82%D9%86%D9%8A%D8%A9-sql%D8%9F-r1651/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_08/62f01afb6885e_sql.png.cf1228f6a319148f16e8c361ac90ba09.png" /></p>

<p>
	سنشرح في هذا الفيديو <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/" rel="">SQL</a> أو مايعرف بـ Structured Query Language أي لغة الاستعلام الهيكلية، حيث سنشرح لماذا نستخدم SQL ومالفائدة منها، مع تبيان أهم الخصائص التي تتميز بها لغة SQL وكيفية عملها.
</p>

<p style="text-align: center;">
	<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="480" title="ما هي تقنية SQL" width="853" src="https://www.youtube.com/embed/Idq1QrXEfQk"></iframe>
</p>

<p>
	يمكنك تعلم المزيد حول هذه اللغة عبر المقالات المتاحة على الأكاديمية <a href="https://academy.hsoub.com/programming/sql/" rel="">بقسم SQL</a>، كما يمكنك الاستفادة من المزيد من المعلومات المتاحة على <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">كتاب ملاحظات للعاملين بلغة SQL</a>. يمكنك أيضًا البدء بتعلم لغة SQL وأنظمة إدارة قواعد البيانات باحترافية أكبر في <a href="https://academy.hsoub.com/learn/computer-science/" rel="">دورة علوم الحاسوب المقدمة من أكاديمية حسوب</a>، ولا تنسى تدعيم معلوماتك عبر <a href="https://wiki.hsoub.com/SQL" rel="external">توثيق اللغة المتاح على موسوعة حسوب</a>.
</p>
]]></description><guid isPermaLink="false">1651</guid><pubDate>Thu, 21 Jul 2022 15:00:00 +0000</pubDate></item><item><title>&#x644;&#x63A;&#x629; &#x645;&#x639;&#x627;&#x644;&#x62C;&#x629; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; DML &#x627;&#x644;&#x62E;&#x627;&#x635;&#x629; &#x628;&#x644;&#x63A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%84%D8%BA%D8%A9-%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-dml-%D8%A7%D9%84%D8%AE%D8%A7%D8%B5%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-sql-r1369/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2021_11/618a1f3a6eace_-----SQL.png.4be1a0360d59e2906191d46f61143632.png" /></p>

<p>
	تُستخدَم لغة <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">معالجة البيانات</a> Data Manipulation Language -أو DML اختصارًا- الخاصة ب<a href="https://wiki.hsoub.com/SQL" rel="external">لغة SQL</a> للاستعلام عن البيانات في قاعدة البيانات وتعديلها، وسنشرح في هذا المقال كيفية استخدام تعليمات أوامر لغة SQL DML والتي هي <code>SELECT</code> و<code>INSERT</code> و<code>UPDATE</code>، و<code>DELETE</code> المُعرَّفة كما يلي:
</p>

<ul>
<li>
		<code><a href="https://wiki.hsoub.com/SQL/select" rel="external">SELECT</a></code>: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r588/" rel="">للاستعلام عن بيانات</a> في <a href="https://academy.hsoub.com/files/18-%D8%A7%D9%84%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A-%D8%A5%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-postgresql/" rel="">قاعدة البيانات</a>.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/insert" rel="external">INSERT</a></code>: لإدخال بيانات في جدول.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/update" rel="external">UPDATE</a></code>: لتحديث بيانات في جدول.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/delete" rel="external">DELETE</a></code>: لحذف بيانات من جدول.
	</li>
</ul>
<p>
	في تعليمة SQL DML:
</p>

<ul>
<li>
		يجب بدأ كل شرط في عبارة بسطر جديد.
	</li>
	<li>
		يجب انتظام بداية كل شرط مع بداية الشروط الأخرى.
	</li>
	<li>
		إذا تألّف شرط من عدة أجزاء، فيجب توضُّع هذه الأجزاء على سطور منفصلة، كما يجب إضافة مسافة بادئة لها تحت بداية الشرط لإظهار العلاقة.
	</li>
	<li>
		تُستخدَم الأحرف الكبيرة لتمثيل الكلمات المحجوزة.
	</li>
	<li>
		تُستخدَم الحروف الصغيرة لتمثيل الكلمات التي يُعرِّفها المستخدِم.
	</li>
</ul>
<h2>
	تعليمة SELECT
</h2>

<p>
	تسمح <a href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">التعليمة أو الأمر SELECT</a> للمستخدِم باستخراج البيانات من الجداول، بناءً على معايير محدَّدة، حيث تُعالَج وفقًا للتسلسل التالي:
</p>

<ul>
<li>
		<code><a href="https://wiki.hsoub.com/SQL/distinct" rel="external">SELECT DISTINCT</a></code> اختيار عنصر أو مجموعة عناصر.
	</li>
	<li>
		<code>FROM</code> من جدول أو مجموعة جداول.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/where" rel="external">WHERE</a></code> يليها تعبير شرطي.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/group_by" rel="external">GROUP BY</a></code> يليها حقل أو مجموعة حقول.
	</li>
	<li>
		<code><a href="https://wiki.hsoub.com/SQL/order_by" rel="external">ORDER BY</a></code> يليها مجموعة حقول.
	</li>
</ul>
<p>
	يمكننا استخدام تعليمة <code>SELECT</code> لإنشاء <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/" rel="">قائمة بهواتف الموظفين من جدول الموظفين</a> Employees كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_10" style="">
<span class="pln">SELECT  </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pun">,</span><span class="pln"> phone
FROM </span><span class="typ">Employees</span><span class="pln">
ORDER BY </span><span class="typ">LastName</span></pre>

<p>
	سيعرض هذا الإجراء اسم عائلة last name الموظف، واسمه الأول first name، ورقم هاتفه phone number من جدول الموظفين Employees كما في الجدول التالي:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
} 

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Last Name
			</th>
			<th>
				First Name
			</th>
			<th>
				Phone Number
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Hagans
			</td>
			<td>
				Jim
			</td>
			<td>
				604-232-3232
			</td>
		</tr>
<tr>
<td>
				Wong
			</td>
			<td>
				Bruce
			</td>
			<td>
				604-244-2322
			</td>
		</tr>
</tbody>
</table>
<p>
	سنستخدم في المثال التالي جدول الناشرين Publishers table الذي يمثِّله الجدول الآتي، حيث ستلاحظ أنّ كندا Canada مكتوبة بطريقة خاطئة في حقل بلد الناشر Publisher Country المقابل لحقل اسم الناشر Example Publishing، ومدينة الناشر ABC Publishing.
</p>

<p>
	استخدم تعليمة <code>UPDATE</code> لتصحيح الأخطاء وتوحيد حقل البلد ليصبح Canada، -كما سنتكلم لاحقًا عن تعليمة <code>UPDATE</code> في هذا المقال.
</p>

<table>
<thead><tr>
<th>
				Publisher Name
			</th>
			<th>
				Publisher City
			</th>
			<th>
				Publisher Province
			</th>
			<th>
				Publisher Country
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Acme Publishing
			</td>
			<td>
				Vancouver
			</td>
			<td>
				BC
			</td>
			<td>
				Canada
			</td>
		</tr>
<tr>
<td>
				Example Publishing
			</td>
			<td>
				Edmonton
			</td>
			<td>
				AB
			</td>
			<td>
				Cnada
			</td>
		</tr>
<tr>
<td>
				ABC Publishing
			</td>
			<td>
				Toronto
			</td>
			<td>
				ON
			</td>
			<td>
				Canda
			</td>
		</tr>
</tbody>
</table>
<p>
	إذا أضفتَ اسم الناشر Publisher Name، ومدينة الناشر Publisher City، فستستخدِم تعليمة <code>SELECT</code>، ويتبعها اسم الحقول التي يُفصَل بينها بفاصلة أجنبية comma، أي كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_12" style="">
<span class="pln">SELECT </span><span class="typ">PubName</span><span class="pun">,</span><span class="pln"> city
FROM </span><span class="typ">Publishers</span></pre>

<p>
	سيؤدي هذا الإجراء إلى عرض اسم الناشر ومدينته من جدول الناشرين.
</p>

<p>
	إذا أردت عرض حقل اسم الناشر باسم حقل المدينة -أي تبديل اسم الحقل PubName ليصبح city-، فاستخدِم تعليمة <code>SELECT</code> مع عدم وضع فاصلة أجنبية بين Pub_Name وcity، أي كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_14" style="">
<span class="pln">SELECT </span><span class="typ">PubName</span><span class="pln"> city
FROM </span><span class="typ">Publishers</span></pre>

<p>
	سيعرض تنفيذ هذا الإجراء فقط الحقل PUB_NAME من جدول الناشرين، بحيث يكون له العنوان city.
</p>

<p>
	يفترض SQL Server أنك تريد وضع اسم عمود جديد للحقل PUB_NAME إذا لم تضمّن الفاصلة الأجنبية.
</p>

<h3>
	تعليمة SELECT مع معيار WHERE
</h3>

<p>
	قد ترغب أحيانًا في التركيز على جزء من جدول الناشرين، مثل الناشرين الموجودين في مدينة فانكوفر Vancouver فقط، إذ ستستخدم في هذه الحالة عبارة <code>SELECT</code> مع معيار <code>WHERE</code>، أي كما يلي: <code>'WHERE city = 'Vancouver</code>.
</p>

<p>
	يوضِّح المثالان الأوليّان التاليان كيفية تحديد اختيار سجل مع المعيار <code>WHERE</code> باستخدام <code>BETWEEN</code>، إذ يعطي كل من هذين المثالَين نتائج تخزين العناصر نفسها التي عددها بين 20 و50 عنصر في المخزن.
</p>

<p>
	يستخدم المثال رقم 1 الكمية التي قيمتها بين 20 و50 عنصر مع تضمين العنصرين 20 و50 بالصورة التالية: <code>qty BETWEEN 20 and 50</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_7" style="">
<span class="pln">SELECT </span><span class="typ">StorID</span><span class="pun">,</span><span class="pln"> qty</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TitleID</span><span class="pln">
FROM </span><span class="typ">Sales</span><span class="pln">
WHERE qty BETWEEN </span><span class="lit">20</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="lit">50</span></pre>

<p>
	يستخدِم المثال رقم 2 الشرط <code>qty &gt;=20 and qty &lt;=50</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_18" style="">
<span class="pln">SELECT </span><span class="typ">StorID</span><span class="pun">,</span><span class="pln"> qty</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TitleID</span><span class="pln">
FROM </span><span class="typ">Sales</span><span class="pln">
WHERE qty </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> qty  </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">50</span></pre>

<p>
	يوضِّح المثال رقم 3 كيفية تحديد اختيار سجل مع المعيار <code>WHERE</code> باستخدام <code>NOT BETWEEN</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_20" style="">
<span class="pln">SELECT </span><span class="typ">StorID</span><span class="pun">,</span><span class="pln"> qty</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TitleID</span><span class="pln">
FROM </span><span class="typ">Sales</span><span class="pln">
WHERE qty NOT BETWEEN </span><span class="lit">20</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="lit">50</span></pre>

<p>
	يظهر المثالان التاليان طريقتَين مختلفتَين لتحديد اختيار سجل مع المعيار <code>WHERE</code> باستخدام <code>IN</code> مع النتائج نفسها.
</p>

<p>
	يوضح المثال رقم 4 كيفية اختيار السجلات باستخدام حقل المقاطعة province من جدول Publishers -أي =province- على أساس جزء من تعليمة <code>WHERE</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_9" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Publishers</span><span class="pln">
WHERE province </span><span class="pun">=</span><span class="pln"> </span><span class="str">'BC'</span><span class="pln"> OR province </span><span class="pun">=</span><span class="pln"> </span><span class="str">'AB'</span><span class="pln"> OR province </span><span class="pun">=</span><span class="pln"> </span><span class="str">'ON'</span></pre>

<p>
	يوضِّح المثال رقم 5 كيفية اختيار السجلات باستخدام المقاطعة province مع <code>IN</code> على أساس جزء من تعليمة <code>WHERE</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_24" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Publishers</span><span class="pln">
WHERE province IN </span><span class="pun">(‘</span><span class="pln">BC</span><span class="pun">’,</span><span class="pln"> </span><span class="pun">‘</span><span class="pln">AB</span><span class="pun">’,</span><span class="pln"> </span><span class="pun">‘</span><span class="pln">ON</span><span class="pun">’)</span></pre>

<p>
	يوضِّح المثالان الأخيران كيف يمكن استخدام <code>NULL</code> و<code>NOT NULL</code> لتحديد السجلات، ولكن سنستخدم في هذين المثالين جدول الكتب Books table الغير موضَّح هنا، والذي يحتوي على حقول، وهي: العنوان Title، والكمية Quantity، وسعر الكتاب Price، وكل ناشر لديه جدول كتب يعطي قائمةً بجميع كتب الناشر.
</p>

<p>
	يستخدِم المثال رقم 6 القيمة <code>NULL</code>:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_7466_28" style="">
<span class="pln">SELECT price</span><span class="pun">,</span><span class="pln"> title
FROM </span><span class="typ">Books</span><span class="pln">
WHERE price IS NULL</span></pre>

<p>
	يستخدِم المثال رقم 7 القيمة <code>NOT NULL</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_32" style="">
<span class="pln">SELECT price</span><span class="pun">,</span><span class="pln"> title
FROM </span><span class="typ">Books</span><span class="pln">
WHERE price IS NOT NULL</span></pre>

<h3>
	استخدام محارف البدل wildcards في شرط LIKE
</h3>

<p>
	يحدِّد الشرط <code>LIKE</code> الصفوف التي تحتوي على الحقول التي تطابق أجزاءً محددة من سلاسل محرفية، كما يُستخدَم <code>LIKE</code> مع البيانات التي من النوع char وvarchar وtext وdatetime وsmalldatetime.
</p>

<p>
	يسمح محرف البدل wildcard للمستخدِم بمطابقة الحقول التي تحتوي على محارف معينة، حيث سيعطي محرف البدل <code>'%province = 'N</code> جميع المقاطعات التي تبدأ بالمحرف N.
</p>

<p>
	يوضِّح الجدول التالي أربعة طرق لتحديد محارف البدل في تعليمة <code>SELECT</code> في صيغة التعبير المنتظم:
</p>

<table>
<thead><tr>
<th>
				محرف البدل wildcard
			</th>
			<th>
				نتيجة استخدامه
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				%
			</td>
			<td>
				يمثل أيّ سلسلة تتألف من صفر أو أكثر من المحارف
			</td>
		</tr>
<tr>
<td>
				_
			</td>
			<td>
				يمثل أيّ محرف واحد
			</td>
		</tr>
<tr>
<td>
				[ ]
			</td>
			<td>
				يمثل أيّ محرف واحد ضمن مجال محدد مثل المجال [a-f]، أو مجموعة محدَّدة مثل المجموعة [abcdef]
			</td>
		</tr>
<tr>
<td>
				[^]
			</td>
			<td>
				يمثل أي محرف واحد ليس ضمن مجال محدد مثل المجال [a - f^]، أو مجموعة محدَّدة مثل المجموعة [abcdef^]
			</td>
		</tr>
</tbody>
</table>
<p>
	تبحث التعليمة <code>'%LIKE 'Mc</code> في المثال رقم 1 عن جميع أسماء العائلة last names التي تبدأ بالمحرفين Mc مثل McBadden:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_11" style="">
<span class="pln">SELECT </span><span class="typ">LastName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">LastName</span><span class="pln"> LIKE </span><span class="str">'Mc%'</span></pre>

<p>
	تبحث التعليمة <code>'LIKE '%inger</code> في المثال رقم 2 عن جميع أسماء العائلة التي تنتهي بالمحارف inger، مثل Ringer وStringer:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_13" style="">
<span class="pln">SELECT </span><span class="typ">LastName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">LastName</span><span class="pln"> LIKE </span><span class="str">'%inger'</span></pre>

<p>
	تبحث التعليمة <code>'%LIKE '%en</code> عن جميع أسماء العائلة التي تحتوي على المحرفين en، مثل Bennett وGreen وMcBadden:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_15" style="">
<span class="pln">SELECT </span><span class="typ">LastName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">LastName</span><span class="pln"> LIKE </span><span class="str">'%en%'</span></pre>

<h3>
	تعليمة SELECT مع الشرط ORDER BY
</h3>

<p>
	يُستخدَم الشرط <code>ORDER BY</code> لترتيب السجلات في القائمة الناتجة، ويمكنك استخدام <code>ASC</code> لترتيب النتائج تصاعديًا، و<code>DESC</code> لترتيب النتائج تنازليًا.
</p>

<p>
	يستخدِم المثال التالي <code>ASC</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_42" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
ORDER BY </span><span class="typ">HireDate</span><span class="pln"> ASC</span></pre>

<p>
	يستخدم المثال التالي <code>DESC</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_44" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
ORDER BY type</span><span class="pun">,</span><span class="pln"> price DESC</span></pre>

<h3>
	تعليمة SELECT مع الشرط GROUP BY
</h3>

<p>
	يُستخدَم الشرط <code>GROUP BY</code> لإنشاء خرج هو عبارة عن صف واحد لكل مجموعة، وينتج قيمًا موجِزةً للأعمدة المحدَّدة، كما هو موضَّح أدناه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_46" style="">
<span class="pln">SELECT type
FROM </span><span class="typ">Books</span><span class="pln">
GROUP BY type</span></pre>

<p>
	يستخدم المثال التالي التعليمة السابقة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_18" style="">
<span class="pln">SELECT type AS </span><span class="str">'Type'</span><span class="pun">,</span><span class="pln"> MIN</span><span class="pun">(</span><span class="pln">price</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Minimum Price'</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
WHERE royalty </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln">
GROUP BY type</span></pre>

<p>
	إذا تضمنت تعليمة <code>SELECT</code> معيار <code>WHERE</code> ليكون السعر price قيمةً غير فارغة not null كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_50" style="">
<span class="pln">SELECT type</span><span class="pun">,</span><span class="pln"> price
FROM </span><span class="typ">Books</span><span class="pln">
WHERE price </span><span class="kwd">is</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span></pre>

<p>
	فستكون التعليمة التي تحتوي على شرط <code>GROUP BY</code> كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_20" style="">
<span class="pln">SELECT type AS </span><span class="str">'Type'</span><span class="pun">,</span><span class="pln"> MIN</span><span class="pun">(</span><span class="pln">price</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Minimum Price'</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
WHERE price </span><span class="kwd">is</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
GROUP BY type</span></pre>

<h3>
	استخدام COUNT مع GROUP BY
</h3>

<p>
	يمكننا استخدام <code>COUNT</code> لإحصاء عدد العناصر الموجودة في حاوية container، ولكن إذا أردت حساب عدد عناصر مختلفة في مجموعات منفصلة مثل رخام ذي ألوان مختلفة، فسنستخدِم دالة <code>COUNT</code> مع الأمر <code>GROUP BY</code>.
</p>

<p>
	توضح تعليمة <code>SELECT</code> أدناه كيفية حساب عدد مجموعات من البيانات باستخدام دالة <code>COUNT</code> مع الشرط أو الأمر <code>GROUP BY</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_55" style="">
<span class="pln">SELECT COUNT</span><span class="pun">(*)</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
GROUP BY type</span></pre>

<h3>
	استخدام AVG وSUM مع GROUP BY
</h3>

<p>
	يمكننا استخدام دالة <code>AVG</code> لتعطينا متوسط أي مجموعة، وتُستخدَم الدالة <code>SUM</code> لإعطاء المجموع.
</p>

<p>
	يستخدِم المثال رقم 1 التالي دالة <code>AVG</code> مع الشرط <code>GROUP BY type</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_58" style="">
<span class="pln">SELECT AVG</span><span class="pun">(</span><span class="pln">qty</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
GROUP BY type</span></pre>

<p>
	يستخدِم المثال رقم 2 التالي دالة <code>SUM</code> مع الشرط <code>GROUP BY type</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_60" style="">
<span class="pln">SELECT SUM</span><span class="pun">(</span><span class="pln">qty</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
GROUP BY type</span></pre>

<p>
	يستخدِم المثال رقم 3 كلًا من الدالتين <code>AVG</code>، و<code>SUM</code> مع الشرط <code>GROUP BY type</code> في تعليمة <code>SELECT</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_23" style="">
<span class="pln">SELECT </span><span class="str">'Total Sales'</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> SUM</span><span class="pun">(</span><span class="pln">qty</span><span class="pun">),</span><span class="pln"> </span><span class="str">'Average Sales'</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> AVG</span><span class="pun">(</span><span class="pln">qty</span><span class="pun">),</span><span class="pln"> stor_id
FROM </span><span class="typ">Sales</span><span class="pln">
GROUP BY </span><span class="typ">StorID</span><span class="pln"> ORDER BY  </span><span class="str">'Total Sales'</span></pre>

<h3>
	تقييد الصفوف مع HAVING
</h3>

<p>
	يمكن استخدام الشرط <code><a href="https://wiki.hsoub.com/SQL/having" rel="external">HAVING</a></code> لتقييد الصفوف، فهو يشبه شرط <code>WHERE</code> باستثناء أنه يتضمّن دالة تجميع aggregate function؛ إذ لا يستطيع الشرط <code>WHERE</code> فعل ذلك، أي يتصرّف الشرط <code>HAVING</code> مثل الشرط <code>WHERE</code>، ولكنه قابل للتطبيق على المجموعات.
</p>

<p>
	نستخدم في هذا المثال الشرط <code>HAVING</code> لاستبعاد المجموعات التي مقاطعتها 'BC'.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_25" style="">
<span class="pln">SELECT au_fname AS </span><span class="str">'Author"s First Name'</span><span class="pun">,</span><span class="pln"> province </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Province'</span><span class="pln">
FROM </span><span class="typ">Authors</span><span class="pln">
GROUP BY au_fname</span><span class="pun">,</span><span class="pln"> province
HAVING province </span><span class="pun">&lt;&gt;</span><span class="pln"> </span><span class="str">'BC'</span></pre>

<h2>
	تعليمة INSERT
</h2>

<p>
	تضيف تعليمة <code><a href="https://wiki.hsoub.com/SQL/insert" rel="external">INSERT</a></code> صفوفًا إلى جدول، وأيضًا ما يلي:
</p>

<ul>
<li>
		تحدِّد تعليمة <code>INSERT</code> الجدول أو العرض view التي ستُدخَل البيانات فيه.
	</li>
	<li>
		تعرض Column List قائمةً بالأعمدة التي ستتأثر بتعليمة <code>INSERT</code>.
	</li>
	<li>
		يجب توفير كل قيمة إذا حُذِف عمود.
	</li>
	<li>
		يمكن وضع الأعمدة في قائمة ضمن أي ترتيب إذا ضمّنتها.
	</li>
	<li>
		تحدِّد الكلمة <code>VALUES</code> البيانات التي تريد إدخالها في الجدول، وتكون VALUES إلزامية).
	</li>
</ul>
<p>
	يجب عدم إدراج الأعمدة ذات الخاصية <code>IDENTITY</code> بصورة صريحة في column_list أو value_sclause.
</p>

<p>
	صيغة تعليمة <code>INSERT</code> هي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_68" style="">
<span class="pln">INSERT </span><span class="pun">[</span><span class="pln">INTO</span><span class="pun">]</span><span class="pln"> </span><span class="typ">Table_name</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> view name </span><span class="pun">[</span><span class="pln">column_list</span><span class="pun">]</span><span class="pln">
DEFAULT VALUES </span><span class="pun">|</span><span class="pln"> values_list </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> statement</span></pre>

<p>
	تُطبَّق القواعد التالية عند إدخال صفوف باستخدام تعليمة <code>INSERT</code>:
</p>

<ul>
<li>
		يؤدي إدخال سلسلة فارغة (' ') في عمود من النوع varchar، أو text إلى إدخال مسافة واحدة.
	</li>
	<li>
		تُحشَى جميع الأعمدة ذات النوع char على اليمين right-padded حتى تصل إلى الطول المحدد.
	</li>
	<li>
		تُزال جميع المسافات الزائدة من البيانات المدرجة في أعمدة من النوع varchar، باستثناء السلاسل التي تحتوي على مسافات فقط، إذ تُختصَر هذه السلاسل إلى مسافة واحدة فقط.
	</li>
	<li>
		إذا أخلَّت تعليمة <code>INSERT</code> بالقيد، أو الافتراض، أو القاعدة، أو إذا كان نوع البيانات خاطئًا، فستفشل هذه التعليمة، وسيعرض خادم SQL Server رسالة خطأ.
	</li>
</ul>
<p>
	يمكن حدوث أحد الأشياء الثلاثة التالية للأعمدة التي لا تحتوي على قيم عند تحديد قيم بعض الأعمدة في column_list فقط:
</p>

<ol>
<li>
		تُدخَل قيمة افتراضية إذا كان للعمود قيد <code>DEFAULT</code>، أو إذا كان الافتراض مرتبط بالعمود، أو إذا كان الافتراض مرتبط بنوع البيانات التي يعرِّفها المستخدم.
	</li>
	<li>
		تُدخَل القيمة الفارغة <code>NULL</code> إذا سمح العمود بالقيم الفارغة، ولا توجد قيمة افتراضية موجودة للعمود.
	</li>
	<li>
		تُعرَض رسالة خطأ ويُرفَض الصف إذا عُرَِف العمود بأنه غير فارغ <code>NOT NULL</code>، ولا توجد قيمة افتراضية.
	</li>
</ol>
<p>
	يستخدِم المثال التالي تعليمة <code>INSERT</code> لإضافة سجل إلى جدول الكتّاب Authors:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_28" style="">
<span class="pln">INSERT INTO </span><span class="typ">Authors</span><span class="pln">
VALUES</span><span class="pun">(</span><span class="str">'555-093-467'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Martin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'April'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'281 555-5673'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'816 Market St.,'</span><span class="pln"> </span><span class="pun">,</span><span class="pln"> </span><span class="str">'Vancouver'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'BC'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'V7G3P4'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span></pre>

<p>
	يوضِّح المثال التالي كيفية إدخال صف جزئي partial row في جدول الناشرِين Publishers مع قائمة أعمدة.
</p>

<p>
	يملك عمود الدولة country قيمة افتراضية هي Canada، لذلك لا يلزمك تضمينه في قيمك.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_32" style="">
<span class="pln">INSERT INTO </span><span class="typ">Publishers</span><span class="pln"> </span><span class="pun">(</span><span class="typ">PubID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PubName</span><span class="pun">,</span><span class="pln"> city</span><span class="pun">,</span><span class="pln"> province</span><span class="pun">)</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="str">'9900'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Acme Publishing'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Vancouver'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'BC'</span><span class="pun">)</span></pre>

<p>
	اتبع المثال التالي لإدخال صفوف في جدول مع عمود <code>IDENTITY</code>، ولا تعطي قيمةً للعمود <code>IDENTITY</code>، ولا قيمةً لاسم العمود ضمن قائمة الأعمدة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_34" style="">
<span class="pln">INSERT INTO jobs
VALUES </span><span class="pun">(</span><span class="str">'DBA'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">175</span><span class="pun">)</span></pre>

<h3>
	إدخال قيم محددة ضمن عمود IDENTITY
</h3>

<p>
	لا يمكن إدخال البيانات مباشرة في عمود <code>IDENTITY</code> افتراضيًا، ولكن إذا حُذِف صف خطأً، أو إذا كانت هناك ثغرات في قيم عمود <code>IDENTITY</code>، فيمكنك إدخال صف وتحديد قيمة العمود <code>IDENTITY</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_76" style="">
<span class="pln">IDENTITY_INSERT option</span></pre>

<p>
	يمكن استخدام خيار <code>IDENTITY_INSERT</code> على النحو التالي للسماح بإدخال قيمة هوية identity محدَّدة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_37" style="">
<span class="pln">SET IDENTITY_INSERT jobs ON
INSERT INTO jobs  </span><span class="pun">(</span><span class="pln">job_id</span><span class="pun">,</span><span class="pln"> job_desc</span><span class="pun">,</span><span class="pln"> min_lvl</span><span class="pun">,</span><span class="pln"> max_lvl</span><span class="pun">)</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="lit">19</span><span class="pun">,</span><span class="pln"> </span><span class="str">'DBA2'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">175</span><span class="pun">)</span><span class="pln">
SET IDENTITY_INSERT jobs OFF</span></pre>

<h3>
	إدخال صفوف باستخدام عبارة SELECT
</h3>

<p>
	يمكننا أحيانًا إنشاء جدول مؤقت صغير من جدول كبير، لذلك يمكننا إدخال صفوف مع تعليمة <code>SELECT</code>.
</p>

<p>
	لا يوجد تحقق لصحة التفرد uniqueness عند استخدام هذا الأمر، وبالتالي، قد يكون هناك العديد من الصفوف بالمعرّف pub_id نفسه في المثال التالي.
</p>

<p>
	ينشِئ هذا المثال جدول ناشرِين Publishers مؤقت هو tmpPublishers أصغر باستخدام تعليمة إنشاء جدول <code>CREATE TABLE</code>، ثم تُستخدَم تعليمة <code>INSERT</code> مع تعليمة <code>SELECT</code> لإضافة سجلات إلى جدول الناشرِين المؤقت من جدول الناشرين Publishers.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_40" style="">
<span class="pln">CREATE TABLE dbo</span><span class="pun">.</span><span class="pln">tmpPublishers </span><span class="pun">(</span><span class="pln">
</span><span class="typ">PubID</span><span class="pln"> </span><span class="kwd">char</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">)</span><span class="pln"> NOT NULL </span><span class="pun">,</span><span class="pln">
</span><span class="typ">PubName</span><span class="pln"> varchar </span><span class="pun">(</span><span class="lit">40</span><span class="pun">)</span><span class="pln"> NULL </span><span class="pun">,</span><span class="pln">
city varchar </span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> NULL </span><span class="pun">,</span><span class="pln">
province </span><span class="kwd">char</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> NULL </span><span class="pun">,</span><span class="pln">
country varchar </span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln"> NULL  DEFAULT </span><span class="pun">(</span><span class="str">'Canada'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
INSERT  tmpPublishers
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Publishers</span></pre>

<p>
	ننسخ في هذا المثال مجموعةً فرعيةً من البيانات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_83" style="">
<span class="pln">INSERT tmpPublishers </span><span class="pun">(</span><span class="pln">pub_id</span><span class="pun">,</span><span class="pln"> pub_name</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="typ">PubID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PubName</span><span class="pln">
FROM </span><span class="typ">Publishers</span></pre>

<p>
	تُنسَخ بيانات الناشرين في هذا المثال إلى جدول tmpPublishers ويُضبَط عمود الدولة country إلى القيمة Canada:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_85" style="">
<span class="pln">INSERT tmpPublishers </span><span class="pun">(</span><span class="typ">PubID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PubName</span><span class="pun">,</span><span class="pln"> city</span><span class="pun">,</span><span class="pln"> province</span><span class="pun">,</span><span class="pln"> country</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="typ">PubID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PubName</span><span class="pun">,</span><span class="pln"> city</span><span class="pun">,</span><span class="pln"> province</span><span class="pun">,</span><span class="pln"> </span><span class="pun">‘</span><span class="typ">Canada</span><span class="pun">’</span><span class="pln">
FROM </span><span class="typ">Publishers</span></pre>

<h2>
	تعليمة UPDATE
</h2>

<p>
	تغيّر تعليمة <code>UPDATE</code> البيانات في الصفوف الموجودة إما بإضافة بيانات جديدة أو بتعديل البيانات الموجودة.
</p>

<p>
	يستخدِم المثال التالي تعليمة <code>UPDATE</code> لتوحيد حقل الدولة country ليكون Canada لجميع السجلات في جدول Publishers:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_42" style="">
<span class="pln">UPDATE </span><span class="typ">Publishers</span><span class="pln">
SET country </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Canada'</span></pre>

<p>
	يزيد المثال التالي مبالغ حقوق المؤلف royalty التي قيمتها بين 10 و20 بنسبة 10%:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_89" style="">
<span class="pln">UPDATE roysched
SET royalty </span><span class="pun">=</span><span class="pln"> royalty </span><span class="pun">+</span><span class="pln"> </span><span class="pun">(</span><span class="pln">royalty </span><span class="pun">*</span><span class="pln"> </span><span class="pun">.</span><span class="lit">10</span><span class="pun">)</span><span class="pln">
WHERE royalty BETWEEN </span><span class="lit">10</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="lit">20</span></pre>

<h3>
	تضمين استعلامات فرعية subqueries ضمن عبارة UPDATE
</h3>

<p>
	يُمنَح الموظفون في جدول الموظفين Employees الذين وظّفهم الناشر في عام 2010 ترقيةً إلى أعلى مستوى وظيفي حسب نوع عملهم كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_91" style="">
<span class="pln">UPDATE </span><span class="typ">Employees</span><span class="pln">
SET job_lvl </span><span class="pun">=</span><span class="pln">
</span><span class="pun">(</span><span class="pln">SELECT max_lvl FROM jobs
WHERE employee</span><span class="pun">.</span><span class="pln">job_id </span><span class="pun">=</span><span class="pln"> jobs</span><span class="pun">.</span><span class="pln">job_id</span><span class="pun">)</span><span class="pln">
WHERE DATEPART</span><span class="pun">(</span><span class="pln">year</span><span class="pun">,</span><span class="pln"> employee</span><span class="pun">.</span><span class="pln">hire_date</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2010</span></pre>

<h2>
	تعليمة DELETE
</h2>

<p>
	تزيل تعليمة <code>DELETE</code> صفوفًا من مجموعة سجلات، كما تحدِّد عبارة <code>DELETE</code> الجدول أو العرض view الذي يحوي الصفوف التي ستُحذَف، ويمكن إدراج جدول أو صف واحد فقط في الوقت نفسه.
</p>

<p>
	يُعَدّ الشرط <code>WHERE</code> المعيار الذي يحدِّد السجلات المراد حذفها، وتكون صيغة تعليمة <code>DELETE</code> كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_93" style="">
<span class="pln">DELETE </span><span class="pun">[</span><span class="pln">FROM</span><span class="pun">]</span><span class="pln"> </span><span class="pun">{</span><span class="pln">table_name </span><span class="pun">|</span><span class="pln"> view_name </span><span class="pun">}</span><span class="pln">
</span><span class="pun">[</span><span class="pln">WHERE clause</span><span class="pun">]</span></pre>

<p>
	قواعد تعليمة <code>DELETE</code> هي:
</p>

<ol>
<li>
		إذا حُذِف شرط <code>WHERE</code> فستُزال جميع الصفوف الموجودة في الجدول باستثناء الفهارس indexes، والجدول، والقيود.
	</li>
	<li>
		لا يمكن استخدام عبارة <code>DELETE</code> بعرض view يحتوي على شرط <code>FROM</code> يسمّي أكثر من جدول واحد، فتعليمة <code>DELETE</code> يمكن أن تؤثر على جدول أساسي فقط في الوقت نفسه.
	</li>
</ol>
<p>
	فيما يلي ثلاث تعليمات <code>DELETE</code> مختلفة يمكن استخدامها:
</p>

<ol>
<li>
		حذف جميع الصفوف من جدول:
	</li>
</ol>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_95" style="">
<span class="pln">DELETE
FROM </span><span class="typ">Discounts</span></pre>

<ol start="2">
<li>
		حذف صفوف محدَّدة:
	</li>
</ol>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_44" style="">
<span class="pln">DELETE
FROM </span><span class="typ">Sales</span><span class="pln">
WHERE stor_id </span><span class="pun">=</span><span class="pln"> </span><span class="str">'6380'</span></pre>

<ol start="3">
<li>
		حذف صفوف بناءً على قيمة ضمن استعلام فرعي:
	</li>
</ol>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_47" style="">
<span class="pln">DELETE FROM </span><span class="typ">Sales</span><span class="pln">
WHERE title_id IN
</span><span class="pun">(</span><span class="pln">SELECT title_id FROM </span><span class="typ">Books</span><span class="pln"> WHERE type </span><span class="pun">=</span><span class="pln"> </span><span class="str">'mod_cook'</span><span class="pun">)</span></pre>

<h2>
	الدوال المبنية مسبقا Built-in Functions
</h2>

<p>
	يوجد العديد من الدوال المبنية مسبقًا في SQL Server، مثل:
</p>

<ol>
<li>
		دوال التجميع Aggregate: ترجع قيمًا موجِزة summary values.
	</li>
	<li>
		دوال التحويل Conversion: تحوِّل نوع بيانات معين إلى نوع آخر.
	</li>
	<li>
		دوال التاريخ Date: تعرض معلومات عن التواريخ والأوقات.
	</li>
	<li>
		الدوال الرياضية Mathematical: تجري عمليات على البيانات العددية.
	</li>
	<li>
		الدوال المتعلِّقة بالسلاسل String: تجري عمليات على سلاسل المحارف، أو البيانات الثنائية، أو التعابير.
	</li>
	<li>
		الدوال المتعلِّقة بالنظام System: ترجع معلومات من قاعدة البيانات.
	</li>
	<li>
		الدوال المتعلِّقة بالنصوص Text، والصور image: تجري عمليات على بيانات نصية، أو على بيانات الصور.
	</li>
</ol>
<p>
	سنشرح أدناه الدوال الأربع الأولى شرحًا مفصَّلًا مع أمثلة عنها.
</p>

<h3>
	دوال التجميع Aggregate functions
</h3>

<p>
	تجري <a href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r855/" rel="">دوال التجميع</a> حسابات على مجموعة من القيم، وترجع قيمةً واحدةً أو قيمةً موجِزةً.
</p>

<p>
	يعرض الجدول التالي هذه الدوال:
</p>

<table>
<thead><tr>
<th>
				الدالة FUNCTION
			</th>
			<th>
				وصفها
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				AVG
			</td>
			<td>
				ترجع متوسط average جميع القيم، أو القيم المميزة DISTINCT فقط، ضمن التعبير
			</td>
		</tr>
<tr>
<td>
				COUNT
			</td>
			<td>
				ترجع عدد القيم غير الفارغة في التعبير، وإذا استخدِم التمايز DISTINCT فستجد الدالة COUNT عدد القيم غير الفارغة الفريدة
			</td>
		</tr>
<tr>
<td>
				(*)COUNT
			</td>
			<td>
				ترجع عدد الصفوف، ولا تأخذ الدالة (*)COUNT معاملات، كما لا يمكن استخدام التمايز DISTINCT معها
			</td>
		</tr>
<tr>
<td>
				MAX
			</td>
			<td>
				ترجع القيمة العليا في التعبير، ويمكن استخدام الدالة Max مع الأعمدة ذات النوع العددي، والمحرفي، والأعمدة ذات النوع datetime، ولكنها لا تُستخدَم مع الأعمدة ذات النوع bit، كما تعطي الدالة MAX مع الأعمدة المحرفية أعلى قيمة في تسلسل مرتَّب، وتتجاهل هذه الدالة القيم الفارغة
			</td>
		</tr>
<tr>
<td>
				MIN
			</td>
			<td>
				ترجع القيمة الدنيا في التعبير. يمكن استخدام الدالة MIN مع أعمدة عددية، ومحرفية، وذات النوع datetime، ولكنها لا تُستخدَم مع أعمدة لها النوع bit، كما تعطي الدالة MIN مع الأعمدة المحرفية أعلى قيمة في تسلسل مرتَّب، وتتجاهل هذه الدالة القيم الفارغة
			</td>
		</tr>
<tr>
<td>
				SUM
			</td>
			<td>
				ترجع مجموع كل القيم، أو فقط القيم المميزة DISTINCT في التعبير، ويمكن استخدام الدالة SUM مع الأعمدة العددية فقط
			</td>
		</tr>
</tbody>
</table>
<p>
	سنعرض فيما يلي أمثلةً عن كل من دوال التجميع الموجودة في الجدول السابق.
</p>

<ul>
<li>
		المثال الأول: الدالة <code>AVG</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_49" style="">
<span class="pln">SELECT AVG </span><span class="pun">(</span><span class="pln">price</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Average Title Price'</span><span class="pln">
FROM </span><span class="typ">Books</span></pre>

<ul>
<li>
		المثال الثاني: الدالة <code>COUNT</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_56" style="">
<span class="pln">SELECT COUNT</span><span class="pun">(</span><span class="typ">PubID</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Number of Publishers'</span><span class="pln">
FROM </span><span class="typ">Publishers</span></pre>

<ul>
<li>
		المثال الثالث: الدالة <code>COUNT</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_62" style="">
<span class="pln">SELECT COUNT</span><span class="pun">(</span><span class="pln">province</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Number of Publishers'</span><span class="pln">
FROM </span><span class="typ">Publishers</span></pre>

<ul>
<li>
		المثال الرابع: الدالة <code>(*) COUNT</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_108" style="">
<span class="pln">SELECT COUNT</span><span class="pun">(*)</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE job_lvl </span><span class="pun">=</span><span class="pln"> </span><span class="lit">35</span></pre>

<ul>
<li>
		المثال الخامس: الدالة <code>MAX</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_110" style="">
<span class="pln">SELECT MAX </span><span class="pun">(</span><span class="typ">HireDate</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<ul>
<li>
		المثال السادس: الدالة <code>MIN</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_114" style="">
<span class="pln">SELECT MIN </span><span class="pun">(</span><span class="pln">price</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Books</span></pre>

<ul>
<li>
		المثال السابع: الدالة <code>SUM</code>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_64" style="">
<span class="pln">SELECT SUM</span><span class="pun">(</span><span class="pln">discount</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Total Discounts'</span><span class="pln">
FROM </span><span class="typ">Discounts</span></pre>

<h3>
	دالة التحويل Conversion function
</h3>

<p>
	تحوّل دالة التحويل نوع بيانات معين إلى نوع بيانات آخر.
</p>

<p>
	يُحوَّل السعر price الذي يحتوي ضمنه على تسعتين 99 إلى خمسة محارف في المثال الآتي، حيث تكون صيغة التعليمة بالصورة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1481_9" style="">
<span class="pln">SELECT </span><span class="str">'The date is '</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> CONVERT</span><span class="pun">(</span><span class="pln">varchar</span><span class="pun">(</span><span class="lit">12</span><span class="pun">),</span><span class="pln"> getdate</span><span class="pun">())</span></pre>

<p>
	إليك مثال:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_66" style="">
<span class="pln">SELECT CONVERT</span><span class="pun">(</span><span class="kwd">int</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10.6496</span><span class="pun">)</span><span class="pln">
SELECT title_id</span><span class="pun">,</span><span class="pln"> price
FROM </span><span class="typ">Books</span><span class="pln">
WHERE CONVERT</span><span class="pun">(</span><span class="kwd">char</span><span class="pun">(</span><span class="lit">5</span><span class="pun">),</span><span class="pln"> price</span><span class="pun">)</span><span class="pln"> LIKE </span><span class="str">'%99%'</span></pre>

<p>
	مثال آخر عن تغيِّر دالة التحويل في المثال التالي البيانات إلى نوع بيانات بحجم مختلف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_73" style="">
<span class="pln">SELECT title_id</span><span class="pun">,</span><span class="pln"> CONVERT</span><span class="pun">(</span><span class="kwd">char</span><span class="pun">(</span><span class="lit">4</span><span class="pun">),</span><span class="pln"> ytd_sales</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Sales'</span><span class="pln">
FROM </span><span class="typ">Books</span><span class="pln">
WHERE type LIKE </span><span class="str">'%cook'</span></pre>

<h3>
	دالة التاريخ Date function
</h3>

<p>
	تُنتج دالة التاريخ تاريخًا عن طريق إضافة فاصل زمني إلى تاريخ محدَّد، والنتيجة هي قيمة لها نوع datetime، وتساوي التاريخ مضافًا إليه عدد أجزاء التاريخ date parts.
</p>

<p>
	إذا كان معامل دالة التاريخ قيمةً من النوع smalldatetime، فستكون النتيجة قيمةً من النوع smalldatetime أيضًا.
</p>

<p>
	تُستخدَم الدالة <code>DATEADD</code> لإضافة وزيادة قيم التاريخ، وصيغة هذه الدالة هي: <code>(DATEADD(datepart, number, date</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_121" style="">
<span class="pln">SELECT DATEADD</span><span class="pun">(</span><span class="pln">day</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> hire_date</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<p>
	يستخدِم المثال الآتي الدالة <code>(DATEDIFF(datepart, date1, date2</code>، ويعيد هذا الأمر عدد أجزاء التاريخ أو الحدود boundaries المتقاطعة بين تاريخَين محددين.
</p>

<p>
	تجعل طريقة حساب الحدود المتقاطعة النتيجة التي أعطتها الدالة <code>DATEDIFF</code> متوافقة مع جميع أنواع البيانات، مثل الدقائق، والثواني، والميلي ثانية.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_75" style="">
<span class="pln">SELECT DATEDIFF</span><span class="pun">(</span><span class="pln">day</span><span class="pun">,</span><span class="pln"> </span><span class="typ">HireDate</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Nov 30 1995'</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<p>
	يمكننا فحص أي جزء من تاريخ معيَّن من السنة إلى الميلي ثانية.
</p>

<p>
	يعرض الجدول التالي أجزاء التاريخ <code>DATEPART</code>، واختصاراتها، وقيمها المقبولة التي يعترف بها خادم SQL Server.
</p>

<table>
<thead><tr>
<th>
				جزء التاريخ DATE PART
			</th>
			<th>
				اختصاره ABBREVIATION
			</th>
			<th>
				قيمه VALUES
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Year
			</td>
			<td>
				yy
			</td>
			<td>
				1753-9999
			</td>
		</tr>
<tr>
<td>
				Quarter
			</td>
			<td>
				qq
			</td>
			<td>
				1-4
			</td>
		</tr>
<tr>
<td>
				Month
			</td>
			<td>
				mm
			</td>
			<td>
				1-12
			</td>
		</tr>
<tr>
<td>
				Day of year
			</td>
			<td>
				dy
			</td>
			<td>
				1-366
			</td>
		</tr>
<tr>
<td>
				Day
			</td>
			<td>
				dd
			</td>
			<td>
				1-31
			</td>
		</tr>
<tr>
<td>
				Week
			</td>
			<td>
				wk
			</td>
			<td>
				1-53
			</td>
		</tr>
<tr>
<td>
				Weekday
			</td>
			<td>
				dw
			</td>
			<td>
				1-7‎ (Sun.-Sat.)
			</td>
		</tr>
<tr>
<td>
				Hour
			</td>
			<td>
				hh
			</td>
			<td>
				0-23
			</td>
		</tr>
<tr>
<td>
				Minute
			</td>
			<td>
				mi
			</td>
			<td>
				0-59
			</td>
		</tr>
<tr>
<td>
				Second
			</td>
			<td>
				ss
			</td>
			<td>
				0-59
			</td>
		</tr>
<tr>
<td>
				Millisecond
			</td>
			<td>
				ms
			</td>
			<td>
				0-999
			</td>
		</tr>
</tbody>
</table>
<h3>
	الدوال الرياضية Mathematical functions
</h3>

<p>
	تجري الدوال الرياضية عمليات على البيانات العددية، ويعرض المثال التالي السعر الحالي لكل كتاب يبيعه الناشر، كما يعرض ما سيكون عليه الأمر إذا ارتفعت جميع الأسعار بنسبة 10%:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_77" style="">
<span class="pln">SELECT </span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="pun">(</span><span class="pln">price </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.1</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'New Price'</span><span class="pun">,</span><span class="pln"> title
FROM </span><span class="typ">Books</span><span class="pln">
SELECT </span><span class="str">'Square Root'</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> SQRT</span><span class="pun">(</span><span class="lit">81</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="str">'Rounded'</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> ROUND</span><span class="pun">(</span><span class="lit">4567.9876</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
SELECT FLOOR </span><span class="pun">(</span><span class="lit">123.45</span><span class="pun">)</span></pre>

<h2>
	ربط الجداول Joining Tables
</h2>

<p>
	يُعَدّ <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">ربط جدولين</a> أو أكثر مثل عملية موازنة بيانات ضمن أعمدة محدَّدة، واستخدام نتائج الموازنة لتشكيل جدول جديد من الصفوف المؤهلة لذلك.
</p>

<p>
	تقوم عبارة <a href="https://wiki.hsoub.com/SQL/join" rel="external">الربط join</a> بما يلي:
</p>

<ul>
<li>
		تحدِّد عمودًا من كل جدول.
	</li>
	<li>
		توازن القيم الموجودة في تلك الأعمدة صفًا صفًا.
	</li>
	<li>
		تدمج الصفوف ذات القيم المؤهلة ضمن صف جديد.
	</li>
</ul>
<p>
	تكون الموازنة عادةً مساواةً -أي القيم التي تتطابق مع بعضها البعض تمامًا-، ولكن يمكن تحديد أنواع ربط أخرى أيضًا.
</p>

<p>
	سنشرح جميع أنواع الربط المختلفة أدناه، مثل: <a href="https://wiki.hsoub.com/SQL/inner_join" rel="external">الربط الداخلي</a> inner، و<a href="https://wiki.hsoub.com/SQL/left_join" rel="external">اليساري</a> (الخارجي)، و<a href="https://wiki.hsoub.com/SQL/right_join" rel="external">اليميني</a> (الخارجي)، و<a href="https://wiki.hsoub.com/SQL/full_join" rel="external">الربط المتقاطع</a> cross join (التام).
</p>

<h3>
	الربط الداخلي Inner join
</h3>

<p>
	يربط جدولين في عمود له نفس نوع البيانات، وينتج الصفوف التي تتطابق فيها قيم العمود فقط، حيث يجري تجاهل الصفوف التي لا مثيل لها.
</p>

<ul>
<li>
		المثال الأول:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_7466_129" style="">
<span class="pln">SELECT jobs</span><span class="pun">.</span><span class="pln">job_id</span><span class="pun">,</span><span class="pln"> job_desc
FROM jobs
INNER JOIN </span><span class="typ">Employees</span><span class="pln"> ON emp
loyee</span><span class="pun">.</span><span class="pln">job_id </span><span class="pun">=</span><span class="pln"> jobs</span><span class="pun">.</span><span class="pln">job_id
WHERE jobs</span><span class="pun">.</span><span class="pln">job_id </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">7</span></pre>

<ul>
<li>
		المثال الثاني:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_131" style="">
<span class="pln">SELECT authors</span><span class="pun">.</span><span class="pln">au_fname</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_lname</span><span class="pun">,</span><span class="pln"> books</span><span class="pun">.</span><span class="pln">royalty</span><span class="pun">,</span><span class="pln"> title
FROM authorsINNER JOIN titleauthor ON authors</span><span class="pun">.</span><span class="pln">au_id</span><span class="pun">=</span><span class="pln">titleauthor</span><span class="pun">.</span><span class="pln">au_id
INNER JOIN books ON titleauthor</span><span class="pun">.</span><span class="pln">title_id</span><span class="pun">=</span><span class="pln">books</span><span class="pun">.</span><span class="pln">title_id
GROUP BY authors</span><span class="pun">.</span><span class="pln">au_lname</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_fname</span><span class="pun">,</span><span class="pln"> title</span><span class="pun">,</span><span class="pln"> title</span><span class="pun">.</span><span class="pln">royalty
ORDER BY authors</span><span class="pun">.</span><span class="pln">au_lname</span></pre>

<h3>
	الربط اليساري الخارجي Left outer join
</h3>

<p>
	ينتج عن الربط الخارجي اليساري كل الصفوف الخارجية اليسرى، إذ تُضمَّن جميع الصفوف من الجدول الأيسر التي لا تحقّق الشرط المحدّد في مجموعة النتائج، وتُضبَط أعمدة الخرج من الجدول الآخر على القيمة الفارغة <code>NULL</code>.
</p>

<p>
	يستخدِم المثال التالي الصيغة الجديدة للربط اليساري الخارجي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_133" style="">
<span class="pln">SELECT publishers</span><span class="pun">.</span><span class="pln">pub_name</span><span class="pun">,</span><span class="pln"> books</span><span class="pun">.</span><span class="pln">title
FROM </span><span class="typ">Publishers</span><span class="pln">
LEFT OUTER JOIN </span><span class="typ">Books</span><span class="pln"> </span><span class="typ">On</span><span class="pln"> publishers</span><span class="pun">.</span><span class="pln">pub_id </span><span class="pun">=</span><span class="pln"> books</span><span class="pun">.</span><span class="pln">pub_id</span></pre>

<p>
	بينما يستخدِم المثال التالي الصيغة القديمة للربط الخارجي اليساري:
</p>

<pre class="ipsCode">
SELECT publishers.pub_name, books.title
FROM Publishers, Books
WHERE publishers.pub_id *= books.pub_id
</pre>

<h3>
	الربط الخارجي الأيمن Right outer join
</h3>

<p>
	يتضّمن الربط الخارجي الأيمن في مجموعة النتائج الخاصة به كافة الصفوف من الجدول الأيمن التي لا تحقّق الشرط المحدّد، وتُضبَط أعمدة الخرج المقابلة من الجدول الآخر على القيمة الفارغة <code>NULL</code>.
</p>

<p>
	يستخدِم المثال التالي الصيغة الجديدة للربط الخارجي الأيمن:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_7466_135" style="">
<span class="pln">SELECT titleauthor</span><span class="pun">.</span><span class="pln">title_id</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_lname</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_fname
FROM titleauthor
RIGHT OUTER JOIN authors ON titleauthor</span><span class="pun">.</span><span class="pln">au_id </span><span class="pun">=</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_id
ORDERY BY au_lname</span></pre>

<p>
	بينما يوضِّح المثال التالي الصيغة القديمة المستخدَمة للربط الخارجي الأيمن:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_7466_137" style="">
<span class="pln">SELECT titleauthor</span><span class="pun">.</span><span class="pln">title_id</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_lname</span><span class="pun">,</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_fname
FROM titleauthor</span><span class="pun">,</span><span class="pln"> authors
WHERE titleauthor</span><span class="pun">.</span><span class="pln">au_id </span><span class="pun">=*</span><span class="pln"> authors</span><span class="pun">.</span><span class="pln">au_id
ORDERY BY au_lname</span></pre>

<h3>
	الربط الخارجي الكامل Full outer join
</h3>

<p>
	يحدِّد الربط الخارجي الكامل أنه في حالة عدم تطابق صف من أي من الجدولين مع معايير التحديد، فسيُضمَّن الصف في مجموعة النتائج، وتُضبَط أعمدة الخرج الخاصة به التي تتوافق مع الجدول الآخر إلى القيمة الفارغة <code>NULL</code>.
</p>

<p>
	فيما يلي مثال عن ربط خارجي كامل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4227_79" style="">
<span class="pln">SELECT books</span><span class="pun">.</span><span class="pln">title</span><span class="pun">,</span><span class="pln"> publishers</span><span class="pun">.</span><span class="pln">pub_name</span><span class="pun">,</span><span class="pln"> publishers</span><span class="pun">.</span><span class="pln">province
FROM </span><span class="typ">Publishers</span><span class="pln">
FULL OUTER JOIN </span><span class="typ">Books</span><span class="pln"> ON books</span><span class="pun">.</span><span class="pln">pub_id </span><span class="pun">=</span><span class="pln"> publishers</span><span class="pun">.</span><span class="pln">pub_id
WHERE </span><span class="pun">(</span><span class="pln">publishers</span><span class="pun">.</span><span class="pln">province </span><span class="pun">&lt;&gt;</span><span class="pln"> </span><span class="str">"BC"</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> publishers</span><span class="pun">.</span><span class="pln">province </span><span class="pun">&lt;&gt;</span><span class="pln"> </span><span class="str">"ON"</span><span class="pun">)</span><span class="pln">
ORDER BY books</span><span class="pun">.</span><span class="pln">title_id</span></pre>

<h3>
	الربط المتقاطع Cross join
</h3>

<p>
	الربط المتقاطع هو ناتج دمج جدولين، وينتج عن هذا الربط صفوف حالة عدم استخدام الشرط WHERE نفسها، أي كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7466_141" style="">
<span class="pln">SELECT au_lname</span><span class="pun">,</span><span class="pln"> pub_name</span><span class="pun">,</span><span class="pln">
FROM </span><span class="typ">Authors</span><span class="pln"> CROSS JOIN </span><span class="typ">Publishers</span></pre>

<p>
	للمزيد من المعلومات، انظر <a href="https://wiki.hsoub.com/SQL" rel="external">توثيق SQL</a> في موسوعة حسوب.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://opentextbc.ca/dbdesign01/chapter/chapter-sql-dml/" rel="external nofollow">SQL Data Manipulation Language</a> لصاحبَيه Adrienne Watt و Nelson Eng.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/devops/servers/databases/%D8%A3%D9%85%D8%AB%D9%84%D8%A9-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%B9%D9%86-%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r597/" rel="">أمثلة عملية عن كيفية تصميم قواعد البيانات</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%8A%D9%83%D9%84%D9%8A%D8%A9-sql-r1368/" rel="">نظرة سريعة على لغة الاستعلامات الهيكلية SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%88%D8%B8%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r546/" rel="">الاعتماديات الوظيفية المستخدمة في تصميم قواعد البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D9%88%D9%82%D9%8A%D9%88%D8%AF%D9%87%D8%A7-%D9%84%D8%B6%D9%85%D8%A7%D9%86-%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r544/" rel="">قواعد السلامة وقيودها لضمان سلامة البيانات في قواعد البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">الاستعلامات الفرعية والإجراءات في </a><a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D9%88%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%8A%D8%A8-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%B4%D9%8A%D8%AD-%D9%81%D9%8A-sql-r848/" rel="">البحث والتنقيب والترشيح في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">معالجة الأخطاء والتعديل على قواعد البيانات في </a><a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/26-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">تصميم قواعد البيانات</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1369</guid><pubDate>Thu, 11 Nov 2021 16:08:00 +0000</pubDate></item><item><title>&#x646;&#x638;&#x631;&#x629; &#x633;&#x631;&#x64A;&#x639;&#x629; &#x639;&#x644;&#x649; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; &#x627;&#x644;&#x647;&#x64A;&#x643;&#x644;&#x64A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%8A%D9%83%D9%84%D9%8A%D8%A9-sql-r1368/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2021_11/618a15cb8bb44_--.png.111f9f8533f86698b89ff3c5601bc222.png" /></p>

<p>
	<a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/" rel="">لغة الاستعلامات الهيكلية</a> Structured Query Language -أو SQL اختصارًا- هي لغة <a href="https://academy.hsoub.com/devops/servers/databases/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%88%D8%AA%D8%B5%D9%85%D9%8A%D9%85%D9%87%D8%A7-r519/" rel="">قاعدة بيانات</a> مصمَّمة لإدارة البيانات الموجودة في نظام إدارة <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D8%A6%D9%82%D9%8A%D8%A9-rdm-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D8%A7%D9%84%D9%85%D9%87%D9%85%D8%A9-%D9%81%D9%8A-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r522/" rel="">قواعد البيانات العلائقية</a>.
</p>

<p>
	طوّرت شركة IBM <a href="https://wiki.hsoub.com/SQL" rel="external">لغة SQL</a> في أوائل السبعينات -عُرِفت بالإصدار 1986-، حيث صُمِّم الإصدار الأولي المسمَّى بلغة الاستعلامات الهيكلية الإنجليزية SEQUEL -اختصارًا للعبارة Structured English Query Language- لمعالجة واسترداد البيانات المخزَّنة في نظام خاص بشركة IBM وشبه علائقي لإدارة قواعد البيانات، ويُسمَّى نظام R.
</p>

<p>
	قدّمت بعد ذلك شركة Relational Software Inc -والتي أصبحت الآن شركة Oracle Corporation- أول تطبيق متاح تجاريًا للغة SQL والمسمَّى بـ Oracle V2 لحواسيب VAX في أواخر السبعينات.
</p>

<p>
	تُستخدَم العديد من أنظمة DBMS العلائقية المتاحة حاليًا، مثل: Oracle Database، وMicrosoft SQL Server -الموضَّح في الشكل التالي-، وMySQL، وIBM DB2، وIBM Informix، وMicrosoft Access، لغة SQL.
</p>

<p style="text-align: center;">
	<img alt="SQLServer.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="81937" data-unique="0urqksr7u" src="https://academy.hsoub.com/uploads/monthly_2021_11/SQLServer.jpg.62d59c230b793313b8aedb0cccb6cdc0.jpg"></p>

<p>
	تُستخدَم لغة قاعدة بيانات SQL في نظام DBMS من أجل:
</p>

<ul>
<li>
		إنشاء بنى <a href="https://academy.hsoub.com/devops/servers/databases/%D8%AE%D8%B5%D8%A7%D8%A6%D8%B5-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%88%D8%A7%D9%84%D9%85%D8%B2%D8%A7%D9%8A%D8%A7-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D9%82%D8%AF%D9%85%D9%87%D8%A7-r520/" rel="">قواعد البيانات</a> والجداول.
	</li>
	<li>
		إجراء الأعمال الأساسية لإدارة البيانات، مثل الإضافة والحذف والتعديل.
	</li>
	<li>
		إجراء استعلامات معقَّدة لتحويل البيانات الأولية إلى معلومات مفيدة.
	</li>
</ul>
<p>
	سوف نركز في هذا المقال على استخدام لغة SQL لإنشاء بنى <a href="https://academy.hsoub.com/devops/servers/databases/" rel="">قواعد البيانات</a> والجداول، باستخدام لغة SQL على أساس لغة تعريف بيانات data definition language -أو DDL اختصارًا- بصورة أساسية.
</p>

<p>
	سنستخدم لغة SQL في مقال لاحق على أساس لغة معالجة بيانات data manipulation language -أو DML اختصارًا- لإدخال البيانات، وحذفها، واختيارها، وتحديثها في جداول قاعدة البيانات.
</p>

<h2>
	إنشاء قاعدة بيانات Create Database
</h2>

<p>
	تتكوّن عبارات لغة SQL DDL الرئيسية من: CREATE DATABASE وCREATE/DROP/ALTER TABLE، إذ تُستخدَم عبارة CREATE في لغة SQL لإنشاء بنى قواعد البيانات والجداول.
</p>

<h3>
	إنشاء قاعدة بيانات
</h3>

<p>
	تُنشَأ قاعدة بيانات جديدة تسمَّى SW باستخدام العبارة CREATE DATABASE SW بلغة SQL. الخطوة التالية بعد إنشاء قاعدة البيانات هي إنشاء جداول قاعدة البيانات.
</p>

<p>
	التنسيق العام للأمر CREATE TABLE هو:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_13" style="">
<span class="pln">CREATE TABLE </span><span class="str">&lt;tablename&gt;</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">ColumnName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Datatype</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Optional</span><span class="pln"> </span><span class="typ">Column</span><span class="pln"> </span><span class="typ">Constraint</span><span class="pun">,</span><span class="pln">
</span><span class="typ">ColumnName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Datatype</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Optional</span><span class="pln"> </span><span class="typ">Column</span><span class="pln"> </span><span class="typ">Constraint</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Optional</span><span class="pln"> table </span><span class="typ">Constraints</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	يكون Tablename اسم جدول قاعدة البيانات مثل جدول الموظف Employee، كما يتكون كل حقل من الأمر CREATE TABLE من ثلاثة أجزا، هي:
</p>

<ol>
<li>
		اسم العمود ColumnName.
	</li>
	<li>
		نوع البيانات Data type.
	</li>
	<li>
		قيد عمود اختياري Optional Column Constraint.
	</li>
</ol>
<p>
	يجب أن يكون اسم العمود ColumnName فريدًا في الجدول، وبعض الأمثلة على أسماء الأعمدة هي FirstName وLastName.
</p>

<p>
	أما نوع البيانات Data Type، فيجب أن يكون نوع بيانات نظام أو نوع بيانات يعرِّفه المستخدِم، كما تملك العديد من <a href="https://wiki.hsoub.com/SQL#.D8.A3.D9.86.D9.88.D8.A7.D8.B9_.D8.A7.D9.84.D8.A8.D9.8A.D8.A7.D9.86.D8.A7.D8.AA" rel="external">أنواع البيانات</a> حجمًا، مثل (CHAR(35 أو (Numeric(8,2 وإليك قائمة بأشهر أنواع البيانات:
</p>

<ul>
<li>
		النوع Bit: بيانات أعداد صحيحة Integer لها قيمة 1 أو 0.
	</li>
	<li>
		النوع Int: بيانات أعداد صحيحة Integer لها القيم من ‎-2^31 أي (‎-2,147,483,648) حتى ‎2^31 – 1، أي (‎2,147,483,647).
	</li>
	<li>
		النوع Smallint: بيانات أعداد صحيحة Integer لها القيم من ‎(-32,768) 2^15 أي حتى ‎ 2^15 – 1أي 32,767.
	</li>
	<li>
		النوع Tinyint: بيانات أعداد صحيحة Integer لها القيم من 0 حتى 255.
	</li>
	<li>
		النوع Decimal: بيانات ذات دقة ثابتة وقياس رقمي لها القيم من ‎-10^38 -1 إلى‎ 10^38.
	</li>
	<li>
		النوع Numeric: مرادف للنوع decimal.
	</li>
	<li>
		النوع Timestamp: رقم فريد على مستوى قاعدة البيانات.
	</li>
	<li>
		النوع Uniqueidentifier: معرَّف فريد عالميًا globally unique identifier -أو GUID اختصارًا-.
	</li>
	<li>
		النوع Money: تتراوح قيم البيانات النقدية من ‎-2^63 أي ‎-922,337,203,685,477.5808 حتى ‎2^63 – 1 أي ‎922,337,203,685,477.5807 بدقة تصل إلى واحد من عشرة آلاف من الوحدة النقدية.
	</li>
	<li>
		النوع Smallmoney: تتراوح قيم البيانات النقدية من ‎-214,748.3648إلى ‎+214,748.3647 بدقة تصل إلى واحد من عشرة آلاف من الوحدة النقدية.
	</li>
	<li>
		النوع Float: بيانات أرقام ذات دقة عشرية تتراوح قيمها بين ‎ -1.79E + 308و ‎1.79E + 308.
	</li>
	<li>
		النوع Real: بيانات أرقام ذات دقة عشرية قيمها تتراوح من ‎-3.40E + 38 حتى ‎3.40E + 38.
	</li>
	<li>
		النوع Datetime: بيانات التاريخ والوقت تتراوح قيمها من January 1, 1753 إلى December 31, 9999 بدقة تبلغ واحد إلى ثلاثة أجزاء من مئة من الثانية، أو 3.33 ميلي ثانية.
	</li>
	<li>
		النوع Smalldatetime: بيانات التاريخ والوقت تتراوح قيمها من January 1, 1900 حتى June 6, 2079 بدقة تبلغ دقيقة واحدة.
	</li>
	<li>
		النوع Char: بيانات محارف ثابتة الطول وليست يونيكود بطول أقصى 8000 محرف.
	</li>
	<li>
		النوع Varchar: بيانات متغيرة الطول وليست يونيكود بحد أقصى 8000 محرف.
	</li>
	<li>
		النوع Text: بيانات متغيرة الطول وليست يونيكود بطول أقصى يبلغ ‎2^31 – 1 أي ‎2,147,483,647 محرفًا.
	</li>
	<li>
		النوع Binary: بيانات ثنائية ذات طول ثابت بطول أقصى 8000 بايت.
	</li>
	<li>
		النوع Varbinary: بيانات ثنائية متغيرة الطول بطول أقصى يبلغ 8000 بايت.
	</li>
	<li>
		النوع Image: بيانات ثنائية متغيرة الطول بطول أقصى ‎2^31 – 1 أي‎ 2,147,483,647بايت.
	</li>
</ul>
<p>
	أخيرًا في ما يتعلق بقيود العمود الاختيارية Optional Column Constraints، فهي الآتي:
</p>

<ul>
<li>
		NULL.
	</li>
	<li>
		NOT NULL.
	</li>
	<li>
		UNIQUE.
	</li>
	<li>
		PRIMARY KEY.
	</li>
	<li>
		DEFAULT.
	</li>
</ul>
<p>
	وتُستخدَم لتهيئة قيمة لسجل جديد.
</p>

<p>
	يشير قيد العمود NULL إلى أن القيمة الفارغة null مسموح بها، مما يعني أنه يمكن إنشاء صف بدون قيمة لهذا العمود؛ كما يشير قيد العمود NOT NULL إلى وجوب توفير قيمة عند إنشاء صف جديد.
</p>

<p>
	سنستخدم <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D9%82%D8%AF%D9%85-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sql-r961/" rel="">تعليمة لغة SQL</a> للتوضيح والتي هي CREATE TABLE EMPLOYEES لإنشاء جدول موظفين يحتوي على 16 سمة attributes أو حقل fields.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_11" style="">
<span class="pln">USE SW
CREATE TABLE EMPLOYEES
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">EmployeeNo</span><span class="pln">      CHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln">  NOT NULL  UNIQUE</span><span class="pun">,</span><span class="pln">
</span><span class="typ">DepartmentName</span><span class="pln">  CHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">  NOT NULL  DEFAULT </span><span class="str">"Human Resources"</span><span class="pun">,</span><span class="pln">
</span><span class="typ">FirstName</span><span class="pln">       CHAR</span><span class="pun">(</span><span class="lit">25</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">LastName</span><span class="pln">        CHAR</span><span class="pun">(</span><span class="lit">25</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Category</span><span class="pln">        CHAR</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">HourlyRate</span><span class="pln">      CURRENCY  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">TimeCard</span><span class="pln">        LOGICAL   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">HourlySalaried</span><span class="pln">  CHAR</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">EmpType</span><span class="pln">         CHAR</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Terminated</span><span class="pln">      LOGICAL   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">ExemptCode</span><span class="pln">      CHAR</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Supervisor</span><span class="pln">      LOGICAL   NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">SupervisorName</span><span class="pln">  CHAR</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">BirthDate</span><span class="pln">       DATE      NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">CollegeDegree</span><span class="pln">   CHAR</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">   NOT NULL</span><span class="pun">,</span><span class="pln">
CONSTRAINT      </span><span class="typ">Employee_PK</span><span class="pln"> PRIMARY KEY</span><span class="pun">(</span><span class="typ">EmployeeNo</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	الحقل الأول هو EmployeeNo من النوع CHAR، ويبلغ طول هذا الحقل 10 محارف، ولا يمكن للمستخدِم ترك هذا الحقل فارغًا NOT NULL، والحقل الثاني هو DepartmentName من النوع CHAR بطول 30.
</p>

<p>
	يُستخدَم قيد الجدول المعرَّف بواسطة الكلمة CONSTRAINT لإنشاء المفتاح الأساسي primary key، وذلك بعد تعريف جميع أعمدة الجدول، أي كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_18" style="">
<span class="pln">CONSTRAINT     </span><span class="typ">EmployeePK</span><span class="pln">      PRIMARY KEY</span><span class="pun">(</span><span class="typ">EmployeeNo</span><span class="pun">)</span></pre>

<p>
	يمكننا إنشاء جدول أقسام Department، وجدول مشاريع Project، وجدول مهام Assignment باستخدام الأمر CREATE TABLE بلغة SQL DDL، كما هو موضَّح في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_20" style="">
<span class="pln">USE SW
CREATE TABLE DEPARTMENT
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">DepartmentName</span><span class="pln"> </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">BudgetCode</span><span class="pln">     </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">OfficeNumber</span><span class="pln">   </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">15</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Phone</span><span class="pln">          </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">15</span><span class="pun">)</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
CONSTRAINT DEPARTMENT_PK PRIMARY KEY</span><span class="pun">(</span><span class="typ">DepartmentName</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	أُنشِئ جدول المشاريع project التالي بسبعة حقول هي: معرِّف المشروع ProjectID، واسم المشروع ProjectName، والقسم Department، والحد الأقصى للساعات MaxHours، وتاريخ البدء StartDate، وتاريخ الانتهاء EndDate.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_22" style="">
<span class="pln">USE SW
CREATE TABLE PROJECT
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">ProjectID</span><span class="pln">       </span><span class="typ">Int</span><span class="pln">  NOT NULL IDENTITY </span><span class="pun">(</span><span class="lit">1000</span><span class="pun">,</span><span class="lit">100</span><span class="pun">),</span><span class="pln">
</span><span class="typ">ProjectName</span><span class="pln">     </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Department</span><span class="pln">      </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">MaxHours</span><span class="pln">        </span><span class="typ">Numeric</span><span class="pun">(</span><span class="lit">8</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln">  NOT NULL DEFAULT </span><span class="lit">100</span><span class="pun">,</span><span class="pln">
</span><span class="typ">StartDate</span><span class="pln">       </span><span class="typ">DateTime</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">EndDate</span><span class="pln">         </span><span class="typ">DateTime</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln">
CONSTRAINT      ASSIGNMENT_PK  PRIMARY KEY</span><span class="pun">(</span><span class="typ">ProjectID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	بينما أُنشِئ جدول المهام assignment بثلاثة حقول، هي: معرِّف المشروع ProjectID، ورقم الموظف EmployeeNumber، وساعات العمل HoursWorked.
</p>

<p>
	يُستخدَم جدول المهام لتسجيل الموظف باستخدام الحقل EmployeeNumber، ومقدار الوقت باستخدام الحقل HoursWorked الذي عمل فيه الموظف في مشروع معين باستخدام الحقل ProjectID، أي كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_24" style="">
<span class="pln">USE SW
CREATE TABLE ASSIGNMENT
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">ProjectID</span><span class="pln">       </span><span class="typ">Int</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">EmployeeNumber</span><span class="pln">  </span><span class="typ">Int</span><span class="pln">  NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">HoursWorked</span><span class="pln">     </span><span class="typ">Numeric</span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln">  NULL</span><span class="pun">,</span><span class="pln">
</span><span class="pun">);</span></pre>

<h2>
	قيود الجدول Table Constraints
</h2>

<p>
	تُعرَّف قيود الجدول بواسطة الكلمة المفتاحية CONSTRAINT ويمكن استخدامها لتطبيق العديد من القيود الموضَّحة أدناه.
</p>

<h3>
	القيد IDENTITY
</h3>

<p>
	يمكننا استخدام قيد العمود الاختياري IDENTITY لتوفير قيمة فريدة تزايدية لهذا العمود، إذ تُستخدَم أعمدة الهوية Identity مع قيود المفتاح الرئيسي PRIMARY KEY لتكون بمثابة معرِّف صف فريد للجدول، كما يمكن إسناد الخاصية IDENTITY إلى عمود له نوع بيانات tinyint، أو smallint، أو int، أو decimal، أو numeric، وهذا القيد:
</p>

<ul>
<li>
		يولِّد أرقامًا متسلسلةً.
	</li>
	<li>
		لا يفرض سلامة الكيان entity integrity.
	</li>
	<li>
		يمكن أن يحتوي عمود واحد فقط على الخاصية IDENTITY.
	</li>
	<li>
		يجب تعريفه على أساس نوع بيانات integer أو numeric أو decimal.
	</li>
	<li>
		لا يمكن تحديث عمود له الخاصية IDENTITY.
	</li>
	<li>
		لا يمكن أن يحتوي على قيم فارغة NULL.
	</li>
	<li>
		لا يمكنه ربط الافتراضات والقيود الافتراضية بالعمود.
	</li>
</ul>
<p>
	بالنسبة للقيد [(IDENTITY[(seed, increment:
</p>

<ul>
<li>
		Seed: هي القيمة الأولية لعمود الهوية identity.
	</li>
	<li>
		Increment: هي القيمة المطلوب إضافتها إلى عمود الزيادة increment الأخير.
	</li>
</ul>
<p>
	سنستخدم مثال قاعدة بيانات آخر لتوضيح عبارات لغة SQL DDL بصورة أكبر من خلال إنشاء الجدول tblHotel في قاعدة بيانات الفندق HOTEL كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_13" style="">
<span class="pln">CREATE TABLE  tblHotel
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">HotelNo</span><span class="pln">   </span><span class="typ">Int</span><span class="pln">         IDENTITY </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">),</span><span class="pln">
</span><span class="typ">Name</span><span class="pln">      </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">    NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Address</span><span class="pln">   </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">    NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">City</span><span class="pln">      </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">25</span><span class="pun">)</span><span class="pln">    NULL</span><span class="pun">,</span><span class="pln">
</span><span class="pun">)</span></pre>

<h3>
	القيد UNIQUE
</h3>

<p>
	يمنع القيد UNIQUE من إدخال قيم مكررة في عمود، حيث:
</p>

<ul>
<li>
		يُستخدَم القيدان PK، و UNIQUE لفرض سلامة الكيان.
	</li>
	<li>
		يمكن تعريف قيود UNIQUE متعددة للجدول.
	</li>
	<li>
		يجري دائمًا التحقق من صحة البيانات الموجودة عند إضافة قيد UNIQUE إلى جدول موجود.
	</li>
	<li>
		يمكن وضع القيد UNIQUE على الأعمدة التي تقبل القيم الفارغة، حيث يمكن أن يكون صفٌ واحد فقط NULL.
	</li>
	<li>
		ينشِئ القيد UNIQUE دليلًا فريدًا للعمود المُختار تلقائيًا.
	</li>
</ul>
<p>
	الصيغة التالية هي الصيغة العامة للقيد UNIQUE:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_28" style="">
<span class="pun">[</span><span class="pln">CONSTRAINT constraint_name</span><span class="pun">]</span><span class="pln">
UNIQUE </span><span class="pun">[</span><span class="pln">CLUSTERED </span><span class="pun">|</span><span class="pln"> NONCLUSTERED</span><span class="pun">]</span><span class="pln">
</span><span class="pun">(</span><span class="pln">col_name </span><span class="pun">[,</span><span class="pln"> col_name2 </span><span class="pun">[…,</span><span class="pln"> col_name16</span><span class="pun">]])</span><span class="pln">
</span><span class="pun">[</span><span class="pln">ON segment_name</span><span class="pun">]</span></pre>

<p>
	يستخدم المثال التالي القيد UNIQUE كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_15" style="">
<span class="pln">CREATE TABLE EMPLOYEES
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">EmployeeNo</span><span class="pln">  CHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln">    NOT NULL    UNIQUE</span><span class="pun">,</span><span class="pln">
</span><span class="pun">)</span></pre>

<h3>
	القيد FOREIGN KEY المفتاح الخارجي
</h3>

<p>
	يعرِّف القيد FOREIGN KEY -أو FK اختصارًا- عمودًا، أو مجموعة من الأعمدة التي تتطابق قيمها مع المفتاح الرئيسي PRIMARY KEY -أو PK اختصارًا- لجدول آخر، بحيث:
</p>

<ul>
<li>
		تُحدَّث القيم في المفتاح الخارجي FK تلقائيًا عند تحديث أو تغيير قيم المفتاح الرئيسي PK في الجدول المرتبط.
	</li>
	<li>
		يجب أن تشير قيود المفتاح الخارجي FK إلى القيد المفتاح الرئيسي PK، أو القيد UNIQUE لجدول آخر.
	</li>
	<li>
		يجب أن يكون عدد أعمدة المفتاح الخارجي FK هو نفسه قيد المفتاح الرئيسي PK، أو قيد UNIQUE.
	</li>
	<li>
		إذا اُستخدِم الخيار WITH NOCHECK، فلن يتحقق قيد المفتاح الخارجي FK من صحة البيانات الموجودة في الجدول.
	</li>
	<li>
		لا يوجد دليل index للأعمدة التي تشارك في قيد المفتاح الخارجي FK.
	</li>
</ul>
<p>
	الصيغة التالية هي الصيغة العامة لقيد المفتاح الخارجي FOREIGN KEY:
</p>

<pre class="ipsCode">
[CONSTRAINT constraint_name]
[FOREIGN KEY (col_name [, col_name2 […, col_name16]])]
REFERENCES [owner.]ref_table [(ref_col [, ref_col2 […, ref_col16]])]
</pre>

<p>
	يكون الحقل HotelNo في المثال التالي في الجدول tblRoom مفتاحًا خارجيًا FK للحقل HotelNo في الجدول tblHotel الموضَّح سابقًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_17" style="">
<span class="pln">USE HOTEL
GO
CREATE TABLE  tblRoom
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">HotelNo</span><span class="pln"> </span><span class="typ">Int</span><span class="pln">        NOT NULL </span><span class="pun">,</span><span class="pln">
</span><span class="typ">RoomNo</span><span class="pln">  </span><span class="typ">Int</span><span class="pln">        NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Type</span><span class="pln">    </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">   NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Price</span><span class="pln">   </span><span class="typ">Money</span><span class="pln">      NULL</span><span class="pun">,</span><span class="pln">
PRIMARY KEY </span><span class="pun">(</span><span class="typ">HotelNo</span><span class="pun">,</span><span class="pln"> </span><span class="typ">RoomNo</span><span class="pun">),</span><span class="pln">
FOREIGN KEY </span><span class="pun">(</span><span class="typ">HotelNo</span><span class="pun">)</span><span class="pln"> REFERENCES tblHotel
</span><span class="pun">)</span></pre>

<h3>
	القيد CHECK
</h3>

<p>
	يقيِّد القيد CHECK القيم التي يمكن إدخالها في جدول، بحيث:
</p>

<ul>
<li>
		يمكن أن يحتوي على شروط بحث مشابهة لعبارة WHERE.
	</li>
	<li>
		يمكنه الربط بين الأعمدة في نفس الجدول.
	</li>
	<li>
		يجب تقييم قاعدة التحقق من صحة البيانات للقيد CHECK من خلال تعبير بولياني boolean expression.
	</li>
	<li>
		يمكن تعريفه لعمود له قاعدة مرتبطة به.
	</li>
</ul>
<p>
	الصيغة التالية هي الصيغة العامة للقيد CHECK:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_34" style="">
<span class="pun">[</span><span class="pln">CONSTRAINT constraint_name</span><span class="pun">]</span><span class="pln">
CHECK </span><span class="pun">[</span><span class="pln">NOT FOR REPLICATION</span><span class="pun">]</span><span class="pln"> </span><span class="pun">(</span><span class="pln">expression</span><span class="pun">)</span></pre>

<p>
	يقتصر حقل النوع Type في المثال التالي على الأنواع "Single"، أو "Double"، أو "Suite"، أو "Executive".
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_19" style="">
<span class="pln">USE HOTEL
GO
CREATE TABLE  tblRoom
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">HotelNo</span><span class="pln"> </span><span class="typ">Int</span><span class="pln">      NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">RoomNo</span><span class="pln">  </span><span class="typ">Int</span><span class="pln">      NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Type</span><span class="pln">    </span><span class="typ">Char</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Price</span><span class="pln">   </span><span class="typ">Money</span><span class="pln">    NULL</span><span class="pun">,</span><span class="pln">
PRIMARY KEY </span><span class="pun">(</span><span class="typ">HotelNo</span><span class="pun">,</span><span class="pln"> </span><span class="typ">RoomNo</span><span class="pun">),</span><span class="pln">
FOREIGN KEY </span><span class="pun">(</span><span class="typ">HotelNo</span><span class="pun">)</span><span class="pln"> REFERENCES tblHotel
CONSTRAINT </span><span class="typ">Valid_Type</span><span class="pln">
CHECK </span><span class="pun">(</span><span class="typ">Type</span><span class="pln"> IN </span><span class="pun">(</span><span class="str">'Single'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Double'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Suite'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Executive'</span><span class="pun">))</span><span class="pln">
</span><span class="pun">)</span></pre>

<p>
	يجب في المثال التالي أن يكون تاريخ تعيين الموظف قبل January 1, 2004، أو يجب أن يكون الحد الأقصى للراتب 300 ألف دولار:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_21" style="">
<span class="pln">GO
CREATE TABLE SALESREPS
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">Empl_num</span><span class="pln"> </span><span class="typ">Int</span><span class="pln"> </span><span class="typ">Not</span><span class="pln"> </span><span class="typ">Null</span><span class="pln">
CHECK </span><span class="pun">(</span><span class="typ">Empl_num</span><span class="pln"> BETWEEN </span><span class="lit">101</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="lit">199</span><span class="pun">),</span><span class="pln">
</span><span class="typ">Name</span><span class="pln">     </span><span class="typ">Char</span><span class="pln"> </span><span class="pun">(</span><span class="lit">15</span><span class="pun">),</span><span class="pln">
</span><span class="typ">Age</span><span class="pln">      </span><span class="typ">Int</span><span class="pln">     CHECK </span><span class="pun">(</span><span class="typ">Age</span><span class="pln"> </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">21</span><span class="pun">),</span><span class="pln">
</span><span class="typ">Quota</span><span class="pln">    </span><span class="typ">Money</span><span class="pln">   CHECK </span><span class="pun">(</span><span class="typ">Quota</span><span class="pln"> </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">0.0</span><span class="pun">),</span><span class="pln">
</span><span class="typ">HireDate</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">,</span><span class="pln">
CONSTRAINT  </span><span class="typ">QuotaCap</span><span class="pln"> CHECK </span><span class="pun">((</span><span class="typ">HireDate</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="str">"01-01-2004"</span><span class="pun">)</span><span class="pln"> OR </span><span class="pun">(</span><span class="typ">Quota</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="lit">300000</span><span class="pun">))</span><span class="pln">
</span><span class="pun">)</span></pre>

<h3>
	القيد DEFAULT
</h3>

<p>
	يُستخدَم القيد DEFAULT لتوفير قيمة تُضاف تلقائيًا لعمود ما إذا لم يوفّرها المستخدم، بحيث:
</p>

<ul>
<li>
		يمكن احتواء العمود على قيد DEFAULT واحد فقط.
	</li>
	<li>
		لا يمكن استخدام القيد DEFAULT في الأعمدة التي لها نوع البيانات timestamp، أو الخاصية identity.
	</li>
	<li>
		ترتبط القيود DEFAULT تلقائيًا بعمود عند إنشائها.
	</li>
</ul>
<p>
	الصيغة العامة للقيد DEFAULT هي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_42" style="">
<span class="pun">[</span><span class="pln">CONSTRAINT constraint_name</span><span class="pun">]</span><span class="pln">
DEFAULT </span><span class="pun">{</span><span class="pln">constant_expression </span><span class="pun">|</span><span class="pln"> niladic</span><span class="pun">-</span><span class="kwd">function</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> NULL</span><span class="pun">}</span><span class="pln">
</span><span class="pun">[</span><span class="pln">FOR col_name</span><span class="pun">]</span></pre>

<p>
	يضبط المثال التالي القيمة الافتراضية default لحقل المدينة city field على القيمة "Vancouver":
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_44" style="">
<span class="pln">USE HOTEL
ALTER TABLE tblHotel
</span><span class="typ">Add</span><span class="pln"> CONSTRAINT df_city DEFAULT </span><span class="pun">‘</span><span class="typ">Vancouver</span><span class="pun">’</span><span class="pln"> FOR </span><span class="typ">City</span></pre>

<h2>
	الأنواع التي يعرفها المستخدم User Defined Types
</h2>

<p>
	تعتمد الأنواع التي يعرِّفها المستخدِم دائمًا على نوع البيانات التي يوفرها النظام، فيمكن لهذه الأنواع فرض سلامة البيانات والسماح بالقيم الفارغة nulls.
</p>

<p>
	اختر الأنواع التي تكون تحت الكلمة "Programmability" في قاعدة البيانات الخاصة بك، لإنشاء نوع بيانات يعرِّفه المستخدِم في خادم SQL Server، ثم انقر بزر الماوس الأيمن واختر المسار New’ –&gt;‘User-defined data type’، أو نفّذ إجراء النظام sp_addtype المخزّن system stored procedure، ثم اكتب ما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_23" style="">
<span class="pln">sp_addtype ssn</span><span class="pun">,</span><span class="pln"> </span><span class="str">'varchar(11)'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'NOT NULL'</span></pre>

<p>
	سيؤدي هذا إلى إضافة نوع بيانات جديد عرّفه المستخدم يسمى SIN بتسعة محارف.
</p>

<p>
	يستخدم الحقل EmployeeSIN نوع البيانات SIN الذي عرّفه المستخدم في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_25" style="">
<span class="pln">CREATE TABLE </span><span class="typ">SINTable</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
</span><span class="typ">EmployeeID</span><span class="pln">     INT </span><span class="typ">Primary</span><span class="pln"> </span><span class="typ">Key</span><span class="pun">,</span><span class="pln">
</span><span class="typ">EmployeeSIN</span><span class="pln">    SIN</span><span class="pun">,</span><span class="pln">
CONSTRAINT </span><span class="typ">CheckSIN</span><span class="pln">
CHECK </span><span class="pun">(</span><span class="typ">EmployeeSIN</span><span class="pln"> LIKE
</span><span class="str">' [0-9][0-9][0-9] – [0-9][0-9] [0-9] – [0-9][0-9][0-9] '</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span></pre>

<h3>
	التعليمة ALTER TABLE
</h3>

<p>
	يمكن استخدام تعليمات ALTER TABLE لإضافة وحذف القيود، بحيث:
</p>

<ul>
<li>
		تسمح تعليمة ALTER TABLE بإزالة الأعمدة.
	</li>
	<li>
		يُتحقق من جميع البيانات الموجودة عند إضافة قيد للتأكد من عدم وجود انتهاكات.
	</li>
</ul>
<p>
	نستخدم في المثال التالي تعليمة ALTER TABLE للخاصية IDENTITY في الحقل ColumnName:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1783_50" style="">
<span class="pln">USE HOTEL
GO
ALTER TABLE  tblHotel
ADD CONSTRAINT unqName UNIQUE </span><span class="pun">(</span><span class="typ">Name</span><span class="pun">)</span></pre>

<p>
	استخدم تعليمة ALTER TABLE لإضافة عمود مع الخاصية IDENTITY مثل التعليمة ALTER TABLE TableName.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_552_27" style="">
<span class="pln">ADD
</span><span class="typ">ColumnName</span><span class="pln">  </span><span class="kwd">int</span><span class="pln"> IDENTITY</span><span class="pun">(</span><span class="pln">seed</span><span class="pun">,</span><span class="pln"> increment</span><span class="pun">)</span></pre>

<h3>
	التعليمة DROP TABLE
</h3>

<p>
	تزيل التعليمة DROP TABLE جدولًا من قاعدة البيانات، لذلك تأكد من تحديد قاعدة البيانات الصحيحة.
</p>

<pre class="ipsCode">
DROP TABLE tblHotel
</pre>

<p>
	سيؤدي تنفيذ عبارة DROP TABLE السابقة بلغة SQL إلى إزالة الجدول tblHotel من قاعدة البيانات.
</p>

<h2>
	تمارين
</h2>

<ol>
<li>
		باستخدام المعلومات الخاصة بالتمرين الموجود في المقال <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D9%88%D9%82%D9%8A%D9%88%D8%AF%D9%87%D8%A7-%D9%84%D8%B6%D9%85%D8%A7%D9%86-%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r544/" rel="">قواعد السلامة والقيود المُطبَّقة عند تصميم قواعد البيانات</a>، طبّق التخطيط باستخدام لغة Transact SQL -أي اعرض تعليمات SQL لكل جدول-، وطبّق القيود أيضًا.
	</li>
	<li>
		أنشئ الجدول الموضَّح أدناه في خاوم SQL Server، واعرض التعليمات التي استخدمتها.
	</li>
</ol>
<p>
	الجدول: Employee
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
} 

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				ATTRIBUTE (FIELD) NAME
			</th>
			<th>
				DATA DECLARATION
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				EMP_NUM
			</td>
			<td>
				CHAR(3)
			</td>
		</tr>
<tr>
<td>
				EMP_LNAME
			</td>
			<td>
				VARCHAR(15)
			</td>
		</tr>
<tr>
<td>
				EMP_FNAME
			</td>
			<td>
				VARCHAR(15)
			</td>
		</tr>
<tr>
<td>
				EMP_INITIAL
			</td>
			<td>
				CHAR(1)
			</td>
		</tr>
<tr>
<td>
				EMP_HIREDATE
			</td>
			<td>
				DATE
			</td>
		</tr>
<tr>
<td>
				JOB_CODE
			</td>
			<td>
				CHAR(3)
			</td>
		</tr>
</tbody>
</table>
<ol start="3">
<li>
		اكتب شيفرة لغة SQL لإدخال صفوف الجدول السابق، بعد إنشاء بنيته.
	</li>
</ol>
<p style="text-align: center;">
	<img alt="Ch15-Exercise-Fig15.1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="81938" data-unique="znfi3897v" src="https://academy.hsoub.com/uploads/monthly_2021_11/Ch15-Exercise-Fig15.1.jpg.521fecff8a88e7fa88aa10711fee9f98.jpg"></p>

<p>
	استخدم الشكل السابق للإجابة على الأسئلة من 4 إلى 10.
</p>

<ol start="4">
<li>
		اكتب شيفرة لغة SQL لتغيير رمز الوظيفة job code إلى 501 للموظف الذي رقمه 107، وافحص النتائج بعد الانتهاء من المهمة، ثم أعد ضبط رمز الوظيفة إلى قيمته الأصلية.
	</li>
	<li>
		اكتب شيفرة لغة SQL لإعطاء قائمة بجميع السمات الخاصة برمز الوظيفة 502، بافتراض إدخال البيانات الموضَّحة في جدول الموظف Employee.
	</li>
	<li>
		اكتب شيفرة لغة SQL لحذف الصف الخاص بالشخص الذي اسمه "William Smithfield"، والذي وُظِّف في June 22, 2004، والذي تصنيف رمز وظيفته هو 500.
	</li>
</ol>
<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix">
		<p>
			<strong>تلميح</strong>: استخدم المعاملات المنطقية لتضمين جميع المعلومات الواردة في هذه المسألة.
		</p>
	</div>
</blockquote>

<ol start="7">
<li>
		أضف السمتين EMP_PCT، وPROJ_NUM إلى جدول الموظف، بحيث تكون السمة EMP_PCT هي نسبة المكافأة المدفوعة لكل موظف.
	</li>
	<li>
		اكتب شيفرة لغة SQL باستخدام أمر واحد لإدخال رقم المشروع PROJ_NUM = 18 لجميع الموظفين الذين تصنيف الوظيفة JOB_CODE الخاص بهم هو 500.
	</li>
	<li>
		اكتب شيفرة لغة SQL باستخدام أمر واحد لإدخال رقم المشروع PROJ_NUM = 25 لجميع الموظفين الذين تصنيف الوظيفة JOB_CODE الخاص بهم يساوي 502 أو أعلى.
	</li>
	<li>
		اكتب شيفرة لغة SQL لتغيير رقم المشروع PROJ_NUM إلى 14 للموظفين الذين تعيّنوا قبل January 1, 1994، ورمز الوظيفة الخاصة بهم يساوي 501 على الأقل. (قد تفترض أن الجدول سيعاد إلى حالته الأصلية التي سبقت هذا السؤال).
	</li>
</ol>
<p>
	ترجمة -وبتصرّف- للمقال <a href="https://opentextbc.ca/dbdesign01/chapter/sql-structured-query-language/" rel="external nofollow">SQL Structured Query Language</a> لصاحبَيه Adrienne Watt وNelson Eng.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D9%84%D8%BA%D8%A9-%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-dml-%D8%A7%D9%84%D8%AE%D8%A7%D8%B5%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-sql-r1369/" rel="">لغة معالجة البيانات DML الخاصة بلغة SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/devops/servers/databases/%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database-development-r553/" rel="">عملية تطوير قواعد البيانات Database Development</a>
	</li>
	<li>
		النسحة الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">الاستعلامات الفرعية والإجراءات في SQL</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D9%88%D9%82%D9%8A%D9%88%D8%AF%D9%87%D8%A7-%D9%84%D8%B6%D9%85%D8%A7%D9%86-%D8%B3%D9%84%D8%A7%D9%85%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r544/" rel="">قواعد السلامة وقيودها لضمان سلامة البيانات في قواعد البيانات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%88%D8%B8%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r546/" rel="">الاعتماديات الوظيفية المستخدمة في تصميم قواعد البيانات</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1368</guid><pubDate>Mon, 08 Nov 2021 16:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x645;&#x631;&#x62C;&#x639; &#x627;&#x644;&#x645;&#x62A;&#x642;&#x62F;&#x645; &#x625;&#x644;&#x649; &#x644;&#x63A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D9%82%D8%AF%D9%85-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sql-r961/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_08/sql-tutorial.png.a076e7a1f743228e32217c3a96fae8cc.png" /></p>

<p>
	SQL أو لغة الاستعلامات البنيوية (Structured Query Language) هي لغة برمجة متخصصة تُستخدَم لمعالجة وإدارة قواعد البيانات. وتُنطق سي كويل (See-Quel). تعد اللغة القياسية لأنظمة إدارة قواعد البيانات (RDBMS)، وتُستخدم تعليمات وأوامر SQL لإجراء عمليات مباشرة على البيانات، مثل:
</p>

<ul>
<li>
		تحديث البيانات
	</li>
	<li>
		إدراج سجلات جديدة في قاعدة البيانات
	</li>
	<li>
		حذف السجلات
	</li>
	<li>
		استخلاص البيانات والتنقيب عنها
	</li>
	<li>
		إنشاء جداول لتخزين البيانات
	</li>
	<li>
		إنجاز مهام إدارية على قاعدة البيانات، مثل تأمين قاعدة البيانات وإنشاء النسخ الاحتياطية وإدارة المستخدمين.
	</li>
</ul>
<h2>
	تاريخ SQL
</h2>

<p>
	طوّرت شركة IBM لغة SQL في بداية السبعينات بإسهام من بويس رايموند (Raymond Boyce) ودونالد شامبرلين (Donald Chamberlin)، وكانت تُسمى آنذاك SEQUEL. كان الهدف من تطويرها هو إدارة ومعالجة نظام R، وهو نظام شبه علائقي لمعالجة قواعد البيانات (quasi-relational database management system).
</p>

<p>
	سنة 1986، اعتمدت كل من المنظمة الأمريكية للمقاييس (ANSI) والمنظمة الدولية للمقاييس (ISO) لغة SQL كمقياس مرجعي، وقد تعاقبت بعد ذلك 9 إصدارات جديدة من المعيار، سنوات: 1989 و 1992 و 1996 و 1999 و 2003 و 2006 و 2008 و 2011 و 2016.
</p>

<h2>
	ما هي أنظمة معالجة قواعد البيانات العلائقية RDBMS؟
</h2>

<p>
	أنظمة معالجة قواعد البيانات العلائقية (Relational Database Management System) هي برامج تُستخدَم لمعالجة وإدارة قواعد البيانات العلائقية (Relational Database)، وهي قواعد تخزِّن البيانات وفق بنية مهيكلة في جداول تتألف من صفوف وأعمدة لتسهيل الوصول إلى القيم المخزنة. لكل جدول مفتاح فريد يميز كل صف من الجدول. وتُسمى "علائقية" (relational) لأنّ القيم المُخزّنة في الجداول متعلقة ببعضها بعضًا.
</p>

<p>
	تجري أنظمة قواعد البيانات العديد من المهام، مثل:
</p>

<ul>
<li>
		تأمين البيانات
	</li>
	<li>
		إنشاء النسخ الاحتياطية
	</li>
	<li>
		إدارة ومعالجة كميات ضخمة من البيانات
	</li>
	<li>
		تصدير البيانات أو استيرادها
	</li>
	<li>
		العمل على عدة جداول تزامنيا
	</li>
</ul>
<p>
	هناك العديد من أنظمة معالجة قواعد البيانات، من أشهرها: Oracle و MySQL و Microsoft SQL Server و DB2. ورغم أنّ أكثرها تستخدم SQL، إلا أنّ لكل منها بعض الإضافات والصياغات الخاصة بها التي لا تُستخدم في الأنظمة الأخرى، بيْد أنّها تدعم جميعا الأوامر الأساسية للغة (SELECT و UPDATE و DELETE و INSERT و WHERE).
</p>

<h2>
	لماذا عليك تعلم SQL‎‎؟
</h2>

<p>
	إن كنت تتساءل عما إذا كانت SQL تستحق أن تتعلمها، فالنقاط التالية ستوضح لك بعض مزايا هذه اللغة:
</p>

<ol>
<li>
		<strong>سهولة التعلم</strong>: لغة SQL سهلة موازنة مع بقية لغات البرمجة، ذلك أنّها مخصصة لغرض واحد، وهو معالجة البيانات
	</li>
	<li>
		<strong>معالجة البيانات الكبيرة</strong>: نحن نعيش في عصر الثورة الرقمية، ومن نتائج ذلك أنّ البيانات أصبحت متاحة بكميات ضخمة. ففي كل يوم تُنتج عدة تيرابايت من البيانات. بالطبع، يمكنك استخدام جداول البيانات العادية، مثل EXCEL وجداول جوجل، ولكنها مخصّصة لمعالجة كمية صغيرة أو متوسطة من البيانات. وهنا يأتي دور SQL، لأنها مصممة لمعالجة كميات ضخمة من البيانات بأداء وكفاءة عالية.
	</li>
	<li>
		<strong>تطوير الويب</strong>: SQL هي إحدى المهارات الضرورية لكل مبرمجي الواجهة الخلفية للخادم، لأنها تُستخدم لمعالجة واسترجاع البيانات المُخزّنة في الخادم، بما فيها بيانات المستخدمين.
	</li>
	<li>
		<strong>السرعة</strong>: لا تفعل SQL إلا شيئا واحدا فقط، وهو معالجة البيانات وإدارتها، وهي ممتازة فيما تفعله. فهي مُحسَّنة للدخول إلى البيانات بسرعة فائقة، ما يجعلها مثالية لتطبيقات الوقت الحقيقي.
	</li>
	<li>
		<strong>فرص العمل</strong>: هناك طلب كبير على مبرمجي SQL في القطاع الخاص، ويُتوقع أن يزداد هذا الطلب في السنوات القادمة، خصوصا في العالم العربي الذي يعرف ازدهارا سريعا للاقتصاد الرقمي في السنوات الأخيرة.
	</li>
	<li>
		<strong>الشهرة</strong>: في استطلاع stackoverflow لسنة 2019، حلت SQL في المرتبة الثالثة في قائمة أكثر تقنيات البرمجة استخداما من قبل المبرمجين على مستوى العالم. بعد <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/javascript/" rel="">جافاسكربت</a> و <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/html/" rel="">HTML</a> و <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/css" rel="">CSS</a>. إذ يستخدمها أكثر من نصف المبرمجين. هذا أمر طبيعي، لأنّ SQL هي إحدى أركان تقنيات الويب، ولا يمكن تطوير أي موقع ويب أو تطبيق بدون معرفة ولو بسيطة بها.
	</li>
	<li>
		<strong>مفتوحة المصدر</strong>: SQL مفتوحة المصدر، كما أنّ لديها مجتمعا كبيرا، إن اعترضتك مشكلة أثناء تعلم SQL، فيمكن أن تطرح سؤالك على stackoverflow أو في <a data-ss1614339168="1" href="https://academy.hsoub.com/questions/c3-programming/" rel="">قسم الأسئلة</a> في أكاديمية حسوب.
	</li>
</ol>
<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50152" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b6034d4b18_StackOverflowDeveloperSurvey2019.png.04f73f7fc35e6849ade53b2fb326219b.png" rel=""><img alt="Stack Overflow Developer Survey 2019.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50152" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b6034d4b18_StackOverflowDeveloperSurvey2019.png.04f73f7fc35e6849ade53b2fb326219b.png"></a>
</p>

<p>
	<a data-ss1614339168="1" href="https://insights.stackoverflow.com/survey/2019#technology" rel="external nofollow">المصدر</a>
</p>

<h2>
	كيف أتعلم SQL؟
</h2>

<p>
	قد تسأل: كيف أتعلم SQL؟ شبكة الإنترنت غنية بالكتب والمراجع والمقالات عن SQL باللغة الإنجليزية، للأسف، من الصعب أن تجد محتوى عربيا عالي الجودة لتعلم SQL، أو أيّ مجال تقني آخر.
</p>

<p>
	لمعالجة هذا الأمر وإثراء المكتبة العربية، أطلقت حسوب مشروعا لترجمة بعض أفضل الكتب التقنية في مجال البرمجة. ونظرا لأهمية SQL للمبرمجين، وحتى لغير المبرمجين من العاملين في القطاعات التقنية، كالصناعة والمحاسبة والصيرفة وتحليل البيانات، أو للمهتمين بقواعد البيانات عموما، قررنا ترجمة أحد أفضل الكتب الإنجليزية عن SQL، وهو كتاب <a data-ss1614339168="1" href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes For Professionals</a>. لقد نشرنا سلسلة تضمّ كافة فصول الكتاب، وهي معروضة في القسم التالي. يمكنك أيضًا تنزيل الكتاب جملة واحدة على هيئة كتاب إلكتروني اطلقنا عليه، <a data-ss1614339168="1" href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL</a>.
</p>
<style type="text/css">
@media screen and (min-width: 650px) {
.response_image {
    width: 33%;
    display: inline-block;
    vertical-align: top;
    margin-top: 0px;
}

.response_descrip {
    width: 64%;
    display: inline-block;
    margin-right: 10px;
    vertical-align: top;
    margin-top: 0px;
}
}</style>
<h2>
	سلسلة "SQL للمحترفين"
</h2>

<p>
	تغطي هذه السلسلة -المبنية على كتاب «<a data-ss1614339168="1" href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL</a>»- كافَّة المفاهيم الأساسية للغة SQL، مثل العمليات الأولية، كإدراج البيانات وحذفها واستخلاصها وتحديثها، وأنواع البيانات، وتصميم الجداول وتنفيذ الاستعلامات، إضافة إلى مفاهيم متقدمة، مثل المعارض والدوال، وإدارة المستخدمين، وكيفية تأمين الشيفرة وغيرها من المواضيع. كما أنّها غنية بالأمثلة التطبيقية التي تشرح كل هذه المواضيع لترسيخ فهمها.
</p>

<p>
	هذه السلسلة ليست مثل غيرها من السلاسل والشروحات التي تشرح لغة SQL من البداية شرحًا مُبسَّطًا ومتسلسلًا وإنَّما تعتمد على مبدأ خير الكلام ما قل ودل في الشرح وترك الشيفرة تشرح نفسها بنفسها، فتحوي على كم كبير من الشيفرات بالموازنة مع الشرح. وُجِّهت هذه السلسلة لمن لديه معرفة بسيطة بلغة SQL، لذا يفضَّل أن تمتلك معرفة بلغة SQL لتستفيد أكبر استفادة منها وتقرأ الشيفرات وتفهمها وتتعلَّم منها. في هذه الحالة، ستساهم هذه السلسلة في رفع مستواك في لغة SQL وستُملِّكك مهارات متقدمة في استعمال لغة SQL بالإضافة إلى بعض الخدع والالتفافات المتقدمة أيضًا. قد تسأل نفسك، هل ينفع أن اقرأ السلسلة دون معرفة مسبقة بلغة SQL؟ سأقول، نعم، ولكن يجب أن تتحلى بالصبر في قراءة الشيفرة وتحليلها وفهمها والبحث عن أي موضوع لم تفهمه والسؤال عن شرح لأي شيفرة غامضة، إذ لن تجد كلامًا وشرحًا كبيرًا للمواضع التي تتحدث عنه السلسلة، كما أن تسلسل المواضيع فيها لا تراعي عدم امتلاك القارئ معرفة بلغة SQL، إذ رُتِّبت ترتيبًا عشوائيًا في العمل الأصلي.
</p>

<p>
	بذكر ترتيب عناوين ومواضيع السلسلة، حاولت ترتيب عناوينها بأنسب شكل لتكون متدرِّجة في الصعوبة وحاولت جمع المواضيع المتشابهة في فصل واحد رغم تشرذمها وتفرقها في العمل الأصلي فلا تشبه النسخة العربية المترجمة النسخة الأجنبية مطلقًا، إذ حاولت أن تكون أفضل منها وأرجو أن نكون قد حققنا ذلك. فإن كنت على معرفة بأحد المواضيع، فلا تتخطاها بل اقرأها، فقد تمر معك إشارة لموضوع متقدم أو ملاحظة مهمة لم تكن تعرفها (تذكر أنَّ اسم الكتاب العربي <a data-ss1614339168="1" href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات متقدمة للعاملية بلغة SQL</a> ;-) ). يمكنك أيضًا أن تقرأ السلسلة من أي قسم تريد فهي من الأساس غير مُرتَّبة ترتيبًا متدرجًا ومتسلسلًا كما أشرت إلى ذلك، رغم محاولتي في ترتيبها لك أنسب ترتيب من البداية للنهاية؛ أرجو لك قراءة ممتعة!
</p>

<h3>
	1. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/" rel="">مدخل إلى SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50153" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/1.jpg.0cc109b6efb4108820109c2d7dce2a84.jpg" rel=""><img alt="1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50153" data-unique="iodjj5xur" src="https://academy.hsoub.com/uploads/monthly_2020_08/1.thumb.jpg.e70f627bc02fbf31008b84d3234a56c2.jpg"></a>
</p>

<p class="response_descrip">
	هذه المقالة هي مدخل عام إلى لغة الاستعلامات SQL، وفيها توطئة لبعض المفاهيم الأساسية لهذه اللغة، مثل المعرّفات و أنواع البيانات، كالأعداد والحروف والقيم المالية، إضافة إلى مجموعة من الأمثلة العملية على بعض الجداول وقواعد البيانات.
</p>

<h3>
	2. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">جلب الاستعلامات عبر SELECT في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50154" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/2.jpg.89b5f5e65d472f557f35c392e24be844.jpg" rel=""><img alt="2.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50154" data-unique="2ueumh2w2" src="https://academy.hsoub.com/uploads/monthly_2020_08/2.thumb.jpg.df02e8a0127d4b4c6e3cb7daf3333c92.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة كيفية استخدَام العبارة SELECT في استعلامات SQL لاختيار واستخلاص النتائج من قاعدة البيانات، تشمل هذه الفقرة العديد من تقنيات الاختيار، مثل حرف البدل والاختيار وفق كُنى الأعمدة، وتحديد عدد السجلات المُختارة والاختيار الشرطي، والاختيار باستخدام الدوال التجميعية، واختيار صفوف من عدة جداول.
</p>

<h3>
	3. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D9%81%D9%8A-sql-r846/" rel="">التجميع والترتيب في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50155" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/3.jpg.6113936a3e6d9ddc220ca2a088c8f9ed.jpg" rel=""><img alt="3.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50155" data-unique="133p2q4yy" src="https://academy.hsoub.com/uploads/monthly_2020_08/3.thumb.jpg.ca67b8bf16856359329b8589d52b29c1.jpg"></a>
</p>

<p class="response_descrip">
	تتحدث هذه المقالة عن كيفية استخدام العبارتين <code>GROUP BY</code> و <code>ORDER BY</code> لتجميع نتائج الاستعلامات في SQL وترتيبها. إضافة إلى التقنيات المُستخدمة لتصنيف النتائج وفق شروط معينة، وعدّ الصفوف في الجدول، والتنقيب عن البيانات أو ترتيبها بحسب عدة أعمدة.
</p>

<h3>
	4. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%AA%D8%B9%D9%84%D9%8A%D9%85%D8%A7%D8%AA-%D8%B4%D8%B1%D8%B7%D9%8A%D8%A9-%D8%B9%D8%A8%D8%B1-case-%D9%81%D9%8A-sql-r847/" rel="">تنفيذ تعليمات شرطية عبر CASE في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50156" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/4.jpg.119d168743a53a3f1606001b311d9989.jpg" rel=""><img alt="4.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50156" data-unique="8m87azt1c" src="https://academy.hsoub.com/uploads/monthly_2020_08/4.thumb.jpg.177a53a9bf9462806be67c59f17702bf.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة العبارة <code>CASE</code>، والتي تُستخدم لكتابة الشيفرات الشرطية (if-then)، وعد الصفوف التي تحقق شرطا معينا، إضافة إلى كيفية استخدام CASE لتحديث البيانات، أو ترتيبها تصاعديا أو تنازليا.
</p>

<h3>
	5. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D9%88%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%8A%D8%A8-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%B4%D9%8A%D8%AD-%D9%81%D9%8A-sql-r848/" rel="">البحث والتنقيب والترشيح في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50157" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/5.jpg.282de72b736f1b60e6f406871f19c12e.jpg" rel=""><img alt="5.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50157" data-unique="1lk3z23kz" src="https://academy.hsoub.com/uploads/monthly_2020_08/5.thumb.jpg.75fb36bfa1bb13afe3e6bead61ea5139.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة بعض معاملات SQL المتخصصة في البحث والتنقيب وترشيح النتائج، مثل المعامل LIKE، الذي يبحث عن التطابقات مع نمط نصي معين، و WHERE و HAVING، اللتان تُستخدمان لترشيح النتائج وفق شروط معينة، إضافة إلى بعض تقنيات التحكم في النتائج المُعادة، واستعراض بعض البيانات الوصفية المتعلقة بالاستعلامات.
</p>

<h3>
	6. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">الدمج بين الجداول في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50158" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/6.jpg.41b14581a0893c8944ed6fade9cb8597.jpg" rel=""><img alt="6.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50158" data-unique="kq0zm9soj" src="https://academy.hsoub.com/uploads/monthly_2020_08/6.thumb.jpg.bf75fa34550ec93b6ae5d1b94c364aa1.jpg"></a>
</p>

<p class="response_descrip">
	سنستعرض في هذه المقالة كيفية استخدام العبارة <code>JOIN</code>، وأنواعها، وكيفية إجراء الدمج العودي والدمج في الاستعلامات الفرعية، وذلك كله من أجل إجراء عملية الدمج بين الجداول والحصول على النتائج المرجوة.
</p>

<h3>
	7. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/" rel="">تحديث الجداول في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50159" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/7.jpg.5181ff363bdbd4a100a2d26741b3dcf4.jpg" rel=""><img alt="7.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50159" data-unique="83mv7u4xt" src="https://academy.hsoub.com/uploads/monthly_2020_08/7.thumb.jpg.69f11395701df6b8f56ed975d8bfb37e.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة كيفية استخدام العبارات UPDATE و CREATE لتحديث وإنشاء قواعد البيانات والجداول، إضافة إلى كيفية إنشاء دوال جديدة.
</p>

<h3>
	8. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">معالجة الأخطاء والتعديل على قواعد البيانات في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50160" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/8.jpg.de4cb2e8b4b25de62671f9387fd364ba.jpg" rel=""><img alt="8.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50160" data-unique="k1dbvjfcr" src="https://academy.hsoub.com/uploads/monthly_2020_08/8.thumb.jpg.959746243990ba5af0a31da95afb96b4.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة كيفية معالجة الأخطاء باستخدام العبارة TRY / CATCH، وكيفية حساب الاتحاد (UNION) وبعض العمليات الأخرى التي تمكّن من تعديل قواعد البيانات، وإدراج بيانات جديدة في الجداول
</p>

<h3>
	9. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/" rel="">حذف الجداول وقواعد البيانات في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50161" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/9.jpg.c1dd51f4cb27f2d01d56b4b07391c915.jpg" rel=""><img alt="9.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50161" data-unique="w9ojizvss" src="https://academy.hsoub.com/uploads/monthly_2020_08/9.thumb.jpg.e95b7f849af94ace20ae8a61e2e4e890.jpg"></a>
</p>

<p class="response_descrip">
	تتحدّث هذه المقالة عن كيفية حذف الجداول وقواعد البيانات (DROP و DELETE)، واقتطاع الجداول (TRUNCATE TABLE)، وكيفية استخدام الحذف المتفشي أو المتسلسل (Cascading Delete) في SQL.
</p>

<h3>
	10. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-sql-r853/" rel="">مواضيع متقدمة في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50162" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/10.jpg.d36822fc9595b78f1967d8da30171c00.jpg" rel=""><img alt="10.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50162" data-unique="qg57ceu67" src="https://academy.hsoub.com/uploads/monthly_2020_08/10.thumb.jpg.527dd16312c36719374a514b6f660ba0.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة عددًا من المواضيع المتقدمة في SQL، مثل إدارة صلاحيات المستخدمين، واستخدام ملفات XML في الاستعلامات، والمفاتيح الرئيسية وأرقام الصفوف، إضافة إلى مفهوم الفهارس، وكيفية إنشائها أو حذفها وتعطيلها.
</p>

<h3>
	11. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r855/" rel="">دوال التعامل مع البيانات في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50163" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/11.jpg.33c3e9cee7a7f3fc3fe623dfcc7ae801.jpg" rel=""><img alt="11.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50163" data-unique="666v2l431" src="https://academy.hsoub.com/uploads/monthly_2020_08/11.thumb.jpg.20c6217bfe945e1290fa595b26812475.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة بعض أنواع الدوال، مثل الدوال التجميعية (Aggregate Functions) التي تُطبَّق على الصفوف، والدوال التحليلية (Analytic Functions) والدوال العددية ودوال النافذة (window function).
</p>

<h3>
	12. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-sql-r854/" rel="">دوال التعامل مع النصوص في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50164" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/12.jpg.17e6fa9e672234b08755ebe4e54869fc.jpg" rel=""><img alt="12.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50164" data-unique="cwax1m5ky" src="https://academy.hsoub.com/uploads/monthly_2020_08/12.thumb.jpg.06f66734434b97784eb59983484f01c8.jpg"></a>
</p>

<p class="response_descrip">
	 تستعرض هذه المقالة مفهوم الدوال النصية String Functions، وهي دوال تُنفَّذ على قيم نصية، وتعيد إمّا قيمًا عددية أو قيمًا نصية. مثلًا، يمكن استخدام الدوال النصية لدمج البيانات، أو استخراج أجزاء من السلاسل النصية، أو موازنة السلاسل النصية أو تحويلها من الأحرف الكبيرة إلى الصغيرة، أو العكس.
</p>

<h3>
	13. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D8%AC%D8%AF%D9%88%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-common-table-expressions-%D9%81%D9%8A-sql-r856/" rel="">التعبيرات الجدولية الشائعة Common Table Expressions</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50165" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/13.jpg.64c1924248f55c70686777a35e220bee.jpg" rel=""><img alt="13.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50165" data-unique="pxndaq2te" src="https://academy.hsoub.com/uploads/monthly_2020_08/13.thumb.jpg.b989347fabdd26c67376198541a06906.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة مفهوم التعبيرات الجدولية (Common Table Expressions) في SQL، والتي يمكن استخدامها مع الاستعلامات المؤقتة والعوديّة لتوليد سلاسل القيم وتسلق الأشجار (trees).
</p>

<h3>
	14. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%81%D8%B1%D9%82%D8%A9-%D9%81%D9%8A-sql-r857/" rel="">مواضيع متفرقة في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50166" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/14.jpg.0590dd06489a784c3c504945872f01b5.jpg" rel=""><img alt="14.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50166" data-unique="cu0mos2ja" src="https://academy.hsoub.com/uploads/monthly_2020_08/14.thumb.jpg.a0e9cbaff8dd3ce715db96f87d320611.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة مجموعة من المواضيع الإضافية في SQL، مثل المعارض (Views)، وكيفية كتابة التعليقات، وكيفية التعامل مع المفاتيح الخارجية (Foreign Keys) وإنشاء تسلسلات العناصر.
</p>

<h3>
	15. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">الاستعلامات الفرعية والإجراءات في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50167" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/15.jpg.fd71120520baacd206ba7a1a7d895653.jpg" rel=""><img alt="15.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50167" data-unique="h6x6m5ju4" src="https://academy.hsoub.com/uploads/monthly_2020_08/15.thumb.jpg.521aface4519ee7ee6b1652f00fb9f54.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة بعض المواضيع المتقدمة عن تنفيذ الشيفرات في SQL، مثل الاستعلامات الفرعية (Subqueries)، وكتل التنفيذ، والإجراءات المُخزّنة، والزنادات (triggers)، وكيفية إنشاء المُعامَلات (transactions) وتنفيذها.
</p>

<h3>
	16. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول وترتيب تنفيذ الاستعلامات ومعلومات المخطط في SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50168" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/16.jpg.42b1504928a0e93071f8c74011beb64d.jpg" rel=""><img alt="16.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50168" data-unique="jolbawaz5" src="https://academy.hsoub.com/uploads/monthly_2020_08/16.thumb.jpg.bebffa09ee107ffad665ff63ba7b0840.jpg"></a>
</p>

<p class="response_descrip">
	تستعرض هذه المقالة عددا من مواضيع SQL المتفرقة، مثل كيفية تصميم جداول قواعد البيانات، واستخدام المرادفات، وكيفية استخلاص المعلومات المتعلقة بقاعدة البيانات عبر معلومات المخطط، والترتيب الذي تُنفّذ وفقه عبارات واستعلامات SQL التي من المفيد تعلمها والإلمام بها.
</p>

<h3>
	17. <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D8%B8%D9%8A%D9%85-%D8%B4%D9%8A%D9%81%D8%B1%D8%A7%D8%AA-sql-%D9%88%D8%AA%D8%A3%D9%85%D9%8A%D9%86%D9%87%D8%A7-r860/" rel="">تنظيم وتأمين شيفرات SQL</a>
</h3>

<p class="response_image">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="50169" data-ss1614339168="1" href="https://academy.hsoub.com/uploads/monthly_2020_08/17.jpg.1829ea6e84721c14bf3e4532c93572fd.jpg" rel=""><img alt="17.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="50169" data-unique="98qbashvl" src="https://academy.hsoub.com/uploads/monthly_2020_08/17.thumb.jpg.d724eed4a019fde7fe0fed5dced0a68a.jpg"></a>
</p>

<p class="response_descrip">
	تتحدث هذه المقالة عن أفضل الممارسات المُتعارف عليها بين المبرمجين، والتي تساعد على كتابة شيفرات SQL نظيفة وعالية المقروئية، وكذلك تأمين الشيفرات عبر التحوّط من أحد أشهر أنواع هجمات SQL، وهو حقن شيفرات SQL ‏(SQL Injection)‏‏.
</p>

<h2>
	دروس ومقالات إضافية
</h2>

<p>
	هذه بعض المقالات الإضافية التي يمكن أن تساعدك على ترسيخ فهمك لبعض مفاهيم SQL وقواعد البيانات.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r584/" rel="">مقدمة عن قواعد البيانات</a>
</h3>

<p class="response_image">
	<img alt="مقدمة-عن-قواعد-البيانات.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50177" data-unique="odllj8dke" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b64659c81d_---.png.32a8692e2d133101c9c5556f0219febd.png"></p>

<p class="response_descrip">
	هذا هو المقال الأول من سلسلة دروس عن لغة الاستعلام البنائية Structured Query language، ويشرح مفهوم قواعد البيانات، وأنظمة إدارة قواعد البيانات، والجداول، وخصائص قواعد البيانات العلاقية.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D9%91%D8%A7%D8%AA-%D9%84%D8%BA%D8%A9-sql-r585/" rel="">أساسيّات لغة SQL</a>
</h3>

<p class="response_image">
	<img alt="أساسيات-لغة-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50176" data-unique="d82qukpys" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b64464ab8e_--SQL.png.31cfdb9fe472dd67d748aa98cd880b77.png"></p>

<p class="response_descrip">
	يعطي هذا المقال لمحة عامة عن لغة الاستعلامات SQL، وعن دورها وعلاقتها بقاعدة البيانات، مع شرح أساسيات وصياغة قواعد البيانات والجداول.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-%D9%88%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D8%B9%D9%84%D9%8A%D9%87%D8%A7-r586/" rel="">البيانات في SQL</a><a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-%D9%88%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D8%B9%D9%84%D9%8A%D9%87%D8%A7-r586/" rel="">: أنواعها والقيود عليها</a>
</h3>

<p class="response_image">
	<img alt="البيانات-في-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50175" data-unique="yoyd09cd6" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b64386f953_--SQL.png.a304cf216dbb5992be498f5a521e404e.png"></p>

<p class="response_descrip">
	يتطرق هذا المقال لأحد المفاهيم الأساسية في قواعد البيانات وفي لغة الاستعلامات SQL، وهو مفهوم القيود، إذ يعرض هذا المفهوم مع أمثلة عملية لتوضيحه. إضافة إلى عرض مفصَّل لمختلف أنواع البيانات المُستخدمة في قواعد البيانات.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%D8%8C-%D8%A7%D9%84%D8%AD%D8%B0%D9%81-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D9%81%D9%8A-sql-r587/" rel="">التعامل مع البيانات (الإدخال، الحذف والتعديل) في SQL</a>
</h3>

<p class="response_image">
	<img alt="التعامل-مع-البيانات-في-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50174" data-unique="c1mfglj5l" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b643139a14_----SQL.png.afa4fe77fa840a67335226be08d7f3a6.png"></p>

<p class="response_descrip">
	يشرح هذا المقال موضوع لغة التعامل مع البيانات Data Manipulation Language، سوف تملك في نهاية هذا المقال المعرفة اللازمة لإضافة سجلات بيانات إلى الجداول، وتعديلها، وحذفها باستخدام عبارات SQL الأساسية، مثل: UPDATE وINSERT وDELETE.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r588/" rel="">الاستعلام عن البيانات في SQL</a>
</h3>

<p class="response_image">
	<img alt="الاستعلام-عن-البيانات-في-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50173" data-unique="a23rtdg24" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b642a8fcc1_----SQL.png.a19585a76111d1ab9aec72f4a45f4a65.png"></p>

<p class="response_descrip">
	هذا المقال تتمة للمقال السابق، ستتعلم فيه إحدى أشهر عبارات لغة الاستعلام البنائية، وهي Select، يتكلم المقال عن كيفية صياغة هذه العبارة، وأشكالها، وكيفية ترشيح البيانات واختيار الأعمدة.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%81%D9%87%D8%A7%D8%B1%D8%B3-indexes-%D9%81%D9%8A-sql-r589/" rel="">الفهارس Indexes في SQL</a>
</h3>

<p class="response_image">
	<img alt="الفهارس-Indexes-في-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50172" data-unique="zxmos0mer" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b642505334_-Indexes--SQL.png.51195906370442db9fddefe7850475db.png"></p>

<p class="response_descrip">
	يتناول هذا المقال موضوع الفهارس Indexes في SQL، وما تمثله في قاعدة البيانات، وما هي الفائدة منها، وكيفية استخدامها في شيفرات SQL.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r590/" rel="">العلاقات بين الجداول في SQL</a>
</h3>

<p class="response_image">
	<img alt="العلاقات-بين-الجداول-في-SQL.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50171" data-unique="zjmm4g2px" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b641c7cbf4_----SQL.png.b703f79a013f49a3c32d90633a16d862.png"></p>

<p class="response_descrip">
	SQL مُتخصَّصة أساسًا في قواعد البيانات العلائقية، لهذا فإنّ فهم موضوع العلاقات بين الجداول ضروري لكل مبرمج يريد احتراف هذه اللغة واستنفاذ إمكانياتها. ستتعلم في هذا المقال مفهوم العلاقات بين جداول قاعدة البيانات، وأنواع هذه العلاقات، وكيف تُمثَّل وتطبق بين الجداول.
</p>

<h3>
	<a data-ss1614339168="1" href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-sql-%D8%A8%D8%A7%D9%84%D8%A3%D9%85%D8%AB%D9%84%D8%A9-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A9-r637/" rel="">تعلم لغة الاستعلام SQL بالأمثلة العملية</a>
</h3>

<p class="response_image">
	<img alt="تعلم-لغة-الاستعلام-SQL-بالأمثلة-العملية.png" class="ipsImage ipsImage_thumbnailed" data-fileid="50170" data-unique="sm98qxei0" src="https://academy.hsoub.com/uploads/monthly_2020_08/5f3b641581ce3_---SQL--.png.6701262d830fa72ba9b367457310216a.png"></p>

<p class="response_descrip">
	أفضل طريقة لتعلم أيّ لغة برمجة هي بتطبيق المعارف على أمثلة عملية. يشرح هذا الدرس المُصوّر أساسيات لغة الاستعلامات SQL عبر أمثلة عملية، وذلك باستخدام لوحة التحكم phpMyAdmin.
</p>

<h2>
	خاتمة
</h2>

<p>
	تُضاف مزيد من المقالات والدروس إلى الأكاديمية حول SQL‎ وقواعد البيانات باستمرار، لذلك تابع مستجدات أكاديمية حسوب. وإن أشكل عليك شيء فيمكنك أن تسأل عنه في <a data-ss1614339168="1" href="https://academy.hsoub.com/questions/c3-programming/" rel="">قسم الأسئلة والأجوبة</a> الخاص بالأكاديمية. يمكنك أيضا الاشتراك في <a data-ss1614339168="1" href="https://www.youtube.com/channel/UCJv37tcBvJlBF2MoVMRMvbQ" rel="external nofollow">قناة حسوب على اليوتوب</a>، هذه القناة تحتوي دروسًا قصيرةً عن العديد من مواضيع البرمجة. تابع أيضًا قسم <a data-ss1614339168="1" href="https://academy.hsoub.com/files/" rel="">الكتب والملفات</a> للاطلاع على أحد الكتب التي ننشرها.
</p>

<p>
	إن كنت مهتما بتعلم لغات برمجة أخرى، فيمكنك زيارة قسم <a data-ss1614339168="1" href="https://academy.hsoub.com/programming/" rel="">البرمجة</a> في الأكاديمية، أيضًا لا تنس زيارة <a data-ss1614339168="1" href="https://wiki.hsoub.com" rel="external">موسوعة حسوب</a>، التي تضم توثيقات الكثير من لغات البرمجة، بما في ذلك <a data-ss1614339168="1" href="https://wiki.hsoub.com/SQL" rel="external">توثيق SQL</a>. وفّقك الله تعالى.
</p>
]]></description><guid isPermaLink="false">961</guid><pubDate>Thu, 20 Aug 2020 13:03:00 +0000</pubDate></item><item><title>&#x62A;&#x646;&#x638;&#x64A;&#x645; &#x634;&#x64A;&#x641;&#x631;&#x627;&#x62A; SQL &#x648;&#x62A;&#x623;&#x645;&#x64A;&#x646;&#x647;&#x627;</title><link>https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D8%B8%D9%8A%D9%85-%D8%B4%D9%8A%D9%81%D8%B1%D8%A7%D8%AA-sql-%D9%88%D8%AA%D8%A3%D9%85%D9%8A%D9%86%D9%87%D8%A7-r860/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/17.jpg.ffb35ee817589c9068e9d14f196e6f07.jpg" /></p>

<p>
	تستعرض هذه المقالة أفضل الممارسات المُتعارف عليها لكتابة شيفرات SQL نظيفة، وكذلك تأمين الشيفرات عبر التحوّط من هجمات حقن SQL.
</p>

<h2>
	الشيفرات البرمجية النظيفة في SQL
</h2>

<p>
	هذه بعض النصائح والقواعد حول كيفية كتابة استعلامات SQL تراعي أفضل الممارسات، وذات مقروئية عالية.
</p>

<h3>
	تنسيق وتهجئة الكلمات المفتاحية والأسماء
</h3>

<h4>
	أسماء الجداول والأعمدة
</h4>

<p>
	هناك طريقتان شائعتان لكتابة أسماء الجداول والأعمدة، وهما <code>‎CamelCase‎</code> و <code>‎snake_case‎</code> كما يوضح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_7" style="">
<span class="pln">SELECT </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">Salary</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">500</span><span class="pun">;</span><span class="pln">
SELECT first_name</span><span class="pun">,</span><span class="pln"> last_name
FROM employees
WHERE salary </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">500</span><span class="pun">;</span></pre>

<p>
	يجب أن تعطي الأسماء فكرة عمّا هو مُخزّن في الكائن المُسمّى. هناك <a href="https://stackoverflow.com/questions/338156/table-naming-dilemma-singular-vs-plural-names" rel="external nofollow">نقاش محتدم</a> حول ما إذا كان الأفضل أن تكون أسماء الجداول بصيغة المفرد أو الجمع، ولكنّ الشائع استخدام صيغة الجمع.
</p>

<p>
	تُنقِص إضافة سابقات أو لاحقات، مثل <code>‎tbl‎</code> أو <code>‎col‎</code>، إلى الأسماء مقروئية الشيفرة، لذلك يُفضل تجنبها. إلا أنّها قد تكون ضرورية في بعض الأحيان لتجنّب التداخل مع الكلمات المفتاحية في SQL، وغالبًا ما تُستخدم مع الزنادات (triggers) والفهارس (والتي لا تُذكر أسماؤها في الاستعلامات عادةً).
</p>

<h4>
	الكلمات المفتاحية
</h4>

<p>
	الكلمات المفتاحية في SQL ليست حسّاسة لحالة الأحرف. ولكن تغلُب كتابتها بأحرف كبيرة.
</p>

<h3>
	المسافات البادئة Indenting
</h3>

<p>
	لا يوجد معيار مقبول ومُوحّد للمسافات البادئة. لكنّ الجميع يتفق على أنّ حشر كل شيء في سطر واحد أمر سيء مثل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_9" style="">
<span class="pln">SELECT d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> COUNT</span><span class="pun">(*)</span><span class="pln"> AS </span><span class="typ">Employees</span><span class="pln"> FROM </span><span class="typ">Departments</span><span class="pln"> AS d JOIN </span><span class="typ">Employees</span><span class="pln"> AS e ON d</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln">
e</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> WHERE d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'HR'</span><span class="pln"> HAVING COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> ORDER BY COUNT</span><span class="pun">(*)</span><span class="pln"> DESC</span><span class="pun">;</span></pre>

<p>
	أضعف الإيمان أن تضع كل عبارة في سطر جديد، مع تقسيم السطور الطويلة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_11" style="">
<span class="pln">SELECT d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
 COUNT</span><span class="pun">(*)</span><span class="pln"> AS </span><span class="typ">Employees</span><span class="pln">
FROM </span><span class="typ">Departments</span><span class="pln"> AS d
JOIN </span><span class="typ">Employees</span><span class="pln"> AS e ON d</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
WHERE d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'HR'</span><span class="pln">
HAVING COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln">
ORDER BY COUNT</span><span class="pun">(*)</span><span class="pln"> DESC</span><span class="pun">;</span></pre>

<p>
	في بعض الأحيان، تُوضع نفس المسافة البادئة قبل الأسطر التي تعقُب الكلمات المفتاحية في SQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_13" style="">
<span class="pln">SELECT   d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
 COUNT</span><span class="pun">(*)</span><span class="pln"> AS </span><span class="typ">Employees</span><span class="pln">
FROM     </span><span class="typ">Departments</span><span class="pln"> AS d
JOIN     </span><span class="typ">Employees</span><span class="pln"> AS e ON d</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
WHERE    d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'HR'</span><span class="pln">
HAVING COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln">
ORDER BY COUNT</span><span class="pun">(*)</span><span class="pln"> DESC</span><span class="pun">;</span></pre>

<p>
	(يمكن القيام بذلك أيضًا عند محاذاة الكلمات المفتاحية في SQL إلى اليمين.)
</p>

<p>
	هناك طريقة شائعة أخرى، وهي وضع الكلمات المفتاحية المهمّة في سطور خاصّة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_15" style="">
<span class="pln">SELECT
    d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
 COUNT</span><span class="pun">(*)</span><span class="pln"> AS </span><span class="typ">Employees</span><span class="pln">
FROM
    </span><span class="typ">Departments</span><span class="pln"> AS d
JOIN
    </span><span class="typ">Employees</span><span class="pln"> AS e
 ON d</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
WHERE
    d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'HR'</span><span class="pln">
HAVING
    COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln">
ORDER BY
    COUNT</span><span class="pun">(*)</span><span class="pln"> DESC</span><span class="pun">;</span></pre>

<p>
	تُحسّن المحاذاة الرأسية للعبارات المتماثلة مقروئية الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_17" style="">
<span class="pln">SELECT </span><span class="typ">Model</span><span class="pun">,</span><span class="pln">
       </span><span class="typ">EmployeeID</span><span class="pln">
FROM </span><span class="typ">Cars</span><span class="pln">
WHERE </span><span class="typ">CustomerID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">42</span><span class="pln">
   AND </span><span class="typ">Status</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span><span class="pun">;</span></pre>

<p>
	استخدام عدّة أسطر يصعّب تضمين أوامر SQL في لغات البرمجة الأخرى. إلا أنّ العديد من اللغات لديها آلية للتعامل مع السلاسل النصية متعددة الأسطر، مثل <code>‎@"..."‎</code> في C#‎‎ أو <code>‎"""..."""‎</code> في Python أو <code>‎R"(...)"‎</code> في C++‎‎‎.
</p>

<h3>
	SELECT *‎‎
</h3>

<p>
	تعيد العبارة <code>‎SELECT *‎</code> جميع الأعمدة بنفس ترتيب ظهورها في الجدول. عند استخدام <code>‎SELECT *‎</code>، فقد تتغيّر البيانات المُعادة من الاستعلام كلّما تغيّر تعريف الجدول. وهذا يضعف توافقية الإصدارات المختلفة من التطبيق أو قاعدة البيانات مع بعضها بعضًا.
</p>

<p>
	علاوة على ذلك، فإنّ قراءة الأعمدة غير الضرورية قد يرفع من مساحة القرص المُستخدَمة، والدخل / الخرج الشبكي (network I/O). لذا عليك دائمًا تحديد العمود (أو الأعمدة) الذي تريد استردادها صراحة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_22" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">                              </span><span class="pun">--</span><span class="pln">  </span><span class="pun">تجنّب</span><span class="pln"> </span><span class="pun">هذا</span><span class="pln">
SELECT ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pln">  </span><span class="pun">--</span><span class="pln"> </span><span class="pun">هذا</span><span class="pln"> </span><span class="pun">أفضل</span><span class="pln">
FROM </span><span class="typ">Emplopees</span><span class="pun">;</span></pre>

<p>
	(لا تنطبق هذه الاعتبارات عند إجراء استعلامات تفاعلية - interactive queries.)
</p>

<p>
	بالمقابل، ليس هناك ضرر من استخدام <code>‎SELECT *‎</code> في استعلام فرعي لعبارة <code>EXISTS</code>، ذلك أنّ <code>EXISTS</code> تتجاهل البيانات الفعلية على أيّ حال (إذ تكتفي بالتحقق من أنّه تمّ العثور على صفّ واحد على الأقل). للسبب نفسه، لا فائدة من إدراج أيّ عمود (أو أعمدة) معيّنة في عبارة <code>EXISTS</code>، لذلك يُفضّل استخدام <code>‎SELECT *‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_24" style="">
<span class="pun">--</span><span class="pln"> </span><span class="pun">سرد</span><span class="pln"> </span><span class="pun">الأقسام</span><span class="pln"> </span><span class="pun">التي</span><span class="pln"> </span><span class="pun">لم</span><span class="pln"> </span><span class="pun">يُعيّن</span><span class="pln"> </span><span class="pun">فيها</span><span class="pln"> </span><span class="pun">أيّ</span><span class="pln"> </span><span class="pun">موظف</span><span class="pln"> </span><span class="pun">حديثا</span><span class="pln">
SELECT ID</span><span class="pun">,</span><span class="pln">
       </span><span class="typ">Name</span><span class="pln">
FROM </span><span class="typ">Departments</span><span class="pln">
WHERE NOT EXISTS </span><span class="pun">(</span><span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
 FROM </span><span class="typ">Employees</span><span class="pln">
 WHERE </span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Departments</span><span class="pun">.</span><span class="pln">ID
 AND </span><span class="typ">HireDate</span><span class="pln"> </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="str">'2015-01-01'</span><span class="pun">);</span></pre>

<h3>
	عمليات الضمّ Joins
</h3>

<p>
	يجب دائمًا استخدام عمليات الضمّ الصريحة (Explicit joins)؛ لأنّ عمليات الضمّ الضمنية (implicit joins) تطرح العديد من المشاكل، مثلًا:
</p>

<ul>
<li>
		في عمليات الضمّ الضمنية، يكون شرط الضمّ داخل عبارة <code>WHERE</code> مخلوطًا مع شروط أخرى. وذلك يصعّب معرفة الجداول المضمومة، وكيفية ضمّها.
	</li>
	<li>
		بسبب النقطة أعلاه، يتعاظم خطر حدوث أخطاء.
	</li>
	<li>
		في SQL القياسية، عمليات الضمّ الصريحة هي الطريقة الوحيدة لاستخدام الضمّ الخارجي:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_26" style="">
<span class="pln">SELECT d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
e</span><span class="pun">.</span><span class="typ">Fname</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">LName</span><span class="pln"> AS </span><span class="typ">EmpName</span><span class="pln">
FROM </span><span class="typ">Departments</span><span class="pln"> AS d
LEFT JOIN </span><span class="typ">Employees</span><span class="pln"> AS e ON d</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pun">;</span></pre>

<ul>
<li>
		يتيح الضمّ الصريح استخدام عبارة <code>USING</code> كما يوضّح المثال التالي:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_28" style="">
<span class="pln">SELECT </span><span class="typ">RecipeID</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Recipes</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
COUNT</span><span class="pun">(*)</span><span class="pln"> AS </span><span class="typ">NumberOfIngredients</span><span class="pln">
FROM </span><span class="typ">Recipes</span><span class="pln">
LEFT JOIN </span><span class="typ">Ingredients</span><span class="pln"> USING </span><span class="pun">(</span><span class="typ">RecipeID</span><span class="pun">);</span></pre>

<p>
	(يتطلب هذا أن يستخدم كلا الجدولين اسم العمود نفسه. تزيل <code>USING</code> تلقائيًا العمود المكرّر من النتيجة، وهكذا سيُعيد الضم في الاستعلام أعلاه عمودًا <code>‎RecipeID‎</code> واحدا.)
</p>

<h2>
	حقن SQL
</h2>

<p>
	حقن SQL هي تقنية يستخدمها القراصنة للوصول إلى جداول قاعدة بيانات موقع معيّن عن طريق حقن تعليمات SQL في حقل إدخال.
</p>

<p>
	إذا لم يكن خادم الويب مُجهّزا للتعامل مع هجمات حقن SQL، فيمكن للمخترقين خداع قاعدة البيانات، وجعلها تنفّذ شيفرة SQL إضافية. والتي قد تمكّنهم من ترقية صلاحيات حساباتهم، أو الوصول إلى المعلومات الشخصية لحساب آخر، أو إجراء أيّ تعديلات أخرى على قاعدة البيانات.
</p>

<p>
	لنفترض أنّ استدعاء معالج تسجيل الدخول إلى موقعك يبدو كما يلي:
</p>

<pre class="ipsCode">
https://somepage.com/ajax/login.ashx?username=admin&amp;password=123
</pre>

<p>
	الآن في login.ashx، ستقرأ القيم التالية:
</p>

<pre class="ipsCode">
strUserName = getHttpsRequestParameterString("username");
strPassword = getHttpsRequestParameterString("password");
</pre>

<p>
	يمكنك استعلام قاعدة البيانات للتحقق ممّا إذا كان هناك مستخدم له كلمة المرور هذه. لذا ستنشئ استعلام SQL التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_31" style="">
<span class="pln">txtSQL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"SELECT * FROM Users WHERE username = '"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> strUserName </span><span class="pun">+</span><span class="pln"> </span><span class="str">"' AND password = '"</span><span class="pun">+</span><span class="pln"> strPassword </span><span class="pun">+</span><span class="str">"'"</span><span class="pun">;</span></pre>

<p>
	سيعمل هذا الاستعلام بلا مشاكل إذا لم يحتو اسم المستخدم وكلمة المرور على علامات اقتباس. ولكن إن احتوى أحد المعاملات على علامات اقتباس، فإنّ شيفرة SQL المُرسلة إلى قاعدة البيانات ستبدو كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_33" style="">
<span class="pun">--</span><span class="pln"> strUserName </span><span class="pun">=</span><span class="pln"> </span><span class="str">"d'Alambert"</span><span class="pun">;</span><span class="pln">
txtSQL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"SELECT * FROM Users WHERE username = 'd'Alambert' AND password = '123'"</span><span class="pun">;</span></pre>

<p>
	سينتج عن هذا خطأ في الصياغة، لأنّ علامة الاقتباس بعد <code>‎d‎</code> في <code>‎d'Alambert‎</code> تنتهي بشيفرة SQL.
</p>

<p>
	يمكنك تصحيح هذا عن طريق تهريب (escaping) علامات الاقتباس في اسم المستخدم وكلمة المرور على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_35" style="">
<span class="pln">strUserName </span><span class="pun">=</span><span class="pln"> strUserName</span><span class="pun">.</span><span class="typ">Replace</span><span class="pun">(</span><span class="str">"'"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"''"</span><span class="pun">);</span><span class="pln">
strPassword </span><span class="pun">=</span><span class="pln"> strPassword</span><span class="pun">.</span><span class="typ">Replace</span><span class="pun">(</span><span class="str">"'"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"''"</span><span class="pun">);</span></pre>

<p>
	هناك حلّ آخر أفضل، وهو استخدام المعاملات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_37" style="">
<span class="pln">cmd</span><span class="pun">.</span><span class="typ">CommandText</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"SELECT * FROM Users WHERE username = @username AND password = @password"</span><span class="pun">;</span><span class="pln">
cmd</span><span class="pun">.</span><span class="typ">Parameters</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="str">"@username"</span><span class="pun">,</span><span class="pln"> strUserName</span><span class="pun">);</span><span class="pln">
cmd</span><span class="pun">.</span><span class="typ">Parameters</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="str">"@password"</span><span class="pun">,</span><span class="pln"> strPassword</span><span class="pun">);</span></pre>

<p>
	إذا لم تستخدم المعاملات، ونسيت استبدال علامات الاقتباس ولو في قيمة واحدة، فيمكن للقرصان استخدام هذا لتنفيذ أوامر SQL في قاعدة البيانات الخاصة بك. على سبيل المثال، يمكن للقرصان أن يعيّن كلمة المرور التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_40" style="">
<span class="pln">lol</span><span class="str">'; DROP DATABASE master; --</span></pre>

<p>
	وبعدها ستبدو SQL كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_42" style="">
<span class="str">"SELECT * FROM Users WHERE username = 'somebody' AND password = 'lol'; DROP DATABASE master; --'"</span><span class="pun">;</span></pre>

<p>
	لسوء الحظ، هذه شيفرة SQL صحيحة، وستنفّذها قاعدة البيانات DB! هذا النوع من الهجمات يسمّى حقن SQL.
</p>

<p>
	هناك أشياء أخرى كثيرة يمكن أن يقوم بها القرصان، مثل سرقة عناوين البريد الإلكتروني الخاصة بالمستخدمين، أو سرقة كلمات المرور خاصتهم، أو سرقة أرقام بطاقات الائتمان، أو سرقة أيّ نوع من البيانات في قاعدة البيانات. لهذا السبب، عليك دائمًا تهريب السلاسل النصية.
</p>

<p>
	لمّا كان النسيان طبيعة في الإنسان، ينصح الكثيرون باستخدام المعاملات دائمًا. لأنّ إطارات لغة البرمجة المُستخدمة تتكفّل بتهريبها نيابة عنك.
</p>

<h3>
	مثال على حقن بسيط
</h3>

<p>
	إذا تم إنشاء عبارة SQL على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_44" style="">
<span class="pln">SQL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"SELECT * FROM Users WHERE username = '"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> user </span><span class="pun">+</span><span class="pln"> </span><span class="str">"' AND password ='"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> pw </span><span class="pun">+</span><span class="pln"> </span><span class="str">"'"</span><span class="pun">;</span><span class="pln"> 
db</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="pln">SQL</span><span class="pun">);</span></pre>

<p>
	سيكون بمقدور القرصان سرقة بياناتك عن طريق إعطاء كلمة مرور من هذا القبيل <code>‎pw' or '1'='1‎</code>؛ وهكذا تصبح عبارة SQL الناتجة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_46" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Users</span><span class="pln"> WHERE username </span><span class="pun">=</span><span class="pln"> </span><span class="str">'somebody'</span><span class="pln"> AND password </span><span class="pun">=</span><span class="str">'pw'</span><span class="pln"> </span><span class="kwd">or</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">=</span><span class="str">'1'</span></pre>

<p>
	العبارة <code>‎'1'='1'‎</code> صحيحة دائمًا، لذلك سيتم اختيار كل الصفوف. لمنع هذا، استخدم معاملات SQL على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4730_48" style="">
<span class="pln">SQL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"SELECT * FROM Users WHERE username = ? AND password = ?"</span><span class="pun">;</span><span class="pln">
db</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="pln">SQL</span><span class="pun">,</span><span class="pln"> </span><span class="pun">[</span><span class="pln">user</span><span class="pun">,</span><span class="pln"> pw</span><span class="pun">]);</span></pre>

<p>
	ترجمة -وبتصرّف- للفصلين من 61 إلى 62 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول ومعلومات المخطط وترتيب تنفيذ الاستعلامات في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">860</guid><pubDate>Wed, 13 May 2020 18:01:00 +0000</pubDate></item><item><title>&#x62A;&#x635;&#x645;&#x64A;&#x645; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x648;&#x645;&#x639;&#x644;&#x648;&#x645;&#x627;&#x62A; &#x627;&#x644;&#x645;&#x62E;&#x637;&#x637; &#x648;&#x62A;&#x631;&#x62A;&#x64A;&#x628; &#x62A;&#x646;&#x641;&#x64A;&#x630; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/16.jpg.4e2b4390615d6a4414055ae6d73d24d3.jpg" /></p>

<p>
	تستعرض هذه المقالة عددا من مواضيع SQL، مثل كيفية تصميم جداول قواعد البيانات، واستخدام المرادفات، وكيفية استخلاص المعلومات المتعلقة بقاعدة البيانات عبر معلومات المخطط، والترتيب الذي تُنفّذ وفقه عبارات واستعلامات SQL.
</p>

<h2>
	تصميم الجداول Table Design
</h2>

<p>
	لا تنحصر وظائف أنظمة قواعد البيانات العلائقية في عرض البيانات في الجداول، وكتابة عبارات SQL لسحب تلك البيانات.
</p>

<p>
	إن كان تصميم الجداول سيئًا، فقد يؤدي ذلك إلى إبطاء تنفيذ الاستعلامات، ويمكن أن يؤثر على عمل قاعدة البيانات، بحيث لا تعمل كما هو متوقع. لذا لا ينبغي النظر إلى جداول قاعدة البيانات كما لو كانت مجرد جداول عادية؛ إذ يتوجّب أن تتّبع مجموعة من القواعد حتى تكون علائقية حقًّا.
</p>

<p>
	هذه هي القواعد الخمسة التي ينبغي أن تتوفّر في أيّ جدول علائقي:
</p>

<ol>
<li>
		أن تكون كل القيم ذرّية (atomic)، أي يجب أن تكون قيمة كل حقل من كل صفّ قيمة واحدة.
	</li>
	<li>
		يجب أن تنتمي بيانات كل حقل إلى نفس نوع البيانات.
	</li>
	<li>
		يجب أن يكون لكل حقل اسمًا فريدًا.
	</li>
	<li>
		يجب أن يحتوي كل صفّ في الجدول على قيمة واحدة على الأقل تجعله متفرّدًا عن السجلات الأخرى في الجدول.
	</li>
	<li>
		لا ينبغي أن يكون لترتيب الصفوف والأعمدة أيّ تأثير.
	</li>
</ol>
<p>
	هذا مثال على جدول يتوافق مع القواعد الخمس أعلاه:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
			<th>
				DOB
			</th>
			<th>
				Manager
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				Fred
			</td>
			<td>
				11/02/1971
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Fred
			</td>
			<td>
				11/02/1971
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Sue
			</td>
			<td>
				08/07/1975
			</td>
			<td>
				2
			</td>
		</tr>
</tbody>
</table>
<p>
	لنتحقق من القواعد السابقة:
</p>

<ul>
<li>
		القاعدة 1: كل القيم ذرّية. إذ لا تحتوِي الحقول <code>‎Id‎</code> و <code>‎Name‎</code> و <code>‎DOB‎</code> و <code>‎Manager‎</code> إلّا قيمًا مُنفردة (single) فقط.
	</li>
	<li>
		القاعدة 2: لا يحتوي الحقل <code>‎Id‎</code> إلّا على الأعداد الصحيحة، فيما يحتوي الحقل <code>‎Name‎</code> حصرًا على القيم النصية (يمكننا إضافة أنها جميعًا تتألف من أربعة أحرف أو أقل)، فيما يحتوي الحقل <code>‎DOB‎</code> على تواريخ من نوع صالح، ويحتوي الحقل <code>‎Manager‎</code> على أعداد صحيحة (يمكننا إضافة أنّها تتوافق مع حقل المفاتيح الرئيسية في جدول المدراء managers).
	</li>
	<li>
		القاعدة 3: <code>‎Id‎</code> و <code>‎Name‎</code> و <code>‎DOB‎</code> و <code>‎Manager‎</code> هي أسماء عناوين فريدة للحقول داخل الجدول.
	</li>
	<li>
		القاعدة 4: يميّز الحقل <code>‎Id‎</code> كلّ السجلّات، ويجعل كلّ سجلّ مختلفًا عن السجلات الأخرى داخل الجدول.
	</li>
</ul>
<p>
	هذا مثال على جدول ذي تصميم سيء:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
			<th>
				DOB
			</th>
			<th>
				Name
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				Fred
			</td>
			<td>
				11/02/1971
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				Fred
			</td>
			<td>
				11/02/1971
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Sue
			</td>
			<td>
				Friday the 18th July 1975
			</td>
			<td>
				2, 1
			</td>
		</tr>
</tbody>
</table>
<p>
	لنتحقق من القواعد السابقة:
</p>

<ul>
<li>
		القاعدة 1: يحتوي الحقل الثاني على قيمتين، 2 و 1.
	</li>
	<li>
		القاعدة 2: يحتوي الحقل <code>DOB</code> على نوعي بيانات مختلفين، نوع التاريخ، ونوع النصوص.
	</li>
	<li>
		القاعدة 3: هناك حقلان لهما الاسم نفسه ("name").
	</li>
	<li>
		القاعدة 4: السجل الأول والثاني متماثلان تمامًا.
	</li>
	<li>
		القاعدة 5: هذه القاعدة مُستوفاة.
	</li>
</ul>
<h2>
	المرادفات Synonyms
</h2>

<p>
	المرادف (Synonym) هو كُنية أو اسم بديل لكائن في قاعدة بيانات، هذا الكائن قد يكون جدولًا أو معرضًا أو إجراءًا مُخزّنًا، أو سلسلة …إلخ.
</p>

<p>
	يوضّح المثال التالي كيفية إنشاء المرادفات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5233_7" style="">
<span class="pln">CREATE SYNONYM </span><span class="typ">EmployeeData</span><span class="pln">
FOR </span><span class="typ">MyDatabase</span><span class="pun">.</span><span class="pln">dbo</span><span class="pun">.</span><span class="typ">Employees</span></pre>

<h2>
	مخطط المعلومات Information Schema
</h2>

<p>
	مخطّط المعلومات (Information Schema) هو استعلام يوفّر معلومات مفيدة للمستخدمين النهائيين عن أنظمة إدارة قواعد البيانات (RDBMS).
</p>

<p>
	تتيح مثل هذه الاستعلامات للمستخدمين إمكانية العثور السريع على جداول قاعدة البيانات التي تحتوي أعمدة معيّنة، كما يحدث عندما ترغب في ربط البيانات من جدولين بشكل غير مباشر عبر جدول ثالث دون معرفة مُسبقة بالجداول التي قد تحتوي على مفاتيح أو أعمدة أخرى مشتركة مع الجداول المستهدفة.
</p>

<p>
	يستخدم المثال التالي تعبيرًا <a href="https://ar.wikipedia.org/wiki/%D8%AA%D9%8A-%D8%B3%D9%83%D9%8A%D9%88%D9%84" rel="external nofollow">T-SQL</a>، ويبحث عن مخطّط المعلومات الخاصّ بقاعدة البيانات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5233_9" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM INFORMATION_SCHEMA</span><span class="pun">.</span><span class="pln">COLUMNS
WHERE COLUMN_NAME LIKE </span><span class="str">'%Institution%'</span></pre>

<p>
	تحتوي النتيجة على قائمة بالأعمدة المُطابقة، وأسماء جداولها، ومعلومات أخرى مفيدة.
</p>

<h2>
	ترتيب التنفيذ Order of Execution
</h2>

<p>
	تُنفّذ عبارات استعلامات SQL وفق ترتيب محدّد. تستعرض هذه الفقرة هذا الترتيب:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5233_11" style="">
<span class="com">/*(8)*/</span><span class="pln"> SELECT </span><span class="com">/*9*/</span><span class="pln"> DISTINCT </span><span class="com">/*11*/</span><span class="pln"> TOP 
</span><span class="com">/*(1)*/</span><span class="pln"> FROM
</span><span class="com">/*(3)*/</span><span class="pln"> JOIN
</span><span class="com">/*(2)*/</span><span class="pln"> ON
</span><span class="com">/*(4)*/</span><span class="pln"> WHERE
</span><span class="com">/*(5)*/</span><span class="pln"> GROUP BY
</span><span class="com">/*(6)*/</span><span class="pln"> WITH </span><span class="pun">{</span><span class="pln">CUBE </span><span class="pun">|</span><span class="pln"> ROLLUP</span><span class="pun">}</span><span class="pln">
</span><span class="com">/*(7)*/</span><span class="pln"> HAVING
</span><span class="com">/*(10)*/</span><span class="pln"> ORDER BY
</span><span class="com">/*(11)*/</span><span class="pln"> LIMIT</span></pre>

<p>
	إليك الترتيب الذي تتم به معالجة الاستعلامات، مع وصف مختصر لكلّ منها (تشير VT إلى "Virtual Table" أي جدول وهمي، وتوضّح كيف يتم إنتاج مختلف البيانات أثناء معالجة الاستعلام):
</p>

<ol>
<li>
		<code>FROM</code>: تنفّذ <a href="https://ar.wikipedia.org/wiki/%D8%AC%D8%AF%D8%A7%D8%A1_%D8%AF%D9%8A%D9%83%D8%A7%D8%B1%D8%AA%D9%8A" rel="external nofollow">جداء ديكارتي</a> (ضمّ متقاطع cross join) بين الجدولين الأولين في عبارة FROM، ونتيجة لذلك، يُنشأ جدول وهمي VT1
	</li>
	<li>
		<code>ON</code>: ترشِّح الجدول الوهمي VT1. ولا تُدرج إلا الصفوف التي تعيد <code>TRUE</code> إلى الجدول الوهمي <code>VT2</code>.
	</li>
	<li>
		<code>OUTER</code>: في حال الضمّ الخارجي <code>OUTER JOIN</code> (على عكس الضمّ المتقاطع <code>CROSS JOIN</code> أو الضمّ الداخلي <code>INNER JOIN</code>)، تُضاف صفوف الجدول أو الجداول المحفوظة (preserved table) التي لم يُعثَر فيها على تطابق إلى صفوف الجدول الوهمي <code>VT2</code> كصفوف خارجية، وينتُج عن ذلك الجدول <code>VT3</code>. في حال كان هناك أكثر من جدولين في عبارة <code>FROM</code>، تُطبَّق الخطوات من 1 إلى 3 بشكل متكرر بين نتيجة عملية الضمّ الأخيرة والجدول التالي في عبارة <code>FROM</code> إلى أن تُعالج جميع الجداول.
	</li>
	<li>
		<code>WHERE</code>: ترشِّح الجدول <code>VT3</code>. ولا تُدرج إلا الصفوف التي تعيد <code>TRUE</code> إلى الجدول <code>VT4</code>
	</li>
	<li>
		<code>GROUP BY</code>: تُقسّم صفوف الجدول الوهمي <code>VT4</code> إلى مجموعات بناءً على قائمة الأعمدة المحدّدة في عبارة <code>GROUP BY</code>. وينجم عن ذلك إنشاء جدول <code>VT5</code>.
	</li>
	<li>
		<code>CUBE | ROLLUP</code>: تُضاف مجموعات أجزاء - Supergroups - (مجموعات مؤلّفة من مجموعات) إلى صفوف <code>VT5</code>، وينتُج الجدول الوهمي <code>VT6</code>.
	</li>
	<li>
		<code>HAVING</code>: ترشِّح الجدول <code>VT6</code>. ولا تُدرج إلا المجموعات التي تعيد القيمة <code>TRUE</code> إلى الجدول <code>VT7</code>.
	</li>
	<li>
		<code>SELECT</code>: تُعالج قائمة <code>SELECT</code>، ويُنشأ الجدول <code>VT8</code>.
	</li>
	<li>
		<code>DISTINCT</code>: تُزال الصفوف المكرّرة من <code>VT8</code>. ويُنشأ الجدول <code>VT9</code>.
	</li>
	<li>
		<code>ORDER BY</code>: تُرتَّب صفوف الجدول <code>VT9</code> وفقًا لقائمة الأعمدة المحدّدة في عبارة <code>ORDER BY</code>، كما يُنشأ مُؤشّر - cursor - ‏(<code>VC10</code>).
	</li>
	<li>
		<code>TOP</code>: يُختار العدد أو النّسبة المئوية المحدّدة من الصفوف من بداية الجدول <code>VC10</code>. ويُنشأ الجدول <code>VT11</code> ثُم يُعاد إلى المُستدعي - caller - (العبارة <code>LIMIT</code> لها نفس وظيفة <code>TOP</code> في بعض لهجات SQL، مثل Postgres و Netezza.)
	</li>
</ol>
<p>
	ترجمة -وبتصرّف- للفصول من 57 إلى 60 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D8%B8%D9%8A%D9%85-%D8%B4%D9%8A%D9%81%D8%B1%D8%A7%D8%AA-sql-%D9%88%D8%AA%D8%A3%D9%85%D9%8A%D9%86%D9%87%D8%A7-r860/" rel="">تنظيم شيفرات SQL وتأمينها</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">الاستعلامات الفرعية والإجراءات في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">859</guid><pubDate>Sat, 09 May 2020 18:08:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; &#x627;&#x644;&#x641;&#x631;&#x639;&#x64A;&#x629; &#x648;&#x627;&#x644;&#x625;&#x62C;&#x631;&#x627;&#x621;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/15.jpg.5e9539e08fb8b967955b4cb0f67a1087.jpg" /></p>

<p>
	تستعرض هذه المقالة بعض المواضيع المتقدمة عن تنفيذ الشيفرات في SQL، مثل الاستعلامات الفرعية، وكتل التنفيذ، والإجراءات المُخزّنة، والزنادات، والمُعاملات.
</p>

<h2>
	الاستعلامات الفرعية Subqueries
</h2>

<p>
	الاستعلامات الفرعية هي استعلامات داخلية أو متشعّبة داخل استعلام آخر في SQL. يُمكن أن تُضمّن الاستعلامات الفرعية داخل <code>‎FROM‎</code> أو <code>SELECT</code> أو <code>WHERE</code>.
</p>

<h3>
	الاستعلامات الفرعية في عبارة FROM
</h3>

<p>
	تتصرّف الاستعلامات الفرعية في عبارة <code>‎FROM‎</code> بشكل مشابه للجداول المؤقتة المُنشأة أثناء تنفيذ استعلام، والمفقودة إثر ذلك.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_7" style="">
<span class="pln">SELECT </span><span class="typ">Managers</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">Salary</span><span class="pln">
FROM </span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="typ">Id</span><span class="pln">
    FROM </span><span class="typ">Employees</span><span class="pln">
    WHERE </span><span class="typ">ManagerId</span><span class="pln"> IS NULL
</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">Managers</span><span class="pln">
JOIN </span><span class="typ">Employees</span><span class="pln"> ON </span><span class="typ">Managers</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">Id</span></pre>

<h3>
	الاستعلامات الفرعية في عبارة SELECT
</h3>

<p>
	إليك مثال على استعلام فرعي في <code>SELECT</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_9" style="">
<span class="pln">SELECT
     </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
     </span><span class="typ">FName</span><span class="pun">,</span><span class="pln">
     </span><span class="typ">LName</span><span class="pun">,</span><span class="pln">
    </span><span class="pun">(</span><span class="pln">SELECT COUNT</span><span class="pun">(*)</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln"> WHERE </span><span class="typ">Cars</span><span class="pun">.</span><span class="typ">CustomerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Customers</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">NumberOfCars</span><span class="pln">
FROM </span><span class="typ">Customers</span></pre>

<h3>
	الاستعلامات الفرعية في عبارة WHERE
</h3>

<p>
	يمكنك استخدام استعلام فرعي لترشيح مجموعة النتائج. على سبيل المثال، تعيد الشيفرة التالية الموظفين الأعلى أجرًا فقط:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_11" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">Salary</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT MAX</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pun">)</span></pre>

<h3>
	الاستعلامات الفرعية المرتبطة Correlated Subqueries
</h3>

<p>
	الاستعلامات الفرعية المرتبطة (والمعروفة أيضًا باسم المتزامنة أو المتّسقة) هي استعلامات متشعّبة تحتوي مرجعًا يشير إلى الصفّ الحالي في الاستعلام الخارجي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_13" style="">
<span class="pln">SELECT </span><span class="typ">EmployeeId</span><span class="pln">
     FROM </span><span class="typ">Employee</span><span class="pln"> AS eOuter
     WHERE </span><span class="typ">Salary</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
       SELECT AVG</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln">
       FROM </span><span class="typ">Employee</span><span class="pln"> eInner
       WHERE eInner</span><span class="pun">.</span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> eOuter</span><span class="pun">.</span><span class="typ">DepartmentId</span><span class="pln">
 </span><span class="pun">)</span></pre>

<p>
	الاستعلام الفرعي <code>‎SELECT AVG(Salary) ...‎</code> مرتبط لأنّه يشير إلى الصفّ <code>‎Employee‎</code> من الجدول <code>‎eOuter‎</code> من الاستعلام الخارجي.
</p>

<h3>
	ترشيح نتائج الاستعلام باستخدام استعلام مُنفَّذ على جدول آخر
</h3>

<p>
	يختار الاستعلام التالي جميع الموظفين غير الموجودين في جدول المشرفين <code>Supervisors</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_15" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">EmployeeID</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT </span><span class="typ">EmployeeID</span><span class="pln">
 FROM </span><span class="typ">Supervisors</span><span class="pun">)</span></pre>

<p>
	يمكن تحقيق النتائج نفسها باستخدام <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">الضم اليساري</a> <code>LEFT JOIN</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_17" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> AS e
LEFT JOIN </span><span class="typ">Supervisors</span><span class="pln"> AS s ON s</span><span class="pun">.</span><span class="typ">EmployeeID</span><span class="pun">=</span><span class="pln">e</span><span class="pun">.</span><span class="typ">EmployeeID</span><span class="pln">
WHERE s</span><span class="pun">.</span><span class="typ">EmployeeID</span><span class="pln"> </span><span class="kwd">is</span><span class="pln"> NULL</span></pre>

<h3>
	الاستعلامات الفرعية في عبارة FROM
</h3>

<p>
	يمكنك استخدام الاستعلامات الفرعية لتعريف جدول مؤقّت واستخدامه في عبارة <code>FROM</code> الخاصّة بالاستعلام الخارجي.
</p>

<p>
	تبحث الشيفرة التالية عن المدن في جدول الطقس <code>weather</code> التي تتغيّر درجات الحرارة اليومية الخاصّة بها بأكثر من 20 درجة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_19" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="pun">(</span><span class="pln">SELECT city</span><span class="pun">,</span><span class="pln"> temp_hi </span><span class="pun">-</span><span class="pln"> temp_lo AS temp_var FROM weather</span><span class="pun">)</span><span class="pln"> AS w
WHERE temp_var </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">;</span></pre>

<p>
	النتيجة:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				city
			</th>
			<th>
				temp_var
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				ST LOUIS
			</td>
			<td>
				21
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				31
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				23
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				31
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				27
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				28
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				28
			</td>
		</tr>
<tr>
<td>
				LOS ANGELES
			</td>
			<td>
				32
			</td>
		</tr>
</tbody>
</table>
<h3>
	الاستعلامات الفرعية في عبارة WHERE
</h3>

<p>
	يبحث المثال التالي عن المدن (من مثال المدن) التي يقل تعداد سكانها عن متوسط درجة الحرارة فيها (يتم الحصول عليها عن طريق استعلام فرعي):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_21" style="">
<span class="pln">SELECT name</span><span class="pun">,</span><span class="pln"> pop2000 FROM cities
WHERE pop2000 </span><span class="pun">&lt;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT avg</span><span class="pun">(</span><span class="pln">pop2000</span><span class="pun">)</span><span class="pln"> FROM cities</span><span class="pun">);</span></pre>

<p>
	في المثال أعلاه، يحدّد الاستعلام الفرعي SELECT avg(pop2000) FROM شرط عبارة WHERE.
</p>

<p>
	النتيجة:
</p>

<table>
<thead><tr>
<th>
				name
			</th>
			<th>
				pop2000
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				San Francisco
			</td>
			<td>
				776733
			</td>
		</tr>
<tr>
<td>
				ST LOUIS
			</td>
			<td>
				348189
			</td>
		</tr>
<tr>
<td>
				Kansas City
			</td>
			<td>
				146866
			</td>
		</tr>
</tbody>
</table>
<h2>
	كتل التنفيذ Execution blocks
</h2>

<p>
	تُستخدم الكلمتان المفتاحيتان <code>BEGIN</code> و <code>END</code> لبدء كتلة تنفيذ (Execution block) وإنهائها على التوالي، كما يوضح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_23" style="">
<span class="kwd">BEGIN</span><span class="pln">
      UPDATE </span><span class="typ">Employees</span><span class="pln"> SET </span><span class="typ">PhoneNumber</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'5551234567'</span><span class="pln"> WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
      UPDATE </span><span class="typ">Employees</span><span class="pln"> SET </span><span class="typ">Salary</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">650</span><span class="pln"> WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">END</span></pre>

<h2>
	الإجراءات المخزّنة Stored Procedures
</h2>

<p>
	يمكن إنشاء الإجراءات المخزّنة عبر واجهة المستخدم الرسومية الخاصة ببرنامج إدارة قاعدة البيانات (مثال SQL Server)، أو من خلال عبارة SQL كما يلي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_25" style="">
<span class="pun">--</span><span class="pln"> </span><span class="pun">تحديد</span><span class="pln"> </span><span class="pun">الاسم</span><span class="pln"> </span><span class="pun">والمعاملات</span><span class="pln">
CREATE PROCEDURE </span><span class="typ">Northwind</span><span class="pun">.</span><span class="pln">getEmployee
 </span><span class="lit">@LastName</span><span class="pln"> nvarchar</span><span class="pun">(</span><span class="lit">50</span><span class="pun">),</span><span class="pln"> 
 </span><span class="lit">@FirstName</span><span class="pln"> nvarchar</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> 
AS 
</span><span class="pun">--</span><span class="pln"> </span><span class="pun">تحديد</span><span class="pln"> </span><span class="pun">الاستعلام</span><span class="pln"> </span><span class="pun">المراد</span><span class="pln"> </span><span class="pun">تنفيذه</span><span class="pln">
SELECT </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Department</span><span class="pln">  
FROM </span><span class="typ">Northwind</span><span class="pun">.</span><span class="pln">vEmployeeDepartment
WHERE </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@FirstName</span><span class="pln"> AND </span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@LastName</span><span class="pln"> 
AND </span><span class="typ">EndDate</span><span class="pln"> IS NULL</span><span class="pun">;</span><span class="pln"> </span></pre>

<p>
	يمكن استدعاء الإجراء على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_27" style="">
<span class="pln">EXECUTE </span><span class="typ">Northwind</span><span class="pun">.</span><span class="pln">getEmployee N</span><span class="str">'Ackerman'</span><span class="pun">,</span><span class="pln"> N</span><span class="str">'Pilar'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> 
EXEC </span><span class="typ">Northwind</span><span class="pun">.</span><span class="pln">getEmployee </span><span class="lit">@LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> N</span><span class="str">'Ackerman'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> N</span><span class="str">'Pilar'</span><span class="pun">;</span><span class="pln"> 
GO 
</span><span class="pun">--</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> 
EXECUTE </span><span class="typ">Northwind</span><span class="pun">.</span><span class="pln">getEmployee </span><span class="lit">@FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> N</span><span class="str">'Pilar'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> N</span><span class="str">'Ackerman'</span><span class="pun">;</span><span class="pln"> 
GO </span></pre>

<h2>
	الزنادات Triggers
</h2>

<p>
	الزنادات هي إجراءات مخزّنة تُستدعى تلقائيًا عند وقوع أحداث معينة، مثل، إدراج صفّ في عمود، أو تحديث عمود ما، أو غيرها من الأحداث.
</p>

<h3>
	إنشاء زناد
</h3>

<p>
	ينشئ هذا المثال زنادًا يُدرج سجلًا في جدول ثانٍ (<code>MyAudit</code>) عند إدراج سجل ما في الجدول الذي عُرِّف الزناد عليه (<code>MyTable</code>). في هذا المثال، الجدول "inserted" هو جدول خاص تستخدمه Microsoft SQL Server لتخزين الصفوف المتأثِّرة (aﬀected rows) خلال عبارتي <code>INSERT</code> و <code>UPDATE</code>؛ يوجد أيضًا جدول "deleted" خاصّ يؤدي نفس الوظيفة في عبارات <code>DELETE</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_29" style="">
<span class="pln">CREATE TRIGGER </span><span class="typ">MyTrigger</span><span class="pln">
     ON </span><span class="typ">MyTable</span><span class="pln">
     AFTER INSERT
AS
</span><span class="kwd">BEGIN</span><span class="pln">
     </span><span class="pun">--</span><span class="pln"> </span><span class="typ">MyAudit</span><span class="pln"> </span><span class="pun">إضافة</span><span class="pln"> </span><span class="pun">سجل</span><span class="pln"> </span><span class="pun">إلى</span><span class="pln"> </span><span class="pun">الجدول</span><span class="pln">
     INSERT INTO </span><span class="typ">MyAudit</span><span class="pun">(</span><span class="typ">MyTableId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">User</span><span class="pun">)</span><span class="pln">
     </span><span class="pun">(</span><span class="pln">SELECT </span><span class="typ">MyTableId</span><span class="pun">,</span><span class="pln"> CURRENT_USER FROM inserted</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">END</span></pre>

<p>
	المثال التالي يستخدم زنادًا لإدارة سلة المحذوفات عبر الجدول "deleted":
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_31" style="">
<span class="pln">CREATE TRIGGER </span><span class="typ">BooksDeleteTrigger</span><span class="pln">
         ON </span><span class="typ">MyBooksDB</span><span class="pun">.</span><span class="typ">Books</span><span class="pln">
         AFTER DELETE
AS
     INSERT INTO </span><span class="typ">BooksRecycleBin</span><span class="pln">
         SELECT </span><span class="pun">*</span><span class="pln">
         FROM deleted</span><span class="pun">;</span><span class="pln">
GO</span></pre>

<h2>
	المعامَلات Transactions
</h2>

<p>
	المعامَلات (Transactions) هي سلسلة من عمليات SQL تُجرى على قاعدة بيانات، هذه السلسلة تُعامل كما لو كانت عملية واحدة، بحيث إما أن تُنفَّذ جميعا، ونقول أنّه تمّ الالتزام بها (committed)، أو عدم تنفيذ أيّ منها، ونقول أنّه تمّ التراجع عنها (rolled back).
</p>

<p>
	المثال التالي يوضّح معاملة بسيطة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_33" style="">
<span class="kwd">BEGIN</span><span class="pln"> TRANSACTION
    INSERT INTO </span><span class="typ">DeletedEmployees</span><span class="pun">(</span><span class="typ">EmployeeID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DateDeleted</span><span class="pun">,</span><span class="pln"> </span><span class="typ">User</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">(</span><span class="pln">SELECT </span><span class="lit">123</span><span class="pun">,</span><span class="pln"> </span><span class="typ">GetDate</span><span class="pun">(),</span><span class="pln"> CURRENT_USER</span><span class="pun">);</span><span class="pln">
    DELETE FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">EmployeeID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">123</span><span class="pun">;</span><span class="pln">
COMMIT TRANSACTION</span></pre>

<p>
	يمكنك التراجع عن المعاملة في حال حدث خطأ في الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9067_35" style="">
<span class="kwd">BEGIN</span><span class="pln"> TRY
    </span><span class="kwd">BEGIN</span><span class="pln"> TRANSACTION
       INSERT INTO </span><span class="typ">Users</span><span class="pun">(</span><span class="pln">ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Age</span><span class="pun">)</span><span class="pln">
       VALUES</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bob'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">24</span><span class="pun">)</span><span class="pln">

       DELETE FROM </span><span class="typ">Users</span><span class="pln"> WHERE </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Todd'</span><span class="pln">
    COMMIT TRANSACTION
</span><span class="kwd">END</span><span class="pln"> TRY
</span><span class="kwd">BEGIN</span><span class="pln"> CATCH
    ROLLBACK TRANSACTION
</span><span class="kwd">END</span><span class="pln"> CATCH</span></pre>

<p>
	ترجمة -وبتصرّف- للفصول من 52 إلى 56 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ المقال:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%85%D8%B9%D9%84%D9%88%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D8%B7-%D9%88%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D9%81%D9%8A-sql-r859/" rel="">تصميم الجداول ومعلومات المخطط وترتيب تنفيذ الاستعلامات في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%81%D8%B1%D9%82%D8%A9-%D9%81%D9%8A-sql-r857/" rel="">مواضيع متفرقة في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">858</guid><pubDate>Wed, 06 May 2020 18:00:00 +0000</pubDate></item><item><title>&#x645;&#x648;&#x627;&#x636;&#x64A;&#x639; &#x645;&#x62A;&#x641;&#x631;&#x642;&#x629; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%81%D8%B1%D9%82%D8%A9-%D9%81%D9%8A-sql-r857/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/14.jpg.5a483da0ed3b5062fd33caca2736d9ce.jpg" /></p>

<p>
	تستعرض هذه المقالة مجموعة من المواضيع الإضافية في SQL، مثل العروض (Views)، وكيفية كتابة التعليقات، وكيفية التعامل مع المفاتيح الخارجية (Foreign Keys) وإنشاء السلاسل.
</p>

<h2>
	العروض Views
</h2>

<h3>
	العروض البسيطة
</h3>

<p>
	تُستخدم العروض (View) لترشيح الصفوف من الجدول الأساسي، أو الاكتفاء بعرض بعض الأعمدة منه فقط:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_7" style="">
<span class="pln">CREATE VIEW new_employees_details AS
SELECT E</span><span class="pun">.</span><span class="pln">id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Salary</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Hire_date</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> E
WHERE hire_date </span><span class="pun">&gt;</span><span class="pln"> date </span><span class="str">'2015-01-01'</span><span class="pun">;</span></pre>

<p>
	يختار (<code>select</code>) المثالُ التالي من النتائج المعروضة في العرض (view):
</p>

<pre class="ipsCode">
select * from new_employees_details
</pre>

<p>
	الخرج الناتج:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody><tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr></tbody>
</table>
<h3>
	العروض المركبة Complex views
</h3>

<p>
	يمكن أن تكون العروض معقدة ومركّبة (تجميعات aggregations، عمليات ضمّ، استعلامات فرعية، إلخ). المهم أن تتأكّد دائمًا من إضافة أسماء الأعمدة لكل شيء تختاره:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_9" style="">
<span class="typ">Create</span><span class="pln"> VIEW dept_income AS
SELECT d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">DepartmentName</span><span class="pun">,</span><span class="pln"> sum</span><span class="pun">(</span><span class="pln">e</span><span class="pun">.</span><span class="pln">salary</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">TotalSalary</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> e
JOIN </span><span class="typ">Departments</span><span class="pln"> d on e</span><span class="pun">.</span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> d</span><span class="pun">.</span><span class="pln">id
GROUP BY d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">;</span></pre>

<p>
	يمكنك الآن الاختيار (<code>SELECT</code>) كما تختار من أيّ جدول عادي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_11" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM dept_income</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				DepartmentName
			</th>
			<th>
				TotalSalary
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				HR
			</td>
			<td>
				1900
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				600
			</td>
		</tr>
</tbody>
</table>
<h3>
	العروض المادية Materialized Views
</h3>

<p>
	العروض المادية هي العروض التي تكون نتائجها مُخزّنة في ذاكرة مادية، وتُحدّث دوريًا حتى تظل متزامنة مع القيم الحالية.
</p>

<p>
	العروض المادّية مفيدة في تخزين نتائج الاستعلامات المعقّدة طويلة الأمد التي لا تعتمد على نتائج الوقت الحقيقي (realtime results).
</p>

<p>
	يمكن إنشاء العروض المادية في Oracle و PostgreSQL. كما توفّر أنظمة قواعد البيانات الأخرى وظائف مماثلة، مثل العروض المُفهرسة (indexed views) في SQL Server، أو جداول الاستعلام المادية (materialized query tables) في DB2.
</p>

<p>
	هذا مثال على العروض المادية في PostgreSQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_13" style="">
<span class="pln">CREATE TABLE mytable </span><span class="pun">(</span><span class="pln">number INT</span><span class="pun">);</span><span class="pln">
INSERT INTO mytable VALUES </span><span class="pun">(</span><span class="lit">1</span><span class="pun">);</span><span class="pln">
CREATE MATERIALIZED VIEW myview AS SELECT </span><span class="pun">*</span><span class="pln"> FROM mytable</span><span class="pun">;</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM myview</span><span class="pun">;</span><span class="pln">
number
</span><span class="pun">--------</span><span class="pln">
</span><span class="lit">1</span><span class="pln">
</span><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">
INSERT INTO mytable VALUES</span><span class="pun">(</span><span class="lit">2</span><span class="pun">);</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM myview</span><span class="pun">;</span><span class="pln">
number
</span><span class="pun">--------</span><span class="pln">
</span><span class="lit">1</span><span class="pln">
</span><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">
REFRESH MATERIALIZED VIEW myview</span><span class="pun">;</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM myview</span><span class="pun">;</span><span class="pln">
number
</span><span class="pun">--------</span><span class="pln">
</span><span class="lit">1</span><span class="pln">
</span><span class="lit">2</span><span class="pln">
</span><span class="pun">(</span><span class="lit">2</span><span class="pln"> rows</span><span class="pun">)</span></pre>

<h2>
	التعليقات
</h2>

<p>
	هناك نوعان من التعليقات في SQL، التعليقات السطرية، والتعليقات متعددة الأسطر.
</p>

<h3>
	التعليقات السطرية Single-line comments
</h3>

<p>
	التعليقات السطرية هي تعليقات تستمر حتى نهاية السطر، وتُسبَق بالرمز <code>‎--‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_15" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">هذا</span><span class="pln"> </span><span class="pun">تعليق</span><span class="pln">
WHERE </span><span class="typ">FName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'John'</span></pre>

<h3>
	التعليقات متعددة الأسطر Multi-line comments
</h3>

<p>
	تُوضع التعليقات متعددة الأسطر داخل الغلاف <code>‎/* ... */‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_17" style="">
<span class="com">/* يعيد هذا الاستعلام
 جميع الموظفين */</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<p>
	يجوز أيضًا إدراج مثل هذا التعليق في منتصف السطر:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_19" style="">
<span class="pln">SELECT </span><span class="com">/* جميع الأعمدة: */</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<h2>
	المفاتيح الخارجية Foreign Keys
</h2>

<p>
	تضمن قيود المفاتيح الخارجية (Foreign Keys constraints) تكامل البيانات، إذ تفرض أن تتطابق القيم الموجودة في جدول معيّن، مع القيم المقابلة في جدول آخر.
</p>

<p>
	مثلا، في الجامعة، تنتمي كل دورة دراسية إلى قسم معيّن. يمكننا التعبير عن هذا القيد (constraint) على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_21" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Department</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Dept_Code</span><span class="pln">        CHAR </span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Dept_Name</span><span class="pln">        VARCHAR </span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> UNIQUE
</span><span class="pun">);</span></pre>

<p>
	المثال التالي يدرج قيمًا جديدة في قسم <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">علوم الحاسوب</a>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_23" style="">
<span class="pln">INSERT INTO </span><span class="typ">Department</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="str">'CS205'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Computer Science'</span><span class="pun">);</span></pre>

<p>
	يحتوي الجدول التالي على معلومات عن المواضيع التي تشملها شعبة <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">علوم الحاسوب</a>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_25" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Programming_Courses</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Dept_Code</span><span class="pln">       CHAR</span><span class="pun">(</span><span class="lit">5</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Prg_Code</span><span class="pln">        CHAR</span><span class="pun">(</span><span class="lit">9</span><span class="pun">)</span><span class="pln"> PRIMARY KEY</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Prg_Name</span><span class="pln">        VARCHAR </span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> UNIQUE</span><span class="pun">,</span><span class="pln">
    FOREIGN KEY </span><span class="pun">(</span><span class="typ">Dept_Code</span><span class="pun">)</span><span class="pln"> </span><span class="typ">References</span><span class="pln"> </span><span class="typ">Department</span><span class="pun">(</span><span class="typ">Dept_Code</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	(يجب أن يتطابق نوع بيانات المفتاح الخارجي مع نوع البيانات الخاص بالمفتاح المشار إليه - referenced key.)
</p>

<p>
	لا يسمح قيد المفتاح الخارجي الخاص بالعمود <code>‎Dept_Code‎</code> إلّا بالقيم الموجودة سلفًا في الجدول المشار إليه. هذا يعني أنه إذا حاولت إدراج القيم التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_27" style="">
<span class="pln">INSERT INTO </span><span class="typ">Programming_Courses</span><span class="pln"> </span><span class="typ">Values</span><span class="pln"> </span><span class="pun">(</span><span class="str">'CS300'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'FDB-DB001'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Database Systems'</span><span class="pun">);</span></pre>

<p>
	فستطرح قاعدة البيانات <strong>خطأ انتهاك المفتاح الخارجي</strong> (Foreign Key violation error)، لأنّ <code>‎CS300‎</code> غير موجودة في جدول الأقسام <code>‎Department‎</code>. ولكن عند تجربة قيمة مفتاح موجود:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_29" style="">
<span class="pln">INSERT INTO </span><span class="typ">Programming_Courses</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="str">'CS205'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'FDB-DB001'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Database Systems'</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Programming_Courses</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="str">'CS205'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'DB2-DB002'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Database Systems II'</span><span class="pun">);</span></pre>

<p>
	فلن يكون هناك أيّ مشكلة.
</p>

<p>
	هذه بعض النصائح حول كيفية استخدام المفاتيح الخارجية:
</p>

<ul>
<li>
		يجب أن يشير المفتاح الخارجي إلى مفتاح فريد - UNIQUE - (أو أساسي - PRIMARY) من الجدول الأصلي الأب (parent table).
	</li>
	<li>
		لن ينجم أيّ خطأ عن إدخال القيمة المعدومة <code>NULL</code> إلى عمود المفتاح الخارجي.
	</li>
	<li>
		يمكن أن تشير قيود المفاتيح الخارجية إلى الجداول الموجودة في نفس قاعدة البيانات.
	</li>
	<li>
		يمكن أن تشير قيود المفتاح الخارجي إلى عمود آخر في نفس الجدول (مرجع ذاتي).
	</li>
</ul>
<h3>
	إنشاء جدول بمفتاح خارجي
</h3>

<p>
	في هذا المثال، لدينا جدول البيانات <code>‎SuperHeros‎</code>. يحتوي هذا الجدول على مفتاح أساسي <code>‎ID‎</code>.
</p>

<p>
	سنضيف جدولًا جديدًا بُغية تخزين صلاحيات كل بطل خارق:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_31" style="">
<span class="pln">CREATE TABLE </span><span class="typ">HeroPowers</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
    ID </span><span class="kwd">int</span><span class="pln"> NOT NULL PRIMARY KEY</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Name</span><span class="pln"> nvarchar</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">HeroId</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> REFERENCES </span><span class="typ">SuperHeros</span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span></pre>

<p>
	في هذا المثال، يُعدّ العمود <code>‎HeroId‎</code> <strong>مفتاحًا خارجيًا</strong> للجدول <code>‎SuperHeros‎</code>.
</p>

<h2>
	التسلسلات Sequences
</h2>

<p>
	التسلسلات هي سلاسل من الأعداد.
</p>

<p>
	المثال التالي ينشئ تسلسلًا يبدأ من 1000، ويتزايد بمقدار 1.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_33" style="">
<span class="pln"> CREATE SEQUENCE orders_seq
 START WITH     </span><span class="lit">1000</span><span class="pln">
 INCREMENT BY   </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	في المثال التالي، سنستخدم مرجعًا (<code>seq_name.NEXTVAL</code>) يشير إلى القيمة التالية في التسلسل.
</p>

<p>
	<strong>تنبيه</strong>: في كلّ عبارة، تكون هناك قيمة واحدة فقط من التسلسل. أي أنّه إذا كانت هناك عدة مراجع إلى القيمة التالية في التسلسل (NEXTVAL) في عبارة معينة، فستشير جميع تلك المراجع إلى نفس الرقم من السلسلة.
</p>

<p>
	يمكن استخدام القيمة التالية <code>NEXTVAL</code> في عبارات الإدراج <code>INSERTS</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_35" style="">
<span class="pln">INSERT INTO </span><span class="typ">Orders</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Order_UID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Customer</span><span class="pun">)</span><span class="pln">
 VALUES </span><span class="pun">(</span><span class="pln">orders_seq</span><span class="pun">.</span><span class="pln">NEXTVAL</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1032</span><span class="pun">);</span></pre>

<p>
	كما يمكن أن تُستخدم في عمليات التحديث:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_37" style="">
<span class="pln">UPDATE </span><span class="typ">Orders</span><span class="pln">
SET </span><span class="typ">Order_UID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> orders_seq</span><span class="pun">.</span><span class="pln">NEXTVAL
WHERE </span><span class="typ">Customer</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">581</span><span class="pun">;</span></pre>

<p>
	ويمكن أيضًا أن تُستخدم في عبارات الاختيار <code>SELECT</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_624_39" style="">
<span class="pln">SELECT </span><span class="typ">Order_seq</span><span class="pun">.</span><span class="pln">NEXTVAL FROM dual</span><span class="pun">;</span></pre>

<p>
	ترجمة -وبتصرّف- للفصول من 47 إلى 51 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D8%B1%D8%B9%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%A5%D8%AC%D8%B1%D8%A7%D8%A1%D8%A7%D8%AA-%D9%81%D9%8A-sql-r858/" rel="">الاستعلامات الفرعية والإجراءات في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D8%AC%D8%AF%D9%88%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-common-table-expressions-%D9%81%D9%8A-sql-r856/" rel="">التعابير الجدولية الشائعة Common Table Expressions في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">857</guid><pubDate>Sat, 02 May 2020 18:05:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x639;&#x627;&#x628;&#x64A;&#x631; &#x627;&#x644;&#x62C;&#x62F;&#x648;&#x644;&#x64A;&#x629; &#x627;&#x644;&#x634;&#x627;&#x626;&#x639;&#x629; Common Table Expressions &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D8%AC%D8%AF%D9%88%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-common-table-expressions-%D9%81%D9%8A-sql-r856/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/13.jpg.fa402dd7e23eae7c90baa9247a19ab19.jpg" /></p>

<h2>
	توليد قيم
</h2>

<p>
	لا توفّر معظم قواعد البيانات طريقة أصلية لإنشاء سلاسل الأرقام؛ بيْد أنّه يمكن استخدام تعبيرات الجدول الشائعة أو التعبيرات الجدولية (common table expressions) مع العوديّة (recursion) لمحاكاة هذا النوع من الوظائف.
</p>

<p>
	يولّد المثال التالي تعبيرًا جدوليًا يُسمّى <code>‎Numbers‎</code>، واسم عموده <code>‎i‎</code>، ويحتوي أرقام الصفوف (1-5):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_7" style="">
<span class="pun">--</span><span class="pln"> </span><span class="pun">لتخزين</span><span class="pln"> </span><span class="pun">الأعداد</span><span class="pln"> </span><span class="str">`i`</span><span class="pln"> </span><span class="pun">واسم</span><span class="pln"> </span><span class="pun">العمود</span><span class="pln"> </span><span class="str">`Numbers"إعطاء اسم الجدول
WITH Numbers(i) AS (
 -- البداية
 SELECT 1
 -- ضروري لأجل العودية UNION ALL المعامل
 UNION ALL
 -- تعبير التكرار
 SELECT i + 1
 -- التعبير الجدولي الذي أعلنا عنه والمُستخدم كمصدر للعودية
 FROM Numbers
 -- عبارة إنهاء العودية
 WHERE i &lt; 5
)
-- استخدام التعبير الجدولي المُنشأ كما لو كان جدولا عاديا
SELECT i FROM Numbers;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				i
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
		</tr>
<tr>
<td>
				2
			</td>
		</tr>
<tr>
<td>
				3
			</td>
		</tr>
<tr>
<td>
				4
			</td>
		</tr>
<tr>
<td>
				5
			</td>
		</tr>
</tbody>
</table>
<p>
	يمكن استخدام هذه الطريقة مع أي مجال من الأعداد، وكذلك مع أنواع أخرى من البيانات.
</p>

<h2>
	الترقيم العودي لشجيرة recursively enumerating a subtree
</h2>

<p>
	المثال التالي يوضّح كيفية ترقيم شجيرة (subtree) عوديًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_11" style="">
<span class="pln">WITH RECURSIVE </span><span class="typ">ManagedByJames</span><span class="pun">(</span><span class="typ">Level</span><span class="pun">,</span><span class="pln"> ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">)</span><span class="pln"> AS </span><span class="pun">(</span><span class="pln">
 </span><span class="pun">--</span><span class="pln"> </span><span class="pun">البدء</span><span class="pln"> </span><span class="pun">بهذا</span><span class="pln"> </span><span class="pun">الصف</span><span class="pln">
 SELECT </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pln">
 FROM </span><span class="typ">Employees</span><span class="pln">
 WHERE ID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
 UNION ALL
 </span><span class="pun">--</span><span class="pln"> </span><span class="pun">الحصول</span><span class="pln"> </span><span class="pun">على</span><span class="pln"> </span><span class="pun">الموظفين</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يعملون</span><span class="pln"> </span><span class="pun">تحت</span><span class="pln"> </span><span class="pun">إمرة</span><span class="pln"> </span><span class="pun">أيّ</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="pun">المدراء</span><span class="pln"> </span><span class="pun">المُختارين</span><span class="pln"> </span><span class="pun">سابقا</span><span class="pln">
 SELECT </span><span class="typ">ManagedByJames</span><span class="pun">.</span><span class="typ">Level</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Employees</span><span class="pun">.</span><span class="pln">ID</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">FName</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">LName</span><span class="pln">
 FROM </span><span class="typ">Employees</span><span class="pln">
 JOIN </span><span class="typ">ManagedByJames</span><span class="pln">
 ON </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">ManagerID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ManagedByJames</span><span class="pun">.</span><span class="pln">ID
 ORDER BY </span><span class="lit">1</span><span class="pln"> DESC </span><span class="pun">--</span><span class="pln"> depth</span><span class="pun">-</span><span class="pln">first search </span><span class="pun">البحث</span><span class="pln"> </span><span class="pun">الأولي-العميق</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">ManagedByJames</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				Level
			</th>
			<th>
				ID
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
		</tr>
</tbody>
</table>
<h2>
	الاستعلامات المؤقتة Temporary query
</h2>

<p>
	تتصرف الاستعلامات المؤقتة (Temporary query) مثل الاستعلامات المتشعّبة (nested subqueries)، إلّا أنّ صياغتها مختلفة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_13" style="">
<span class="pln">WITH </span><span class="typ">ReadyCars</span><span class="pln"> AS </span><span class="pun">(</span><span class="pln">
   SELECT </span><span class="pun">*</span><span class="pln">
    FROM </span><span class="typ">Cars</span><span class="pln">
    WHERE </span><span class="typ">Status</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
SELECT ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Model</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TotalCost</span><span class="pln">
FROM </span><span class="typ">ReadyCars</span><span class="pln">
ORDER BY </span><span class="typ">TotalCost</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				ID
			</th>
			<th>
				Model
			</th>
			<th>
				TotalCost
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				Ford F-150
			</td>
			<td>
				200
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Ford F-150
			</td>
			<td>
				230
			</td>
		</tr>
</tbody>
</table>
<p>
	هذا استعلام فرعي مكافئ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_15" style="">
<span class="pln">SELECT ID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Model</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TotalCost</span><span class="pln">
FROM </span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="pun">*</span><span class="pln">
    FROM </span><span class="typ">Cars</span><span class="pln">
    WHERE </span><span class="typ">Status</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ReadyCars</span><span class="pln">
ORDER BY </span><span class="typ">TotalCost</span></pre>

<h2>
	التسلّق العوديّ لشجرة recursively going up in a tree
</h2>

<p>
	المثال التالي يوضّح كيفية تسلق شجرة عوديًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_17" style="">
<span class="pln">WITH RECURSIVE </span><span class="typ">ManagersOfJonathon</span><span class="pln"> AS </span><span class="pun">(</span><span class="pln">
 </span><span class="pun">--</span><span class="pln"> </span><span class="pun">البدء</span><span class="pln"> </span><span class="pun">بهذا</span><span class="pln"> </span><span class="pun">الصف</span><span class="pln">
 SELECT </span><span class="pun">*</span><span class="pln">
 FROM </span><span class="typ">Employees</span><span class="pln">
 WHERE ID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pln">
 UNION ALL
 </span><span class="pun">--</span><span class="pln"> </span><span class="pun">الحصول</span><span class="pln"> </span><span class="pun">على</span><span class="pln"> </span><span class="pun">مدراء</span><span class="pln"> </span><span class="pun">كل</span><span class="pln"> </span><span class="pun">الصفوف</span><span class="pln"> </span><span class="pun">المُختارة</span><span class="pln"> </span><span class="pun">سابقا</span><span class="pln">
 SELECT </span><span class="typ">Employees</span><span class="pun">.*</span><span class="pln">
 FROM </span><span class="typ">Employees</span><span class="pln">
 JOIN </span><span class="typ">ManagersOfJonathon</span><span class="pln">
 ON </span><span class="typ">Employees</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ManagersOfJonathon</span><span class="pun">.</span><span class="typ">ManagerID</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">ManagersOfJonathon</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
		</tr>
</tbody>
</table>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<h2>
	التوليد العودي للتواريخ
</h2>

<p>
	المثال التالي يولّد تواريخ مع تضمين الجداول الزمنية لفِرَق العمل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_19" style="">
<span class="pln">DECLARE </span><span class="lit">@DateFrom</span><span class="pln"> DATETIME </span><span class="pun">=</span><span class="pln"> </span><span class="str">'2016-06-01 06:00'</span><span class="pln">
DECLARE </span><span class="lit">@DateTo</span><span class="pln"> DATETIME </span><span class="pun">=</span><span class="pln"> </span><span class="str">'2016-07-01 06:00'</span><span class="pln">
DECLARE </span><span class="lit">@IntervalDays</span><span class="pln"> INT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">7</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="typ">Transition</span><span class="pln"> </span><span class="typ">Sequence</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">وقت</span><span class="pln"> </span><span class="pun">الاستراحة</span><span class="pln"> </span><span class="pun">في</span><span class="pln"> </span><span class="pun">المناوبات</span><span class="pln"> </span><span class="pun">الليلية</span><span class="pln"> </span><span class="pun">والنهارية</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> RR </span><span class="pun">(</span><span class="typ">Rest</span><span class="pln"> </span><span class="pun">&amp;</span><span class="pln"> </span><span class="typ">Relax</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> DS </span><span class="pun">(</span><span class="typ">Day</span><span class="pln"> </span><span class="typ">Shift</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> NS </span><span class="pun">(</span><span class="typ">Night</span><span class="pln"> </span><span class="typ">Shift</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pln">
</span><span class="pun">;</span><span class="pln">WITH roster AS
</span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="lit">@DateFrom</span><span class="pln"> AS </span><span class="typ">RosterStart</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AS </span><span class="typ">TeamA</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> AS </span><span class="typ">TeamB</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> AS </span><span class="typ">TeamC</span><span class="pln">
    UNION ALL
    SELECT DATEADD</span><span class="pun">(</span><span class="pln">d</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@IntervalDays</span><span class="pun">,</span><span class="pln"> </span><span class="typ">RosterStart</span><span class="pun">),</span><span class="pln">
       CASE </span><span class="typ">TeamA</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="lit">2</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="lit">3</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamA</span><span class="pun">,</span><span class="pln">
       CASE </span><span class="typ">TeamB</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="lit">2</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="lit">3</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamB</span><span class="pun">,</span><span class="pln">
       CASE </span><span class="typ">TeamC</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="lit">2</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="lit">3</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamC</span><span class="pln">
    FROM roster WHERE </span><span class="typ">RosterStart</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> DATEADD</span><span class="pun">(</span><span class="pln">d</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">@IntervalDays</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@DateTo</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="typ">RosterStart</span><span class="pun">,</span><span class="pln">
       ISNULL</span><span class="pun">(</span><span class="pln">LEAD</span><span class="pun">(</span><span class="typ">RosterStart</span><span class="pun">)</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">RosterStart</span><span class="pun">),</span><span class="pln"> </span><span class="typ">RosterStart</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">@IntervalDays</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">RosterEnd</span><span class="pun">,</span><span class="pln">
       CASE </span><span class="typ">TeamA</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="str">'RR'</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="str">'DS'</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="str">'NS'</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamA</span><span class="pun">,</span><span class="pln">
       CASE </span><span class="typ">TeamB</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="str">'RR'</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="str">'DS'</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="str">'NS'</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamB</span><span class="pun">,</span><span class="pln">
       CASE </span><span class="typ">TeamC</span><span class="pln"> WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="str">'RR'</span><span class="pln"> WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="str">'DS'</span><span class="pln"> WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="str">'NS'</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">TeamC</span><span class="pln">
FROM roster</span></pre>

<p>
	النتيجة المُعادة:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="36214" href="https://academy.hsoub.com/uploads/monthly_2020_04/rm2xk.jpg.392101026b1cb2e72ec2d535d1e1a3ee.jpg" rel=""><img alt="rm2xk.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="36214" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_04/rm2xk.jpg.392101026b1cb2e72ec2d535d1e1a3ee.jpg"></a>
</p>

<h2>
	استخدام CONNECT BY في Oracle مع تعبير جدولي عودي
</h2>

<p>
	توفّر الوظيفة <code>CONNECT BY</code> المُستخدمة في Oracle العديد من الميزات المفيدة التي لا يوجد لها مثيل في التعبيرات الجدولية العودية القياسية في SQL.
</p>

<p>
	يحاول هذا المثال محاكاة هذه الميزات (مع بعض الإضافات التكميلية) باستخدام صياغة SQL Server. هذه الوظائف مفيدة للغاية لمطوّري Oracle - إذ توفّر لهم العديد من الميزات في الاستعلامات المتشعبة (hierarchical queries) غير الموجودة في قواعد البيانات الأخرى، كما أنّها مفيدة أيضًا في توضيح استخدامات الاستعلامات المتشعبة عمومًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8835_21" style="">
<span class="pln"> WITH tbl AS </span><span class="pun">(</span><span class="pln">
     SELECT id</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> parent_id
         FROM mytable</span><span class="pun">)</span><span class="pln">
 </span><span class="pun">,</span><span class="pln">     tbl_hierarchy AS </span><span class="pun">(</span><span class="pln">
     </span><span class="com">/* Anchor */</span><span class="pln">
     SELECT </span><span class="lit">1</span><span class="pln"> AS </span><span class="str">"LEVEL"</span><span class="pln">
         </span><span class="pun">--,</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AS CONNECT_BY_ISROOT
         </span><span class="pun">--,</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> AS CONNECT_BY_ISBRANCH
         </span><span class="pun">,</span><span class="pln"> CASE WHEN t</span><span class="pun">.</span><span class="pln">id IN </span><span class="pun">(</span><span class="pln">SELECT parent_id FROM tbl</span><span class="pun">)</span><span class="pln"> THEN </span><span class="lit">0</span><span class="pln"> ELSE </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS CONNECT_BY_ISLEAF
         </span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> AS CONNECT_BY_ISCYCLE
         </span><span class="pun">,</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="pln">t</span><span class="pun">.</span><span class="pln">id AS VARCHAR</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> AS SYS_CONNECT_BY_PATH_id
         </span><span class="pun">,</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="pln">t</span><span class="pun">.</span><span class="pln">name AS VARCHAR</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> AS SYS_CONNECT_BY_PATH_name
         </span><span class="pun">,</span><span class="pln"> t</span><span class="pun">.</span><span class="pln">id AS root_id
         </span><span class="pun">,</span><span class="pln"> t</span><span class="pun">.*</span><span class="pln">
     FROM tbl t
   WHERE t</span><span class="pun">.</span><span class="pln">parent_id IS NULL </span><span class="pun">--</span><span class="pln"> START WITH parent_id IS NULL
 UNION ALL
 </span><span class="com">/* العودية*/</span><span class="pln">
 SELECT th</span><span class="pun">.</span><span class="str">"LEVEL"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AS </span><span class="str">"LEVEL"</span><span class="pln">
         </span><span class="pun">--,</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> AS CONNECT_BY_ISROOT
         </span><span class="pun">--,</span><span class="pln"> CASE WHEN t</span><span class="pun">.</span><span class="pln">id IN </span><span class="pun">(</span><span class="pln">SELECT parent_id FROM tbl</span><span class="pun">)</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln"> ELSE </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS CONNECT_BY_ISBRANCH
         </span><span class="pun">,</span><span class="pln"> CASE WHEN t</span><span class="pun">.</span><span class="pln">id IN </span><span class="pun">(</span><span class="pln">SELECT parent_id FROM tbl</span><span class="pun">)</span><span class="pln"> THEN </span><span class="lit">0</span><span class="pln"> ELSE </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS CONNECT_BY_ISLEAF
         </span><span class="pun">,</span><span class="pln"> CASE WHEN th</span><span class="pun">.</span><span class="pln">SYS_CONNECT_BY_PATH_id LIKE </span><span class="str">'%/'</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="pln">t</span><span class="pun">.</span><span class="pln">id AS VARCHAR</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'/%'</span><span class="pln">
        THEN </span><span class="lit">1</span><span class="pln"> ELSE </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> AS CONNECT_BY_ISCYCLE
         </span><span class="pun">,</span><span class="pln"> th</span><span class="pun">.</span><span class="pln">SYS_CONNECT_BY_PATH_id </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="pln">t</span><span class="pun">.</span><span class="pln">id AS VARCHAR</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> AS SYS_CONNECT_BY_PATH_id
         </span><span class="pun">,</span><span class="pln"> th</span><span class="pun">.</span><span class="pln">SYS_CONNECT_BY_PATH_name </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="pln">t</span><span class="pun">.</span><span class="pln">name AS VARCHAR</span><span class="pun">(</span><span class="pln">MAX</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'/'</span><span class="pln"> AS     SYS_CONNECT_BY_PATH_name
         </span><span class="pun">,</span><span class="pln"> th</span><span class="pun">.</span><span class="pln">root_id
         </span><span class="pun">,</span><span class="pln"> t</span><span class="pun">.*</span><span class="pln">
     FROM tbl t
         JOIN tbl_hierarchy th ON </span><span class="pun">(</span><span class="pln">th</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> t</span><span class="pun">.</span><span class="pln">parent_id</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> CONNECT BY PRIOR id </span><span class="pun">=</span><span class="pln"> parent_id
     WHERE th</span><span class="pun">.</span><span class="pln">CONNECT_BY_ISCYCLE </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> NOCYCLE
SELECT th</span><span class="pun">.*</span><span class="pln">
 </span><span class="pun">--,</span><span class="pln"> REPLICATE</span><span class="pun">(</span><span class="str">' '</span><span class="pun">,</span><span class="pln"> </span><span class="pun">(</span><span class="pln">th</span><span class="pun">.</span><span class="str">"LEVEL"</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> th</span><span class="pun">.</span><span class="pln">name AS tbl_hierarchy
     FROM tbl_hierarchy th
     JOIN tbl CONNECT_BY_ROOT ON </span><span class="pun">(</span><span class="pln">CONNECT_BY_ROOT</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> th</span><span class="pun">.</span><span class="pln">root_id</span><span class="pun">)</span><span class="pln">
  ORDER BY th</span><span class="pun">.</span><span class="pln">SYS_CONNECT_BY_PATH_name</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> ORDER SIBLINGS BY name</span></pre>

<p>
	هذا شرح لميزات <code>CONNECT BY</code> الموضّحة أعلاه:
</p>

<ul>
<li>
		العبارات
		<ul>
<li>
				<code>CONNECT BY</code>: تحدّد العلاقة التي تعرّف التشعّب
			</li>
			<li>
				<code>START WITH</code>: تحدّد العقدة الجذرية (root nodes).
			</li>
			<li>
				<code>ORDER SIBLINGS BY</code>: تحدّد ترتيب النتائج
			</li>
		</ul>
</li>
	<li>
		المعاملات
		<ul>
<li>
				<code>NOCYCLE</code>: توقِف معالجة فرع معيّن عند رصد شعبة دورية (loop). لأنّ الشعب الصالحة هي الشعب غير الدورية (Directed Acyclic)، أي الشعب التي لا يمكن العودة عبرها إلى العقدة نفسها.
			</li>
		</ul>
</li>
	<li>
		العمليات
		<ul>
<li>
				<code>PRIOR</code>: تحصل على البيانات من العقدة الأب (node's parent).
			</li>
			<li>
				<code>CONNECT_BY_ROOT</code>: تحصل على البيانات من العقدة الجذرية.
			</li>
		</ul>
</li>
	<li>
		أشباه الأعمدة Pseudocolumns
		<ul>
<li>
				<code>LEVEL</code>: تشير إلى مسافة العقدة من جذرها.
			</li>
			<li>
				<code>CONNECT_BY_ISLEAF</code>: تشير إلى عقدة بدون فروعها.
			</li>
			<li>
				<code>CONNECT_BY_ISCYCLE</code>: تشير إلى عقدة ذات مرجع دائري (circular reference).
			</li>
		</ul>
</li>
	<li>
		الدوال
		<ul>
<li>
				<code>SYS_CONNECT_BY_PATH</code>: تعيد سلسلة نصية تمثّل المسار من الجذر إلى العقدة.
			</li>
		</ul>
</li>
</ul>
<p>
	ترجمة -وبتصرّف- للفصل 46 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%81%D8%B1%D9%82%D8%A9-%D9%81%D9%8A-sql-r857/" rel="">مواضيع متفرقة في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-sql-r854/" rel="">دوال التعامل مع النصوص في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب<a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel=""> ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">856</guid><pubDate>Wed, 29 Apr 2020 18:02:00 +0000</pubDate></item><item><title>&#x62F;&#x648;&#x627;&#x644; &#x627;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x627;&#x644;&#x646;&#x635;&#x648;&#x635; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-sql-r854/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/12.jpg.a64f4b90558ef6c9bf5fd1c4d18944c5.jpg" /></p>

<p>
	الدوال النصية String Functions هي دوال تُنفَّذ على قيم نصية، وتعيد إمّا قيمًا عددية أو قيمًا نصية. مثلًا، يمكن استخدام الدوال النصية لدمج البيانات، أو استخراج أجزاء من السلاسل النصية، أو موازنة السلاسل النصية أو تحويلها من الأحرف الكبيرة إلى الصغيرة، أو العكس.
</p>

<h2>
	ضم السلاسل النصية
</h2>

<p>
	في SQL القياسية ‏‎(ANSI / ISO)‎‎، يُرمز لمعامل ضمّ السلاسل النصية (string concatenation) بالرمز <code>‎||‎</code>. وهذه الصياغة مدعومة من قبل كافّة أنظمة معالجة قواعد البيانات الرئيسية خلا SQL Server:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_7" style="">
<span class="pln">SELECT </span><span class="str">'Hello'</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> </span><span class="str">'World'</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> </span><span class="str">'!'</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="typ">HelloWorld</span><span class="pun">!</span></pre>

<p>
	تدعم العديد من أنظمة معالجة قواعد البيانات الدالة <code>‎CONCAT‎</code> التي تضمّ السلاسل النصية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_9" style="">
<span class="pln">SELECT CONCAT</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'World'</span><span class="pun">);</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'HelloWorld'</span></pre>

<p>
	تدعم أيضًا بعض قواعد البيانات استخدام <code>‎CONCAT‎</code> لضمّ أكثر من سلسلتين نصيتين (باستثناء Oracle):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_11" style="">
<span class="pln">SELECT CONCAT</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'World'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'!'</span><span class="pun">);</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'HelloWorld!'</span></pre>

<p>
	في بعض أنظمة معالجة قواعد البيانات، يجب تحويل الأنواع غير النصبة قبل ضمّها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_13" style="">
<span class="pln">SELECT CONCAT</span><span class="pun">(</span><span class="str">'Foo'</span><span class="pun">,</span><span class="pln"> CAST</span><span class="pun">(</span><span class="lit">42</span><span class="pln"> AS VARCHAR</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)),</span><span class="pln"> </span><span class="str">'Bar'</span><span class="pun">);</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'Foo42Bar'</span></pre>

<p>
	تجري بعض قواعد البيانات (مثل Oracle) تحويلات ضمنيّة غير مُفرِِّطة (implicit lossless conversions)، أي لا ينتج عنها أيّ ضياع للبيانات. على سبيل المثال، يعيد تطبيق الدالة <code>‎CONCAT‎</code> على النوعين <code>‎CLOB‎</code> و <code>‎NCLOB‎</code> قيمة من النوع <code>‎NCLOB‎</code>. فيما يعيد تطبيق الدالة <code>‎CONCAT‎</code> على عدد، وعلى قيمةٍ من النوع <code>‎varchar2‎</code> قيمةً من النوع <code>‎varchar2‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_15" style="">
<span class="pln">SELECT CONCAT</span><span class="pun">(</span><span class="pln">CONCAT</span><span class="pun">(</span><span class="str">'Foo'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">42</span><span class="pun">),</span><span class="pln"> </span><span class="str">'Bar'</span><span class="pun">)</span><span class="pln"> FROM dual</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="typ">Foo42Bar</span></pre>

<p>
	يمكن لبعض قواعد البيانات استخدام المعامل <code>‎+‎</code> غير القياسي (في معظم الأحيان مع الأعداد وحسب):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_17" style="">
<span class="pln">SELECT </span><span class="str">'Foo'</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> CAST</span><span class="pun">(</span><span class="lit">42</span><span class="pln"> AS VARCHAR</span><span class="pun">(</span><span class="lit">5</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">'Bar'</span><span class="pun">;</span></pre>

<p>
	لا تدعم إصدارات SQL Server قبل 2012 الدالة <code>‎CONCAT‎</code>، لذا فإنّ المعامل <code>‎+‎</code> هو الطريقة الوحيدة لضمّ السلاسل النصية فيها:
</p>

<h3>
	طول سلسلة نصية
</h3>

<p>
	<strong>SQL Server</strong>
</p>

<p>
	تُستخدم الدالة <code>LEN</code> لحساب طول سلسلة نصية، بيد أنّها لا تحسُب المسافات البيضاء الزائدة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_19" style="">
<span class="pln">SELECT LEN</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">5</span><span class="pln">
SELECT LEN</span><span class="pun">(</span><span class="str">'Hello '</span><span class="pun">);</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">5</span></pre>

<p>
	على خلاف <code>LEN</code>، تحسب الدالة <code>DATALENGTH</code> طول سلسلة نصية بما فيها المسافات الزائدة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_21" style="">
<span class="pln">SELECT DATALENGTH</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">5</span><span class="pln">
SELECT DATALENGTH</span><span class="pun">(</span><span class="str">'Hello '</span><span class="pun">);</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">6</span></pre>

<p>
	تجدر الإشارة إلى أنّ الدالة <code>DATALENGTH</code> تُعيد طول التمثيل البتّي (byte representation) في الذاكرة للسلسلة النصية، والذي تتعلق قيمته بمجموعة المحارف (charset) المستخدمة لتخزين السلسلة النصية.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_23" style="">
<span class="pln">DECLARE </span><span class="lit">@str</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Hello '</span><span class="pln">
SELECT DATALENGTH</span><span class="pun">(</span><span class="lit">@str</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln">  </span><span class="lit">6</span><span class="pln">

DECLARE </span><span class="lit">@nstr</span><span class="pln"> nvarchar</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Hello '</span><span class="pln">   
SELECT DATALENGTH</span><span class="pun">(</span><span class="lit">@nstr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln">  </span><span class="lit">12</span></pre>

<p>
	عادة ما تكون قيم varchar عبارة عن سلسلة نصية من النوع ASCII حيث يخزن كل حرف في بايت، وعادة ما تكون قيم nvarchar عبارة عن سلسلة نصية من النوع unicode حيث يخزن كل حرف في بايتين.
</p>

<p>
	<strong>Oracle</strong>
</p>

<p>
	يستخدم نظام Oracle الدالة <code>Length</code> لحساب طول سلسلة نصية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_25" style="">
<span class="pln">SELECT </span><span class="typ">Length</span><span class="pun">(</span><span class="str">'Bible'</span><span class="pun">)</span><span class="pln"> FROM dual</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">5</span><span class="pln">
SELECT </span><span class="typ">Length</span><span class="pun">(</span><span class="str">'righteousness'</span><span class="pun">)</span><span class="pln"> FROM dual</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">13</span><span class="pln">
SELECT </span><span class="typ">Length</span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">)</span><span class="pln"> FROM dual</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> NULL</span></pre>

<h2>
	تقليم المسافات الفارغة
</h2>

<p>
	تُستخدم الدالة <code>Trim</code> لإزالة المسافات البيضاء الموجودة في بداية أو نهاية نتائج الاستعلام.
</p>

<p>
	توجد في MSSQL عدّة دوال للتقليم كما يوضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_27" style="">
<span class="pln">SELECT LTRIM</span><span class="pun">(</span><span class="str">'  Hello  '</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'Hello  '</span><span class="pln">
SELECT RTRIM</span><span class="pun">(</span><span class="str">'  Hello  '</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'  Hello'</span><span class="pln">
SELECT LTRIM</span><span class="pun">(</span><span class="pln">RTRIM</span><span class="pun">(</span><span class="str">'  Hello  '</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'Hello'</span></pre>

<p>
	هذا المثال يعمل في MySql و Oracle:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_29" style="">
<span class="pln">SELECT TRIM</span><span class="pun">(</span><span class="str">'  Hello  '</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'Hello'</span></pre>

<h2>
	الدالتان UPPER و LOWER
</h2>

<p>
	تحوّل الدالة <code>UPPER</code> سلسلة نصية إلى سلسلة نصية ذات أحرف كبيرة، أما <code>LOWER</code> فتفعل العكس:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_31" style="">
<span class="pln">SELECT UPPER</span><span class="pun">(</span><span class="str">'HelloWorld'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'HELLOWORLD'</span><span class="pln">
SELECT LOWER</span><span class="pun">(</span><span class="str">'HelloWorld'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'helloworld'</span></pre>

<h2>
	تقسيم السلاسل النصية
</h2>

<p>
	تقسّم الدالة <code>SPLIT</code> السلسلة النصية بحسب فاصل حرفي. لاحظ أنّ <code>‎STRING_SPLIT()‎</code> دالةٌ جدولية (table-valued function).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_33" style="">
<span class="pln">SELECT value FROM STRING_SPLIT</span><span class="pun">(</span><span class="str">'Lorem ipsum dolor sit amet.'</span><span class="pun">,</span><span class="pln"> </span><span class="str">' '</span><span class="pun">);</span></pre>

<p>
	سنحصل على النتيجة التالية:
</p>

<pre class="ipsCode">
value
-----
Lorem
ipsum
dolor
sit
amet.
</pre>

<h2>
	الاستبدال
</h2>

<p>
	تستبدل الدالة <code>‎REPLACE‎</code> سلسلة نصية بأخرى. وتُصاغ وفق الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_35" style="">
<span class="pln">REPLACE</span><span class="pun">(</span><span class="pln"> S </span><span class="pun">,</span><span class="pln"> O </span><span class="pun">,</span><span class="pln"> R </span><span class="pun">)</span></pre>

<ul>
<li>
		S: السلسلة النصية التي سيُبحَث فيها
	</li>
	<li>
		O: السلسلة النصية المراد استبدالها
	</li>
	<li>
		R: السلسلة النصية المراد وضعها مكان السلسلة الأصلية:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_37" style="">
<span class="pln">SELECT REPLACE</span><span class="pun">(</span><span class="pln"> </span><span class="str">'Peter Steve Tom'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Steve'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Billy'</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="typ">Peter</span><span class="pln"> </span><span class="typ">Billy</span><span class="pln"> </span><span class="typ">Tom</span></pre>

<h2>
	التعابير النمطية REGEXP
</h2>

<p>
	<strong>MySQL ≥ 3.19</strong>
</p>

<p>
	تُستخدم <code>REGEXP</code> للتحقّق ممّا إذا كانت السلسلة النصية تتطابق مع تعبير نمطي - regular expression - (داخل سلسلة نصّية أخرى).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_39" style="">
<span class="pln">SELECT </span><span class="str">'bedded'</span><span class="pln"> REGEXP </span><span class="str">'[a-f]'</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="kwd">True</span><span class="pln">
SELECT </span><span class="str">'beam'</span><span class="pln"> REGEXP </span><span class="str">'[a-f]'</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="kwd">False</span></pre>

<h2>
	السلاسل النصية الفرعية Substrings
</h2>

<p>
	تعيد الدالة <code>‎SUBSTRING</code> جزءًا من سلسلة نصية كما يوَضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_41" style="">
<span class="pln">SELECT SUBSTRING</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'He'</span><span class="pln">
SELECT SUBSTRING</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'llo'</span></pre>

<p>
	<strong>تنبيه</strong>: تبدأ فهارس السلاسل النصية في SQL من القيمة 1.
</p>

<p>
	غالبًا ما تُستخدم <code>SUBSTRING</code> مع الدّالة <code>‎LEN()‎</code> للحصول على آخر <code>‎n‎</code> حرف من سلسلة نصية ذات طول غير معروف.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_43" style="">
<span class="pln">DECLARE </span><span class="lit">@str1</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@str2</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'FooBarBaz'</span><span class="pun">;</span><span class="pln">
SELECT SUBSTRING</span><span class="pun">(</span><span class="lit">@str1</span><span class="pun">,</span><span class="pln"> LEN</span><span class="pun">(</span><span class="lit">@str1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'llo'</span><span class="pln">
SELECT SUBSTRING</span><span class="pun">(</span><span class="lit">@str2</span><span class="pun">,</span><span class="pln"> LEN</span><span class="pun">(</span><span class="lit">@str2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'Baz'</span></pre>

<h2>
	Stuff
</h2>

<p>
	تحشر الدالة <code>Stuff</code> سلسلة نصّية داخل أخرى، إذ تستبدل 0 حرف أو أكثر في موضع معين.
</p>

<p>
	<strong>تنبيه</strong>: يُحسب الموضع <code>‎start‎</code> انطلاقا من القيمة 1.
</p>

<p>
	هذه صياغة الدالة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_47" style="">
<span class="pln">STUFF </span><span class="pun">(</span><span class="pln"> character_expression </span><span class="pun">,</span><span class="pln"> start </span><span class="pun">,</span><span class="pln"> length </span><span class="pun">,</span><span class="pln"> replaceWith_expression </span><span class="pun">)</span><span class="pln"> </span></pre>

<p>
	يحشر المثال التوضيحي التالي السلسلة النصية 'Hello' في الموضع 4 من السلسلة 'FooBarBaz' ويضعها مكان <code>Bar</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_50" style="">
<span class="pln">SELECT STUFF</span><span class="pun">(</span><span class="str">'FooBarBaz'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Hello'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'FooHelloBaz'</span></pre>

<h2>
	الدالتان LEFT و RIGHT
</h2>

<p>
	تعيد الدالة RIGHT آخر n حرف من سلسلة نصية، فيما تعيد LEFT أول n حرف من سلسلة نصية:
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_52" style="">
<span class="pln">SELECT LEFT</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="typ">He</span><span class="pln">  
SELECT RIGHT</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> lo</span></pre>

<p>
	لا يحتوي نظام Oracle SQL على الدالتين <code>LEFT</code> و <code>RIGHT</code>. بيْد أنّه يمكن محاكاتهما باستخدام الدالتين <code>SUBSTR</code> و <code>LENGTH</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_54" style="">
<span class="pln">SELECT SUBSTR</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln">  </span><span class="typ">He</span><span class="pln">
SELECT SUBSTR</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln">LENGTH</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">)-</span><span class="lit">2</span><span class="pun">+</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> lo</span></pre>

<h2>
	عكس سلسلة نصية
</h2>

<p>
	تعكس الدالة <code>REVERSE</code> السلاسل النصية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_56" style="">
<span class="pln">SELECT REVERSE</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> olleH</span></pre>

<h2>
	تكرار سلسلة نصية
</h2>

<p>
	تضمّ الدالة <code>‎REPLICATE‎</code> سلسلة نصية إلى نفسها عددًا محدّدًا من المرّات كما يوضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_58" style="">
<span class="pln">SELECT REPLICATE </span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="lit">4</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln"> </span><span class="str">'HelloHelloHelloHello'</span></pre>

<h2>
	استخدام الدالة Replace مع Select و Update
</h2>

<p>
	تُستخدم الدالة <code>REPLACE</code> في SQL لتحديث محتوى سلسلة نصية. وتُستدعى هذه الدالة عبر الصياغة <code>REPLACE()‎</code> في MySQL و Oracle و SQL Server. وتُصاغ على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_60" style="">
<span class="pln">REPLACE </span><span class="pun">(</span><span class="pln">str</span><span class="pun">,</span><span class="pln"> find</span><span class="pun">,</span><span class="pln"> repl</span><span class="pun">)</span></pre>

<p>
	يستبدل المثال التالي تكرارات السلسلة النصية <code>‎South‎</code> بـ <code>‎Southern‎</code> في جدول الموظفين Employees:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				FirstName
			</th>
			<th>
				Address
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				James
			</td>
			<td>
				South New York
			</td>
		</tr>
<tr>
<td>
				John
			</td>
			<td>
				South Boston
			</td>
		</tr>
<tr>
<td>
				Michael
			</td>
			<td>
				South San Diego
			</td>
		</tr>
</tbody>
</table>
<h3>
	استخدام REPLACE مع Select
</h3>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_62" style="">
<span class="pln">SELECT
    </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln">
    REPLACE </span><span class="pun">(</span><span class="typ">Address</span><span class="pun">,</span><span class="pln"> </span><span class="str">'South'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Southern'</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Address</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
ORDER BY </span><span class="typ">FirstName</span></pre>

<p>
	سنحصل على النتيجة التالية:
</p>

<table>
<thead><tr>
<th>
				FirstName
			</th>
			<th>
				Address
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				James
			</td>
			<td>
				Southern New York
			</td>
		</tr>
<tr>
<td>
				John
			</td>
			<td>
				Southern Boston
			</td>
		</tr>
<tr>
<td>
				Michael
			</td>
			<td>
				Southern San Diego
			</td>
		</tr>
</tbody>
</table>
<h3>
	استخدام REPLACE مع Update
</h3>

<p>
	يمكننا استخدام الدالة <code>REPLACE</code> لإجراء تغييرات دائمة في الجدول على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_64" style="">
<span class="typ">Update</span><span class="pln"> </span><span class="typ">Employees</span><span class="pln">
</span><span class="typ">Set</span><span class="pln"> city </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Address</span><span class="pun">,</span><span class="pln"> </span><span class="str">'South'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Southern'</span><span class="pun">);</span></pre>

<p>
	هناك مقاربة أخرى أشهر تتمثل في استخدام <code>REPLACE</code> مع عبارة <code>WHERE</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_66" style="">
<span class="typ">Update</span><span class="pln"> </span><span class="typ">Employees</span><span class="pln">
</span><span class="typ">Set</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Address</span><span class="pun">,</span><span class="pln"> </span><span class="str">'South'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Southern'</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Where</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> LIKE </span><span class="str">'South%'</span><span class="pun">;</span></pre>

<h2>
	INSTR
</h2>

<p>
	تعيد هذه الدالة فهرس أول ظهور لسلسلة نصية فرعية (أو تعيد 0 إن لم يُعثر عليها).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_68" style="">
<span class="pln">SELECT INSTR</span><span class="pun">(</span><span class="str">'FooBarBar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bar'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">4</span><span class="pln">
SELECT INSTR</span><span class="pun">(</span><span class="str">'FooBarBar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Xar'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">0</span></pre>

<h2>
	PARSENAME
</h2>

<p>
	<strong>SQL Server</strong>
</p>

<p>
	تعيد الدالة <code>PARSENAME</code> جزءًا محدّدًا من كائن نصي - string(object name)‎‎ -. قد يحتوي اسم الكائن - object name - على اسم كائن شبه نصّي (string like object)، أو اسم المالك (owner name) أو اسم قاعدة البيانات أو اسم الخادم. يمكنك معرفة المزيد من التفاصيل من الرابط:<br><a href="https://msdn.microsoft.com/en-us/library/ms188006.aspx" rel="external nofollow">MSDN:PARSENAME</a>
</p>

<p>
	هذه صياغة الدالة <code>PARSENAME</code>:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_232_70" style="">
<span class="pln">PARSENAME</span><span class="pun">(</span><span class="str">'NameOfStringToParse'</span><span class="pun">,</span><span class="typ">PartIndex</span><span class="pun">)</span></pre>

<ul>
<li>
		يمكنك العثور على اسم الكائن، في الفهرس رقم <code>‎1‎</code>:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_72" style="">
<span class="pln">SELECT PARSENAME</span><span class="pun">(</span><span class="str">'ServerName.DatabaseName.SchemaName.ObjectName'</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`ObjectName`</span><span class="pln">
SELECT PARSENAME</span><span class="pun">(</span><span class="str">'[1012-1111].SchoolDatabase.school.Student'</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`Student`</span></pre>

<ul>
<li>
		للحصول على اسم المخطط (schema)، استخدم الفهرس <code>‎2‎</code>:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_74" style="">
<span class="pln">SELECT PARSENAME</span><span class="pun">(</span><span class="str">'ServerName.DatabaseName.SchemaName.ObjectName'</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`SchemaName`</span><span class="pln">
SELECT PARSENAME</span><span class="pun">(</span><span class="str">'[1012-1111].SchoolDatabase.school.Student'</span><span class="pun">,</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`school`</span></pre>

<ul>
<li>
		للحصول على اسم قاعدة البيانات، استخدم الفهرس <code>‎3‎</code>:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_76" style="">
<span class="pln">SELECT PARSENAME</span><span class="pun">(</span><span class="str">'ServerName.DatabaseName.SchemaName.ObjectName'</span><span class="pun">,</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`DatabaseName`</span><span class="pln">
SELECT PARSENAME</span><span class="pun">(</span><span class="str">'[1012-1111].SchoolDatabase.school.Student'</span><span class="pun">,</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`SchoolDatabase`</span></pre>

<ul>
<li>
		للحصول على اسم الخادم، استخدم الفهرس <code>‎4‎</code>:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_232_78" style="">
<span class="pln">SELECT PARSENAME</span><span class="pun">(</span><span class="str">'ServerName.DatabaseName.SchemaName.ObjectName'</span><span class="pun">,</span><span class="lit">4</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`ServerName`</span><span class="pln">
SELECT PARSENAME</span><span class="pun">(</span><span class="str">'[1012-1111].SchoolDatabase.school.Student'</span><span class="pun">,</span><span class="lit">4</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">`[1012-1111]`</span></pre>

<p>
	تعيد <code>PARSENAME</code> قيمة معدومة (null) في حال كان الجزء المُعيّن غير موجود في الكائن النصي.
</p>

<p>
	ترجمة -وبتصرّف- للفصل 41 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D8%AC%D8%AF%D9%88%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-common-table-expressions-%D9%81%D9%8A-sql-r856/" rel="">التعابير الجدولية الشائعة Common Table Expressions في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r855/" rel="">دوال التعامل مع البيانات في SQL</a>
	</li>
	<li>
		النسخة الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">854</guid><pubDate>Sat, 25 Apr 2020 18:08:00 +0000</pubDate></item></channel></rss>
