המשימה לכאורה פשוטה- הפונקציה המוכרת המבצעת זאת היא Len, אלא שהיא עלולה להכשיל אותנו מכיוון שהיא אינה סופרת את הרווחים המובילים והמסיימים, ובמילים אחרות- מבצעת למחרוזת Trim ורק אז בודקת את אורכה.
ציטוט מה-BOL:
LEN (string_expression): Returns the number of characters of the specified string expression, excluding trailing blanks.
Note: To return the number of bytes used to represent an expression, use the DATALENGTH function.
ומה אומר ה-BOL על DataLength?
DATALENGTH (expression) : Returns the number of bytes used to represent any expression.
כמו בהרבה מקרים אחרים- יש לקרוא את האותיות הקטנות: Len סופר תווים (ללא רווחים מובילים ומסיימים)
ו-DataLength סופר Bytes.
ההבדל הוא שבסוגי נתונים כדוגמת Char או Varchar כל תו הוא Byte,
אולם ב-NChar או NVarchar כל תו הוא שני Bytes:
Select Len('ABCD ') [Len_Varchar],
DataLength('ABCD ') [DataLen_Varchar],
Len(N'ABCD ') [Len_NVarchar],
DataLength(N'ABCD ') [DataLen_NVarchar];
לפיכך יש לשים לב לשתי נקודות:
אין טעם להשתמש ב-NVarchar כשניתן להשתמש ב-Varchar: גם עולה יותר וגם יש לו תופעות לוואי לא נעימות.
אם אין ברירה ורוצים למצוא את אורך המחרוזת כולל הרווחים (ללא קשר לשאלה אם זה Unicode או לא)- אפשר להסתבך כך:
Declare @S NVarchar(Max);
Select @S='ABCD ';
Select Len('#'+@S+'#')-2 [Length];
לחילופין אפשר להמיר את כל הרווחים לתווים אחרים על ידי Replace או לבצע Cast ל-Varchar ואז להשתמש ב-DataLength ועוד.
למי שיש רעיון יותר פשוט – אשמח לשמוע..