اذهب إلى المحتوى

دوال التعامل مع النصوص في SQL


محمد بغات

الدوال النصية String Functions هي دوال تُنفَّذ على قيم نصية، وتعيد إمّا قيمًا عددية أو قيمًا نصية. مثلًا، يمكن استخدام الدوال النصية لدمج البيانات، أو استخراج أجزاء من السلاسل النصية، أو موازنة السلاسل النصية أو تحويلها من الأحرف الكبيرة إلى الصغيرة، أو العكس.

ضم السلاسل النصية

في SQL القياسية ‏‎(ANSI / ISO)‎‎، يُرمز لمعامل ضمّ السلاسل النصية (string concatenation) بالرمز ‎||‎. وهذه الصياغة مدعومة من قبل كافّة أنظمة معالجة قواعد البيانات الرئيسية خلا SQL Server:

SELECT 'Hello' || 'World' || '!'; -- ==> HelloWorld!

تدعم العديد من أنظمة معالجة قواعد البيانات الدالة ‎CONCAT‎ التي تضمّ السلاسل النصية:

SELECT CONCAT('Hello', 'World'); -- ==> 'HelloWorld'

تدعم أيضًا بعض قواعد البيانات استخدام ‎CONCAT‎ لضمّ أكثر من سلسلتين نصيتين (باستثناء Oracle):

SELECT CONCAT('Hello', 'World', '!'); -- ==> 'HelloWorld!'

في بعض أنظمة معالجة قواعد البيانات، يجب تحويل الأنواع غير النصبة قبل ضمّها:

SELECT CONCAT('Foo', CAST(42 AS VARCHAR(5)), 'Bar'); -- ==> 'Foo42Bar'

تجري بعض قواعد البيانات (مثل Oracle) تحويلات ضمنيّة غير مُفرِِّطة (implicit lossless conversions)، أي لا ينتج عنها أيّ ضياع للبيانات. على سبيل المثال، يعيد تطبيق الدالة ‎CONCAT‎ على النوعين ‎CLOB‎ و ‎NCLOB‎ قيمة من النوع ‎NCLOB‎. فيما يعيد تطبيق الدالة ‎CONCAT‎ على عدد، وعلى قيمةٍ من النوع ‎varchar2‎ قيمةً من النوع ‎varchar2‎:

SELECT CONCAT(CONCAT('Foo', 42), 'Bar') FROM dual; -- ==> Foo42Bar

يمكن لبعض قواعد البيانات استخدام المعامل ‎+‎ غير القياسي (في معظم الأحيان مع الأعداد وحسب):

SELECT 'Foo' + CAST(42 AS VARCHAR(5)) + 'Bar';

لا تدعم إصدارات SQL Server قبل 2012 الدالة ‎CONCAT‎، لذا فإنّ المعامل ‎+‎ هو الطريقة الوحيدة لضمّ السلاسل النصية فيها:

طول سلسلة نصية

SQL Server

تُستخدم الدالة LEN لحساب طول سلسلة نصية، بيد أنّها لا تحسُب المسافات البيضاء الزائدة.

SELECT LEN('Hello') -- 5
SELECT LEN('Hello '); -- 5

على خلاف LEN، تحسب الدالة DATALENGTH طول سلسلة نصية بما فيها المسافات الزائدة:

SELECT DATALENGTH('Hello') -- 5
SELECT DATALENGTH('Hello '); -- 6

تجدر الإشارة إلى أنّ الدالة DATALENGTH تُعيد طول التمثيل البتّي (byte representation) في الذاكرة للسلسلة النصية، والذي تتعلق قيمته بمجموعة المحارف (charset) المستخدمة لتخزين السلسلة النصية.

DECLARE @str varchar(100) = 'Hello '
SELECT DATALENGTH(@str) --  6

DECLARE @nstr nvarchar(100) = 'Hello '   
SELECT DATALENGTH(@nstr) --  12

عادة ما تكون قيم varchar عبارة عن سلسلة نصية من النوع ASCII حيث يخزن كل حرف في بايت، وعادة ما تكون قيم nvarchar عبارة عن سلسلة نصية من النوع unicode حيث يخزن كل حرف في بايتين.

Oracle

يستخدم نظام Oracle الدالة Length لحساب طول سلسلة نصية:

SELECT Length('Bible') FROM dual; -- 5
SELECT Length('righteousness') FROM dual; -- 13
SELECT Length(NULL) FROM dual; -- NULL

تقليم المسافات الفارغة

تُستخدم الدالة Trim لإزالة المسافات البيضاء الموجودة في بداية أو نهاية نتائج الاستعلام.

توجد في MSSQL عدّة دوال للتقليم كما يوضّح المثال التالي:

SELECT LTRIM('  Hello  ') -- ==> 'Hello  '
SELECT RTRIM('  Hello  ') -- ==> '  Hello'
SELECT LTRIM(RTRIM('  Hello  ')) -- ==> 'Hello'

هذا المثال يعمل في MySql و Oracle:

SELECT TRIM('  Hello  ') -- ==> 'Hello'

الدالتان UPPER و LOWER

تحوّل الدالة UPPER سلسلة نصية إلى سلسلة نصية ذات أحرف كبيرة، أما LOWER فتفعل العكس:

SELECT UPPER('HelloWorld') -- ==> 'HELLOWORLD'
SELECT LOWER('HelloWorld') -- ==> 'helloworld'

تقسيم السلاسل النصية

تقسّم الدالة SPLIT السلسلة النصية بحسب فاصل حرفي. لاحظ أنّ ‎STRING_SPLIT()‎ دالةٌ جدولية (table-valued function).

SELECT value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');

سنحصل على النتيجة التالية:

value
-----
Lorem
ipsum
dolor
sit
amet.

الاستبدال

تستبدل الدالة ‎REPLACE‎ سلسلة نصية بأخرى. وتُصاغ وفق الشكل التالي:

REPLACE( S , O , R )
  • S: السلسلة النصية التي سيُبحَث فيها
  • O: السلسلة النصية المراد استبدالها
  • R: السلسلة النصية المراد وضعها مكان السلسلة الأصلية:
SELECT REPLACE( 'Peter Steve Tom', 'Steve', 'Billy' ) -- Peter Billy Tom

التعابير النمطية REGEXP

MySQL ≥ 3.19

تُستخدم REGEXP للتحقّق ممّا إذا كانت السلسلة النصية تتطابق مع تعبير نمطي - regular expression - (داخل سلسلة نصّية أخرى).

SELECT 'bedded' REGEXP '[a-f]' -- True
SELECT 'beam' REGEXP '[a-f]' -- False

السلاسل النصية الفرعية Substrings

تعيد الدالة ‎SUBSTRING جزءًا من سلسلة نصية كما يوَضّح المثال التالي:

SELECT SUBSTRING('Hello', 1, 2) -- ==> 'He'
SELECT SUBSTRING('Hello', 3, 3) -- ==> 'llo'

تنبيه: تبدأ فهارس السلاسل النصية في SQL من القيمة 1.

غالبًا ما تُستخدم SUBSTRING مع الدّالة ‎LEN()‎ للحصول على آخر ‎n‎ حرف من سلسلة نصية ذات طول غير معروف.

DECLARE @str1 VARCHAR(10) = 'Hello', @str2 VARCHAR(10) = 'FooBarBaz';
SELECT SUBSTRING(@str1, LEN(@str1) - 2, 3) -- ==> 'llo'
SELECT SUBSTRING(@str2, LEN(@str2) - 2, 3) -- ==> 'Baz'

Stuff

تحشر الدالة Stuff سلسلة نصّية داخل أخرى، إذ تستبدل 0 حرف أو أكثر في موضع معين.

تنبيه: يُحسب الموضع ‎start‎ انطلاقا من القيمة 1.

هذه صياغة الدالة:

STUFF ( character_expression , start , length , replaceWith_expression ) 

يحشر المثال التوضيحي التالي السلسلة النصية 'Hello' في الموضع 4 من السلسلة 'FooBarBaz' ويضعها مكان Bar:

SELECT STUFF('FooBarBaz', 4, 3, 'Hello') -- ==> 'FooHelloBaz'

الدالتان LEFT و RIGHT

تعيد الدالة RIGHT آخر n حرف من سلسلة نصية، فيما تعيد LEFT أول n حرف من سلسلة نصية:

إليك المثال التالي:

SELECT LEFT('Hello',2) -- He  
SELECT RIGHT('Hello',2) -- lo

لا يحتوي نظام Oracle SQL على الدالتين LEFT و RIGHT. بيْد أنّه يمكن محاكاتهما باستخدام الدالتين SUBSTR و LENGTH على النحو التالي:

SELECT SUBSTR('Hello',1,2) --  He
SELECT SUBSTR('Hello',LENGTH('Hello')-2+1,2) -- lo

عكس سلسلة نصية

تعكس الدالة REVERSE السلاسل النصية:

SELECT REVERSE('Hello') -- ==> olleH

تكرار سلسلة نصية

تضمّ الدالة ‎REPLICATE‎ سلسلة نصية إلى نفسها عددًا محدّدًا من المرّات كما يوضّح المثال التالي:

SELECT REPLICATE ('Hello',4) -- ==> 'HelloHelloHelloHello'

استخدام الدالة Replace مع Select و Update

تُستخدم الدالة REPLACE في SQL لتحديث محتوى سلسلة نصية. وتُستدعى هذه الدالة عبر الصياغة REPLACE()‎ في MySQL و Oracle و SQL Server. وتُصاغ على النحو التالي:

REPLACE (str, find, repl)

يستبدل المثال التالي تكرارات السلسلة النصية ‎South‎ بـ ‎Southern‎ في جدول الموظفين Employees:

FirstName Address
James South New York
John South Boston
Michael South San Diego

استخدام REPLACE مع Select

إليك الاستعلام التالي:

SELECT
    FirstName,
    REPLACE (Address, 'South', 'Southern') Address
FROM Employees
ORDER BY FirstName

سنحصل على النتيجة التالية:

FirstName Address
James Southern New York
John Southern Boston
Michael Southern San Diego

استخدام REPLACE مع Update

يمكننا استخدام الدالة REPLACE لإجراء تغييرات دائمة في الجدول على النحو التالي:

Update Employees
Set city = (Address, 'South', 'Southern');

هناك مقاربة أخرى أشهر تتمثل في استخدام REPLACE مع عبارة WHERE على النحو التالي:

Update Employees
Set Address = (Address, 'South', 'Southern')
Where Address LIKE 'South%';

INSTR

تعيد هذه الدالة فهرس أول ظهور لسلسلة نصية فرعية (أو تعيد 0 إن لم يُعثر عليها).

SELECT INSTR('FooBarBar', 'Bar') -- 4
SELECT INSTR('FooBarBar', 'Xar') -- 0

PARSENAME

SQL Server

تعيد الدالة PARSENAME جزءًا محدّدًا من كائن نصي - string(object name)‎‎ -. قد يحتوي اسم الكائن - object name - على اسم كائن شبه نصّي (string like object)، أو اسم المالك (owner name) أو اسم قاعدة البيانات أو اسم الخادم. يمكنك معرفة المزيد من التفاصيل من الرابط:
MSDN:PARSENAME

هذه صياغة الدالة PARSENAME:

PARSENAME('NameOfStringToParse',PartIndex)
  • يمكنك العثور على اسم الكائن، في الفهرس رقم ‎1‎:
SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',1) -- `ObjectName`
SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',1) -- `Student`
  • للحصول على اسم المخطط (schema)، استخدم الفهرس ‎2‎:
SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',2) -- `SchemaName`
SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',2) -- `school`
  • للحصول على اسم قاعدة البيانات، استخدم الفهرس ‎3‎:
SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',3) -- `DatabaseName`
SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',3) -- `SchoolDatabase`
  • للحصول على اسم الخادم، استخدم الفهرس ‎4‎:
SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',4) -- `ServerName`
SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',4) -- `[1012-1111]`

تعيد PARSENAME قيمة معدومة (null) في حال كان الجزء المُعيّن غير موجود في الكائن النصي.

ترجمة -وبتصرّف- للفصل 41 من الكتاب SQL Notes for Professionals

اقرأ أيضًا:


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...