
در حین بروز استثناهای Entity framework، میتوان توسط ابزارهای Logging متنوعی مانند ELMAH، جزئیات متداول آنها را برای بررسیهای آتی ذخیره کرد. اما این جزئیات فاقد SQL نهایی تولیدی و همچنین پارامترهای ورودی توسط کاربر یا تنظیم شده توسط برنامه هستند. برای اینکه بتوان این جزئیات را نیز ثبت کرد، میتوان یک IDbCommandInterceptor جدید را طراحی کرد.
کلاس EfExceptionsInterceptor
در اینجا نمونهای از یک پیاده سازی اینترفیس IDbCommandInterceptor را مشاهده میکنید. همچنین طراحی یک متد عمومی که میتواند به جزئیات SQL نهایی و پارامترهای آن دسترسی داشته باشد، در اینترفیس IEfExceptionsLogger ذکر شدهاست
public interface IEfExceptionsLogger
{
void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext);
}
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
namespace ElmahEFLogger
{
public class EfExceptionsInterceptor : IDbCommandInterceptor
{
private readonly IEfExceptionsLogger _efExceptionsLogger;
public EfExceptionsInterceptor(IEfExceptionsLogger efExceptionsLogger)
{
_efExceptionsLogger = efExceptionsLogger;
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
}
}
تهیه یک پیاده سازی سفارشی از IEfExceptionsLogger توسط ELMAH
اکنون که ساختار کلی IDbCommandInterceptor سفارشی برنامه مشخص شد، میتوان پیاده سازی خاصی از آنرا جهت استفاده از ELMAH به نحو ذیل ارائه داد:
using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using Elmah;
namespace ElmahEFLogger.CustomElmahLogger
{
public class ElmahEfExceptionsLogger : IEfExceptionsLogger
{
/// <summary>
/// Manually log errors using ELMAH
/// </summary>
public void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext)
{
var ex = interceptionContext.OriginalException;
if (ex == null)
return;
var sqlData = CommandDumper.LogSqlAndParameters(command, interceptionContext);
var contextualMessage = string.Format(“{0}{1}OriginalException:{1}{2} {1}”, sqlData, Environment.NewLine, ex);
if (!string.IsNullOrWhiteSpace(contextualMessage))
{
ex = new Exception(contextualMessage, new ElmahEfInterceptorException(ex.Message));
}
try
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
catch
{
ErrorLog.GetDefault(null).Log(new Error(ex));
}
}
}
}
در اینجا شیء Command به همراه SQL نهایی تولید و پارامترهای مرتبط است. همچنین interceptionContext.OriginalException جزئیات عمومی استثنای رخ داده را به همراه دارد. میتوان این اطلاعات را پس از اندکی نظم بخشیدن، به متد Raise مربوط به ELMAH ارسال کرد تا جزئیات بیشتری از استثنای رخ داده شده، در لاگهای آن ظاهر شوند.
استفاده از ElmahEfExceptionsLogger جهت طراحی یک Interceptor عمومی
public class ElmahEfInterceptor : EfExceptionsInterceptor
{
public ElmahEfInterceptor()
: base(new ElmahEfExceptionsLogger())
{ }
}
برای استفاده از ElmahEfExceptionsLogger و تهیه یک Interceptor عمومی، میتوان با ارث بری از کلاس Interceptor ابتدای بحث شروع کرد و وهلهای از ElmahEfExceptionsLogger را به سازندهی آن تزریق نمود (یکی از چندین روش ممکن). سپس برای استفاده از آن کافی است به ابتدای متد Application_Start فایل Global.asax.cs مراجعه و در ادامه سطر ذیل را اضافه نمود:
DbInterception.Add(new ElmahEfInterceptor());
پس از آن جزئیات کلیه استثناهای EF در لاگهای نهایی ELMAH به نحو ذیل ظاهر خواهند شد:

یکی از مباحثی که به نظرم هر دانشجوی رشته کامپیوتر، فناوری اطلاعات و علاقمند به این حوزه باید بداند بحث کاراکترهاست؛ جدا از اینکه همه ما در مورد وجود ascii یا UTF-8 و … و توضیحات مختصر آن اطلاع داریم ولی عدهای از دوستان مثل من هنوز اطلاعات پایهایتر و جامعتری در این باره نداریم؛ در این مقاله که برداشتی از وب سایت smashing magazine و W3 است به این مبحث میپردازیم.
کامپیوترها تنها با اعداد سر و کار دارند نه با حروف؛ پس این بسیار مهم هست که همه کامپیوترها بر روی یک سری اعداد مشخص به عنوان نمایندهای از حروف به توافق برسند. این توافق یکسان بین همه کامپیوترها بسیار مهم هست و باید طبق یک استاندارد مشترک استفاده شود تا در همه سیستمها قابل استفاده و انتقال باشد؛ برای همین در سال ۱۹۶۰ اتحادیه استاندارهای آمریکا، یک سیستم رمزگذاری ۷ بیتی را ایجاد کرد؛ به نام American Standard Code for Information Interchange یا کد استاندارد سازی شده آمریکایی برای تبادل اطلاعات یا همان ASCII. این هفت بیت به ما اجازه میداد تا ۱۲۸ حرف را کدگذاری کنیم. این مقدار برای حروف کوچک و بزرگ انگلیسی و هم چنین حروف لاتین، همراه با کدگذاری ارقام و یک سری علائم نگارشی و کاراکترهایی از قبیل space ، tab و موارد مشابه و نهایتا کلیدهای کنترلی کافی بود. در سال ۱۹۶۸ این استاندارد توسط رییس جمهور وقت آمریکا لیندون جانسون به رسمیت شناخته شده و همه سیستمهای کامپیوتری ملزم به رعایت و استفاده از این استاندارد شدند.
برای لیست کردن و دیدن این کدها و نمادهای حرفیشان میتوان با یک زبان برنامه نویسی یا اسکریپتی آنها را لیست کرد. کد زیر نمونهای از کد نوشته شده در جاوااسکریپت است.
<html>
<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>
<script type=”text/javascript”>
for (var i=0; i<128; i++) document.writeln ((i%32?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);
</script>
</body>
</html>
در سالهای بعدی، با قویتر شدن پردازشگرها و ۸ بیت شدن یک بایت به جای ذخیره ۱۲۸ عدد توانستند ۲۵۶ عدد را ذخیره کنند ولی استاندارد اسکی تا ۱۲۸ کد ایجاد شده بود و مابقی را به عنوان ذخیره نگاه داشتند. در ابتدا کامپیوترهای IBM از آنها برای ایجاد نمادهای اضافهتر و همچنین اشکال استفاده میکرد؛ مثلا کد ۲۰۰ شکل ╚ بود که احتمالا برنامه نویسان زمان داس، این شکل را به خوبی به خاطر میاورند یا مثلا حروف یونانی را اضافه کردند که با کد ۲۲۴ شکل آلفا α بود و بعدها به عنوان code page 437 نامگذاری شد. هر چند که هرگز مانند اسکی به یک استاندارد تبدیل نشد و بسیاری از کشورها از این فضای اضافی برای استانداردسازی حروف خودشان استفاده میکردند و در کشورها کدپیجهای مختلفی ایجاد شد. برای مثال در روسیه کد پیچ ۸۸۵ از کد ۲۲۴ برای نمایش Я بهره میبرد و در کد پیچ یونانی ۷۳۷ برای نمایش حرف کوچک امگا ω استفاده میشد. این کار ادامه داشت تا زمانیکه مایکروسافت در سال ۱۹۸۰ کد پیچ Windows-1251 الفبای سریلیک را ارئه کرد. این تلاش تا سال ۱۹۹۰ ادامه پیدا کرد و تا آن زمان ۱۵ کدپیج مختلف استاندارسازی شده برای الفبایی چون سیریلیک، عربی، عبری و … ایجاد شد که این استانداردها از ISO-8859-1 شروع و تا ISO-8859-16 ادامه داشت و موقعی که فرستنده پیامی را ارسال میکرد، گیرنده باید از کدپیج مورد نظر مطلع میبود تا بتواند پیام را صحیح بخواند.
بیایید با یک برنامه علائم را در این ۱۵ استاندارد بررسی کنیم. تکه کدی که من در اینجا نوشتم یک لیست را که در آن اعداد یک تا ۱۶ لیست شده است، نشان میدهد که با انتخاب هر کدام، کدها را از ۰ تا ۲۵۵ بر اساس هر استاندارد به ترتیب نمایش میدهد. این کار توسط تعیین استاندارد در تگ متا رخ میدهد.
در زمان بارگذاری، استانداردها با کد زیر به لیست اضافه میشوند.در مرحله بعد لیستی که postback را در آن فعال کردهایم، کد زیر را اجرا میکند. در این کد ابتدا charset انتخاب شده ایجاد شده و سپس یکی یکی کدها را به کاراکتر تبدیل میکنیم و رشته نهایی را درج میکنیم
private String ISO = “ISO-8859-“;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 1; i < 16; i++)
{
ListItem item = new ListItem();
item.Text = ISO + i.ToString();
item.Value = i.ToString();
DropDownList1.Items.Add(item);
}
ShowCodes(1);
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedItem != null)
{
int value = int.Parse(DropDownList1.SelectedValue);
ShowCodes(value);
}
}
private void ShowCodes(int value)
{
Response.Charset = ISO + value;
string s = “”;
for (int i = 0; i < 256; i++)
{
char ch = (char)i;
s += i + “-” + ch;
s += “
“;//br tag
}
Label1.Text = s;
}
تقریبا سال ۱۹۹۰ بود که بسیاری از اسناد به همین شیوهها نوشته و ذخیره شد. ولی باز برای بسیاری از زبانها، حتی داشتن یکی دو حرف بیشتر مشکلاتی را به همراه داشت. مثلا حروف بعضی زبانها مثل چینی و ژاپنی چینی که ۲۵۶ عدد، پاسخگو نبود و با آمدن شبکهای چون اینترنت و بحث بین المللی شدن و انتقال اطلاعات، این مشکل بزرگتر از آنچه بود، شد.
یونیکد نجات بخش
اواخر سال ۱۹۸۰ بود که پیشنهاد یک استاندارد جدید داده شد و در آن به هر حرف و یا نماد در هر زبانی یک عدد یکتا نسبت داده میشد و باید بیشتر از ۲۵۶ عدد میبود که آن را یونیکد نامیدند. در حال حاضر یونیکد نسخه ۶۰۱ شامل ۱۱۰ هزار کد می شود. ۱۲۸ تای آن همانند اسکی است. از ۱۲۸ تا ۲۵۵ مربوط به علائم و علامتهاست که بیشتر آنها از استاندارد ISO-8859-1 وام گرفته شدهاند. از ۲۵۶ به بعد هم بسیاری از علائم تلفظی و … وجود دارد و از کد ۸۸۰ زبان یونایی آغاز شده و پس از آن زبانهای سیریلیک، عبری، عربی و الی آخر ادامه مییابند. برای نشان دادن یک کد یونیکد به شکل هگزادسیمال U+0048 نوشته میشود و برای تبدیل آن به دسیمال ۴*۱۶+۸=۷۲ استفاده میشود. به هر کد یونیکد، کد پوینت code point گفته میشود.
در ویکی پدیای فارسی، یونیکد اینگونه توضیح داده شده است: “نقش یونیکد در پردازش متن این است که به جای یک تصویر برای هر نویسه یک کد منحصر به فرد ارایه میکند. به عبارت دیگر، یونیکد یک نویسه را به صورت مجازی ارایه میکند و کار ساخت تصویر (شامل اندازه، شکل، قلم، یا سبک) نویسه را به عهده نرمافزار دیگری مانند مرورگر وب یا واژهپرداز میگذارد. “
یونیکد از ۸ بیت یا ۱۶ بیت استفاده نمیکند و با توجه به اینکه دقیقا ۱۱۰ ،۱۱۶ کد را حمایت میکند به ۲۱ بیت نیاز دارد. هر چند که کامپیوترها امروزه از معمارهای ۳۲ بیتی و ۶۴ بیتی استفاده میکنند، این سوال پیش میآید که ما چرا نمیتوانیم کاراکترها را بر اساس این ۳۲ بیت و ۶۴ بیت قرار بدهیم؟ پاسخ این سوال ایناست که چنین کاری امکان پذیر است و بسیاری از نرم افزارهای نوشته شده در زبان سی و سی ++ از wide character حمایت میکنند. این مورد یک کاراکتر ۳۲ بیتی به نام wchar_t است که نوعی داده char توسعه یافته هشت بیتی است و بسیاری از مرورگرهای امروزی از آن بهره مند هستند و تا ۴ بیلیون کاراکتر را حمایت میکنند.
شکل زیر دسته بندی از انواع زبانهای تحت حمایت خود را در نسخه ۵.۱ یونیکد نشان میدهد
کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کردهایم نشان میدهد
<html>
<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>
<script type=”text/javascript”>
for (var i=0; i<2096; i++)
document.writeln ((i%256?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);
</script>
</body>
</html>
CSS & Unicode
یکی از جذابترین خصوصیات در css، خصوصیت Unicode-range است. شما میتوانید برای هر کاراکتر یا حتی رنج خاصی از کاراکترها، فونت خاصی را اعمال کنید. به دو نمونه زیر دقت کنید:
/* cyrillic */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
در صورتی که در Unicode-range، تنها یک کد مانند U+20AD نوشته شود، فونت مورد نظر فقط بر روی کاراکتری با همین کد اعمال میشود. ولی اگر بین دو کد از علامت – استفاده شود، فونت مورد نظر بر روی کاراکترهایی که بین این رنج هستند اعمال میشود U+0025-00FF و حتی میتوان اینگونه نوشت ??U+4 روی کاراکترهایی در رنج U+400 تا U+4FF اعمال میشوند. برای اطلاعات بیشتر به اینجا و اینجا مراجعه کنید.
به ۶۵۵۳۶ کد اول یونیکد Basic Multilingual Plan یا به اختصار BMP میگویند و شامل همه کاراکترهای رایجی است که مورد استفاده قرار میگیرند. همچنین یونیکد شامل یک فضای بسیار بزرگ خالی است که به شما اجازه توسعه دادن آن را تا میلیونها کد میدهد. به کاراکترهایی که در این موقعیت قرار میگیرند supplementary characters یا کاراکترهای مکمل گویند. برای اطلاعات بیشتر میتوانید به سایت رسمی یونیکد مراجعه کنید. در اینجا هم مباحث آموزشی خوبی برای یونیکد دارد، هر چند کاملتر آن در سایت رسمی برای نسخههای مختلف یونیکد وجود دارد.
UTF-8 نجات بخش میشود
بسیاری از مشکلات ما حل شد. همه حروف را داریم و مرورگرها نیز همه حروف را میشناسند؛ ولی برای ما دو مشکل ایجاد کرده است:
بسیاری از نرم افزارها و پروتکلها هنوز ۸ بیتی کار میکنند.
اگر یک متن انگلیسی ارسال کنید، ۸ بیت هم کافی است ولی در این حالت ۳۲ بیت جابجا میشود؛ یعنی ۴ برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد میکند.
برای حل این مشکل استاندارهای زیادی چون USC-2 یا UTF-16 ایجاد شدند ولی در سالهای اخیر برنده رقابت، UTF-8 بود که مخفف عبارت Universal Character Set Transformation Format 8 bit میباشد. این کدگذاری بسیار هوشمندانه عمل میکند. موقعی که شما کاراکتری را وارد میکنید که کدش بین ۰ تا ۲۵۵ است، ۸ بیت به آن اختصاص میدهد و اگر در محدودهای است که بتوان دو بایت را به آن اختصاص داد، دوبایت و اگر بیشتر بود، سه بایت و اگر باز بیشتر بود ۴ بایت به آن اختصاص میدهد. پس با توجه به محدوده کد، تعداد بایتها مشخص میشوند. بنابراین یک متن نوشته شده انگلیسی که مثلا از کدهای بین ۰تا ۱۲۸ استفاده میکند و فرمت ذخیره آن UTF-8 باشد به ازای هر کارکتر یک بایت ذخیره میکند.
مقایسهای بین نسخههای مختلف :
همانطور که میبینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMPها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از ۴ بایت برای نمایش کاراکترهای مکمل استفاده میکند و در UTF-32 از ۴ بایت برای همه کاراکترها یا کد پوینتها استفاده میشود.

var d = new Date();
$.jCookies({
name: ‘dotnettips.info’,
value: { Title: ‘ساخت کوکی با jcookie’, Author: ‘علی یگانه مقدم’, Seen: d.getDate(), Favorite: true }
});
همانطور که میبینید ذخیره اطلاعات توسط jcookie بسیار ساده و راحت بوده و هر نوع داده ای در آن به راحتی قابل ذخیره سازیست. برای مثال میتوانید اطلاعات یک کلاس را خیلی راحت و سریع با آن ذخیره کنید. به طور پیش فرض تاریخ انقضای کوکی ۲۷ روز بعد از ایجاد آن میباشد. در صورتی که تمایل دارید این تاریخ را تغییر دهید یکی از خاصیتهای seconds,minutes,hours و days در دسترس شماست و مقادیری که جلوی آنها به کارگرفته میشود باید نوع صحیح بوده و در صورتی که مقدار نامعتبر وارد شود خاصیت مورد نظر نادیده گرفته میشود.
$.jCookies ({ name : ‘User’, value : { username : ‘Bob’ , level : 5 }, minutes : 60 });
برای تغییر پیش فرضهای ساخت کوکی مانند انقضای ۲۷ روز به عدد پیش فرض خودتان فایل jcookies.js را باز کرده و تنظیمات پیش فرض آن را تغییر بدهید. برای تغییر دنبال کد زیر بگردید:
$.jCookies.defaults =
{
name : ”,
value : ”,
days : 27
}
Error : {
arguments : undefined,
message : “Invalid base64 data”,
stack : “—”,
type : undefined
}
بازیابی همه کوکی ها
var values = $.jCookies({ get: ‘*’ });
alert(values[“dotnettips.info”].Title);
alert(values[“data2”].Title);
- برگشت دادهها از حالت رمزگذاری base64
- دادهها در فرمت json هستند و باید به حالتی قابل استفاده در محیط شی گرا تبدیل شوند.
Title | ایجاد کوکی با jcookie |
Author | علی یگانه مقدم |
Seen | 2015/1/14 |
Favorite | true |
byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
string json = Encoding.UTF8.GetString(from64);
Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Page.Response.Write(“Title: “+ (string)article[“Title”]);
پشتیبانی از یونیکد
موقعی که من اولین مثال بالا را نوشتم و مقادیر را به صورت فارسی وارد کردم متوجه شدم که رشتههای یونیکد را انکود نمیکند و در نتیجه زبان فارسی در آن پشتیبانی نمیشود. برای همین تغییراتی در فایل js ایجاد کرده و عبارت value قبل از تبدیل به base64 را به صورت utf-16 انکود کردم و در هنگام خواندن کوکی هم به صورت utf-16 دیکود کردم و مشکل زبان فارسی هم در این حالت حل شد. البته کدی که اضافه کردم قابلیتهای انکودینگ بیشتری هم دارد.
فقط تنها مورد این هست که برای خواندن کوکی در سمت سرور باید یک تغییر کوچک یک کلمه ای بدهیم؛ باید کلمه UTF8 را به Unicode که میشود همان UTF-16 در کد تغییر دهیم، که به کد زیر تغییر خواهد یافت:
byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
string json = Encoding.Unicode.GetString(from64);
Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Page.Response.Write(“Title: “+ (string)article[“Title”]);

توسط روشی که امروز باهم بررسی می کنیم شما می توانید IP کاربری که به سرور متصل شده را بدست آورید.
بدست آوردن IP کاربر کاربردهای فراوانی دارد . شما می توانید اجازه دسترسی به دیتاهای خاصی را به کاربر بدهید یا کلا ورود کاربر را مسدود کنید یا حتی می توانید ساعات ورود و خروج کاربران را ثبت کنید تا برای گزارشات خاصی استفاده شود .
CREATE FUNCTION [dbo].[GetCurrentIP] ()
RETURNS varchar(255)
AS
BEGIN
DECLARE @IP_Address varchar(255);
SELECT @IP_Address = client_net_address
FROM sys.dm_exec_connections
WHERE Session_id = @@SPID;
Return @IP_Address;
END
جدول sys.dm_exec_connections از جداول SQL SERVER حاوی اطلاعاتی در مورد اتصال به Instance های نصب شده و جزییات هر یک از این اتصال ها می باشد بطور مثال مدت زمان برقراری اتصال ((connect_time ، پروتکل برقراری اتصال ( protocol_type که می تواند TDS یا SOAP باشد) ، protocol_version ، last_write ، last_read ( مدت زمان نوشته شدن و خوانده شدن اطلاعات ) و …
فیلد client_net_address هم آدرس هاست (ip) اتصال شده به سرور را برمی گرداند .
فیلد Session_id هم id سشن (session) مربوط به اتصال کنونی است .