آموزش جامع متغیر سیستمی @@SPID در SQL Server؛ Syntax، خروجی و ۱۰ مثال کاربردی

آموزش جامع متغیر سیستمی @@SPID در SQL Server

توسط admin | گروه SQL Server | 1405/05/03

نظرات 0

آموزش جامع متغیر سیستمی @@SPID در SQL Server با ۱۰ مثال عملی

در بسیاری از اسکریپت‌های مدیریتی، عدد یا نام خام به‌تنهایی برای تصمیم‌گیری کافی نیست و باید به Metadata قابل فهم تبدیل شود. در این مقاله، @@SPID از سطح مقدماتی تا سناریوهای حرفه‌ای بررسی می‌شود و هر مثال با خروجی نمونه ارائه شده است.

این شناسه برای ردیابی Request، درج Correlation ID در لاگ، بررسی Blocking و اتصال به DMVهای نشست استفاده می‌شود. تمرکز آموزش بر این است که @@SPID در چه Contextی اجرا شود، نتیجه آن چگونه تفسیر شود و چه زمانی باید از یک DMV یا کاتالوگ‌ویوی جایگزین کمک گرفت.

برای مشاهده جایگاه @@SPID میان سایر توابع و شمارنده‌ها، راهنمای جامع توابع کمکی کارایی و Metadata در SQL Server را نیز مطالعه کنید.

تعریف و کاربرد اصلی @@SPID

متغیر سراسری @@SPID شناسه Session یا Server Process ID اتصال جاری را برمی‌گرداند. این تعریف در ظاهر کوتاه است، اما استفاده درست از @@SPID به درک مفاهیمی مانند session_id، SPID و sys.dm_exec_sessions وابسته است.

قاعده عملی @@SPID: ابتدا ورودی و Context را معتبر کنید، سپس خروجی را با نوع داده و معنای واقعی آن تفسیر کنید.

Syntax تابع یا متغیر @@SPID

SELECT @@SPID AS Result;

پارامترهای @@SPID

پارامترتوضیح
بدون پارامتراین متغیر مستقیماً در عبارت SELECT یا شرط قابل استفاده است.

نوع خروجی و رفتار NULL در @@SPID

smallint و نشان‌دهنده شناسه نشست فعلی. در کد تولیدی بهتر است نوع مقصد به‌صورت صریح تعیین شود؛ زیرا تبدیل ضمنی می‌تواند مقایسه، مرتب‌سازی یا ذخیره نتیجه @@SPID را مبهم کند.

مفاهیم کلیدی مرتبط با @@SPID

  • session_id
  • SPID
  • sys.dm_exec_sessions
  • blocking
  • request tracking
  • connection
  • scope
نقشه مفهومی @@SPID در SQL Serverنمودار فنی اختصاصی @@SPID شامل session_id، SPID، sys.dm_exec_sessions، blocking، request tracking@@SPIDsession_idSPIDsys.dm_exec_sessionsblockingrequest trackingاین شناسه برای ردیابی Request، درج Correlation ID در لاگ، بررسی Blocking و اتصال به DMVهای

تصویر نخست، ارتباط @@SPID را با مفاهیم اختصاصی session_id، SPID، sys.dm_exec_sessions و blocking نشان می‌دهد؛ این روابط مبنای انتخاب ورودی و تفسیر خروجی هستند.

سناریوهای واقعی استفاده از @@SPID

سناریوی 1 برای @@SPID، «ثبت Session در لاگ» است. در این حالت باید نتیجه همراه Context پایگاه داده، زمان نمونه‌برداری و در صورت نیاز شناسه نشست ثبت شود تا داده برای عیب‌یابی بعدی ارزش داشته باشد.

سناریوی 2 برای @@SPID، «مشاهده Request جاری» است. در این حالت باید نتیجه همراه Context پایگاه داده، زمان نمونه‌برداری و در صورت نیاز شناسه نشست ثبت شود تا داده برای عیب‌یابی بعدی ارزش داشته باشد.

سناریوی 3 برای @@SPID، «ردیابی Blocking» است. در این حالت باید نتیجه همراه Context پایگاه داده، زمان نمونه‌برداری و در صورت نیاز شناسه نشست ثبت شود تا داده برای عیب‌یابی بعدی ارزش داشته باشد.

سناریوی 4 برای @@SPID، «اتصال داده Temp Table به Session» است. در این حالت باید نتیجه همراه Context پایگاه داده، زمان نمونه‌برداری و در صورت نیاز شناسه نشست ثبت شود تا داده برای عیب‌یابی بعدی ارزش داشته باشد.

مثال‌های عملی @@SPID از ساده تا حرفه‌ای

مثال 1: نمایش شناسه نشست جاری

شناسه اتصال فعال را مستقیم می‌خوانیم. این سناریو به‌طور اختصاصی برای درک رفتار @@SPID طراحی شده است.

SELECT @@SPID AS CurrentSessionId;
CurrentSessionId
57

این مقدار تا پایان Connection جاری ثابت می‌ماند. هنگام استفاده سازمانی از @@SPID، خروجی نمونه را با داده واقعی محیط خود تطبیق دهید.

مثال 2: اتصال به sys.dm_exec_sessions

جزئیات نشست جاری را با SPID فیلتر می‌کنیم. این سناریو به‌طور اختصاصی برای درک رفتار @@SPID طراحی شده است.

SELECT s.session_id, s.login_name, s.host_name, s.program_name, s.status
        FROM sys.dm_exec_sessions AS s
        WHERE s.session_id = @@SPID;
session_idlogin_namehost_nameprogram_namestatus
57app_userWEB01Microsoft.Data.SqlClientrunning

فقط اطلاعات موردنیاز را در لاگ عملیاتی نگه دارید. هنگام استفاده سازمانی از @@SPID، خروجی نمونه را با داده واقعی محیط خود تطبیق دهید.

مثال 3: مشاهده Request جاری

Request همان نشست را از DMV می‌خوانیم. این سناریو به‌طور اختصاصی برای درک رفتار @@SPID طراحی شده است.

SELECT r.session_id, r.status, r.command, r.cpu_time, r.logical_reads
        FROM sys.dm_exec_requests AS r
        WHERE r.session_id = @@SPID;
session_idstatuscommandcpu_timelogical_reads
57runningSELECT12145

هنگام اجرای Query فعلی ممکن است ردیف Request قابل مشاهده باشد. هنگام استفاده سازمانی از @@SPID، خروجی نمونه را با داده واقعی محیط خود تطبیق دهید.

مثال 4: ثبت Correlation در جدول موقت

SPID و یک شناسه عملیات را کنار هم قرار می‌دهیم. این سناریو به‌طور اختصاصی برای درک رفتار @@SPID طراحی شده است.

CREATE TABLE #OperationTrace
        (
            SessionId smallint NOT NULL,
            OperationId uniqueidentifier NOT NULL,
            CapturedAt datetime2(0) NOT NULL
        );
        
        INSERT INTO #OperationTrace
        VALUES (@@SPID, NEWID(), SYSDATETIME());
        
        SELECT * FROM #OperationTrace;
SessionIdOperationIdCapturedAt
576A2CFB9D-9288-4DB8-9E18-5BA7A428A5442026-07-25 00:40:00

OperationId هویت رخداد را مستقل از استفاده مجدد SPID حفظ می‌کند. هنگام استفاده سازمانی از @@SPID، خروجی نمونه را با داده واقعی محیط خود تطبیق دهید.

جریان اجرا @@SPID در SQL Serverنمودار فنی اختصاصی @@SPID شامل session_id، SPID، sys.dm_exec_sessions، blocking، request trackingsession_idمرحله 1SPIDمرحله 2@@SPIDمرحله 3sys.dm_exec_sessionsمرحله 4blockingمرحله 5ورودی تا خروجی @@SPIDrequest trackingconnectionsmallint و نشان‌دهنده شناسه نشست فعلی.

تصویر دوم، جریان اجرای @@SPID را از ورودی و اعتبارسنجی تا تولید خروجی نمایش می‌دهد و نشان می‌دهد که request tracking در کدام مرحله باید کنترل شود.

ادامه مثال‌های پیشرفته @@SPID

مثال 5: تشخیص Blocking خود نشست

اطمینان می‌دهیم نشست جاری توسط چه Sessionای مسدود شده است. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

SELECT r.session_id, r.blocking_session_id, r.wait_type
        FROM sys.dm_exec_requests AS r
        WHERE r.session_id = @@SPID;
session_idblocking_session_idwait_type
5782LCK_M_S

برای KILL کردن Blocker ابتدا تراکنش و اثر کسب‌وکاری را بررسی کنید. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

مثال 6: استفاده در نام داده موقت

شناسه نشست را در یک برچسب نمایشی می‌گذاریم. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

SELECT CONCAT(N'worker-session-', @@SPID) AS WorkerLabel;
WorkerLabel
worker-session-57

برای نام شیء واقعی، SQL پویا و Quote مناسب لازم است؛ این مثال فقط برچسب می‌سازد. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

مثال 7: بررسی بازاستفاده شدن SPID

SPID را همراه login_time ثبت می‌کنیم. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

SELECT s.session_id, s.login_time, s.login_name
        FROM sys.dm_exec_sessions AS s
        WHERE s.session_id = @@SPID;
session_idlogin_timelogin_name
572026-07-25 00:32:10app_user

ترکیب session_id و login_time احتمال اشتباه ناشی از reuse را کم می‌کند. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

مثال 8: روش اشتباه برای هویت کاربر

هویت Login را جدا از SPID می‌خوانیم. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

SELECT @@SPID AS SessionId,
               ORIGINAL_LOGIN() AS OriginalLogin,
               SUSER_SNAME() AS EffectiveLogin;
SessionIdOriginalLoginEffectiveLogin
57app_userapp_user

SPID شناسه فنی نشست است و جایگزین شناسه کاربر نیست. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

مثال 9: کنترل نشست پیش از عملیات حساس

اطلاعات Connection جاری را برای ثبت حسابرسی آماده می‌کنیم. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

SELECT
            @@SPID AS SessionId,
            ORIGINAL_LOGIN() AS LoginName,
            HOST_NAME() AS HostName,
            APP_NAME() AS ApplicationName,
            SYSDATETIME() AS CapturedAt;
SessionIdLoginNameHostNameApplicationNameCapturedAt
57admin_userDBA-LAPTOPSQL Server Management Studio2026-07-25 00:42:00

HOST_NAME و APP_NAME توسط Client اعلام می‌شوند و به‌تنهایی قابل اعتماد امنیتی نیستند. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

مثال 10: فیلتر کارا روی DMV

به‌جای خواندن همه Sessionها، مستقیم SPID را شرط می‌کنیم. در این مثال، هدف تنها اجرای Query نیست؛ بلکه نشان دادن یک تصمیم فنی صحیح پیرامون @@SPID است.

DECLARE @CurrentSessionId smallint = @@SPID;
        
        SELECT c.session_id, c.net_transport, c.auth_scheme
        FROM sys.dm_exec_connections AS c
        WHERE c.session_id = @CurrentSessionId;
session_idnet_transportauth_scheme
57TCPKERBEROS

Predicate روی کلید session_id دامنه DMV را کوچک نگه می‌دارد. این نکته از تفسیر سطحی یا استفاده تکراری و بی‌هدف از @@SPID جلوگیری می‌کند.

خطاهای رایج در کار با @@SPID

خطای 1 در استفاده از @@SPID

SPID پس از پایان Session می‌تواند برای اتصال دیگری دوباره استفاده شود. برای رفع این مشکل، ورودی و Context را از منبع معتبر بخوانید و نتیجه @@SPID را پیش از ادامه منطق با شرط صریح کنترل کنید.

خطای 2 در استفاده از @@SPID

برای هویت دائمی کاربر یا تراکنش مناسب نیست. برای رفع این مشکل، ورودی و Context را از منبع معتبر بخوانید و نتیجه @@SPID را پیش از ادامه منطق با شرط صریح کنترل کنید.

خطای 3 در استفاده از @@SPID

KILL کردن Session فقط با بررسی دقیق و مجوز کافی انجام شود. برای رفع این مشکل، ورودی و Context را از منبع معتبر بخوانید و نتیجه @@SPID را پیش از ادامه منطق با شرط صریح کنترل کنید.

ملاحظات Performance برای @@SPID

از نظر کارایی، @@SPID زمانی کم‌هزینه باقی می‌ماند که روی یک مقدار هدفمند یا مجموعه محدود اجرا شود. فراخوانی آن روی هزاران ردیف بدون Predicate اولیه می‌تواند CPU و زمان گزارش را افزایش دهد.

اگر گزارش به چند Property از چندین شیء نیاز دارد، استفاده Set-based از کاتالوگ‌ویو یا DMV مرتبط با session_id معمولاً بهتر از تکرار @@SPID برای هر سلول است.

در Jobهای دوره‌ای، نتیجه @@SPID را همراه Timestamp ذخیره کنید، اما Frequency نمونه‌برداری را متناسب با سرعت تغییر داده انتخاب کنید. جمع‌آوری بیش از حد، جدول تاریخچه را بدون ارزش تحلیلی بزرگ می‌کند.

برای محاسبات عددی پیرامون @@SPID، نوع داده را قبل از ضرب یا تفریق ارتقا دهید و در سناریوهای تجمعی، Restart و بازنشانی Baseline را در نظر بگیرید.

Best Practiceهای اختصاصی @@SPID

  1. ورودی @@SPID را از نام یا شناسه معتبر و دارای Schema یا Context روشن تأمین کنید.
  2. نتیجه NULL در @@SPID را از مقدار صفر، false یا رشته خالی جدا نگه دارید.
  3. نوع خروجی @@SPID را پیش از ذخیره یا مقایسه به نوع مقصد مناسب تبدیل کنید.
  4. در گزارش‌های بزرگ، گزینه Set-based مرتبط با session_id را ارزیابی کنید.
  5. زمان Capture، نام Database و در صورت نیاز @@SPID را کنار نتیجه @@SPID ثبت کنید.
  6. مجوز مشاهده Metadata یا DMV را با حداقل سطح دسترسی لازم تنظیم کنید. در مبحث @@SPID
  7. مثال‌های @@SPID را روی نسخه و Edition واقعی محیط هدف آزمایش کنید.
  8. برای SQL پویا، خروجی نامی @@SPID را با QUOTENAME و پارامترسازی ایمن مصرف کنید.
سناریوی عملی و بهینه‌سازی @@SPID در SQL Serverنمودار فنی اختصاصی @@SPID شامل session_id، SPID، sys.dm_exec_sessions، blocking، request trackingروش پرخطرBest Practice@@SPIDSPID پس از پایان Session می‌تواند برای اتصال دبرای هویت دائمی کاربر یا تراکنش مناسب نیست.تفسیر خام @@SPIDثبت Session در لاگsession_idrequest tracking

تصویر سوم، تفاوت روش پرخطر و Best Practice در استفاده از @@SPID را مقایسه می‌کند؛ هدف آن جلوگیری از خطاهای مربوط به SPID پس از پایان Session می‌تواند برای اتصال دیگری دوباره استفاده شود. و بهبود تصمیم‌گیری فنی است.

سؤالات متداول اختصاصی @@SPID

@@SPID دقیقاً چه مسئله‌ای را در SQL Server حل می‌کند؟

متغیر سراسری @@SPID شناسه Session یا Server Process ID اتصال جاری را برمی‌گرداند. در عمل، این شناسه برای ردیابی Request، درج Correlation ID در لاگ، بررسی Blocking و اتصال به DMVهای نشست استفاده می‌شود. بنابراین استفاده از @@SPID زمانی ارزشمند است که خروجی آن در یک تصمیم فنی روشن مصرف شود، نه اینکه فقط برای نمایش عدد یا نام به کار رود.

نوع خروجی @@SPID چیست و چگونه باید آن را مدیریت کرد؟

نوع خروجی این ابزار چنین است: smallint و نشان‌دهنده شناسه نشست فعلی. بهتر است پیش از تبدیل نوع، مقایسه یا درج در جدول گزارش، حالت NULL و محدوده مقدار را صریح کنترل کنید تا رفتار @@SPID قابل پیش‌بینی بماند.

آیا @@SPID در گزارش‌های سازمانی کاربرد تجاری دارد؟

بله. در سناریوهایی مانند ثبت Session در لاگ و مشاهده Request جاری، خروجی @@SPID می‌تواند کیفیت گزارش مدیریتی را بالا ببرد. ارزش تجاری زمانی ایجاد می‌شود که این داده به هشدار، ظرفیت‌سنجی یا کاهش زمان عیب‌یابی متصل شود.

استفاده از @@SPID در پروژه‌های بزرگ چه مزیتی دارد؟

در پروژه بزرگ، استانداردسازی نحوه استفاده از @@SPID باعث می‌شود تیم توسعه، DBA و پشتیبانی یک تعریف مشترک از session_id و SPID داشته باشند. این هماهنگی خطاهای تفسیر و دوباره‌کاری را کاهش می‌دهد.

تفاوت @@SPID با گزینه نزدیک آن چیست؟

@@SPID فقط نشست جاری را می‌دهد؛ sys.dm_exec_sessions فهرست نشست‌های قابل مشاهده را برمی‌گرداند. انتخاب صحیح باید بر اساس حجم داده، نیاز به خروجی Set-based و سطح جزئیات گزارش انجام شود؛ یک تابع scalar همیشه جایگزین کاتالوگ‌ویو یا DMV کامل نیست.

برای طراحی اسکریپت حرفه‌ای مبتنی بر @@SPID چه خدماتی لازم می‌شود؟

در پروژه‌های حساس می‌توان منطق @@SPID را در قالب رویه مانیتورینگ، Dashboard، گزارش زمان‌بندی‌شده یا کنترل Deployment پیاده کرد. تحلیل نیاز، تست روی نسخه واقعی SQL Server و مستندسازی خروجی، بخش‌های مهم خدمات مشاوره و انجام پروژه هستند.

رایج‌ترین خطا هنگام کار با @@SPID چیست؟

یکی از خطاهای مهم این است که SPID پس از پایان Session می‌تواند برای اتصال دیگری دوباره استفاده شود. همچنین نادیده گرفتن NULL یا Context اجرای Query می‌تواند نتیجه‌ای ظاهراً معتبر ولی از نظر عملیاتی اشتباه تولید کند.

آیا فراخوانی زیاد @@SPID بر Performance اثر می‌گذارد؟

یک فراخوانی منفرد معمولاً سبک است، اما اجرای @@SPID روی مجموعه بسیار بزرگ یا در شرطی که برای هر ردیف محاسبه شود می‌تواند هزینه ایجاد کند. ابتدا ردیف‌ها را محدود کنید و در گزارش‌های وسیع، جایگزین Set-based را ارزیابی کنید.

بهترین روش استفاده از @@SPID چیست؟

بهترین روش این است که ورودی @@SPID اعتبارسنجی، نوع خروجی صریح، حالت NULL مدیریت و نتیجه همراه زمان و Context ثبت شود. همچنین باید مشخص باشد که خروجی برای نمایش، کنترل ایمنی یا تصمیم کارایی مصرف می‌شود.

@@SPID با کدام نسخه‌های SQL Server سازگار است؟

از قابلیت‌های قدیمی و پایدار SQL Server است. با این حال، هنگام انتقال اسکریپت به Azure SQL یا Edition دیگر، Propertyها، مجوزهای Metadata و تفاوت‌های پلتفرم را روی همان محیط آزمایش کنید.

سؤالات مصاحبه درباره @@SPID

در مصاحبه چگونه تفاوت ورودی و خروجی @@SPID را توضیح می‌دهید؟

پاسخ مناسب باید Syntax یعنی @@SPID، نوع خروجی و شرایط NULL را توضیح دهد و یک نمونه از ثبت Session در لاگ ارائه کند.

چه زمانی به‌جای @@SPID از کاتالوگ‌ویو یا DMV استفاده می‌کنید؟

وقتی گزارش چندین ردیف و چند Property نیاز دارد، روش Set-based معمولاً مناسب‌تر است؛ @@SPID برای تبدیل یا بررسی هدفمند یک مقدار بسیار خواناست.

چگونه نتیجه نامعتبر @@SPID را از مقدار false یا صفر جدا می‌کنید؟

با بررسی صریح IS NULL، اعتبارسنجی ورودی و در صورت نیاز Join با Metadata منبع، علت نتیجه را روشن می‌کنم. این توضیح به‌طور اختصاصی به @@SPID مربوط است.

چه نکته Performance درباره @@SPID مهم است؟

فراخوانی را پس از محدود کردن مجموعه داده انجام می‌دهم و از محاسبه تکراری @@SPID در SELECT و WHERE جلوگیری می‌کنم.

یک سناریوی واقعی برای @@SPID بیان کنید.

سناریوی مناسب می‌تواند ردیابی Blocking باشد؛ در آن خروجی همراه Timestamp، نام Database و شناسه نشست ثبت می‌شود تا قابل پیگیری باشد.

چک‌لیست نهایی استفاده از @@SPID

  • Syntax @@SPID و ورودی‌های آن با نسخه هدف تطبیق داده شده است.
  • Context پایگاه داده یا Instance برای @@SPID روشن است.
  • مجوز لازم برای Metadata یا DMV بررسی شده است. در مبحث @@SPID
  • NULL، مقدار نامعتبر و حالت مرزی @@SPID تست شده است.
  • نمونه خروجی با نوع داده واقعی مقایسه شده است. در مبحث @@SPID
  • در Query بزرگ، هزینه فراخوانی تکراری @@SPID اندازه‌گیری شده است.
  • جایگزین Set-based برای گزارش انبوه ارزیابی شده است. در مبحث @@SPID
  • نتیجه نهایی همراه Timestamp و توضیح عملیاتی ثبت می‌شود. در مبحث @@SPID

جمع‌بندی آموزش @@SPID

@@SPID ابزاری کوچک اما مؤثر برای این شناسه برای ردیابی Request، درج Correlation ID در لاگ، بررسی Blocking و اتصال به DMVهای نشست استفاده می‌شود. است. استفاده حرفه‌ای از آن به اعتبارسنجی ورودی، تفسیر نوع خروجی، کنترل NULL و انتخاب Scope مناسب وابسته است.

پس از تسلط بر @@SPID، برای مقایسه آن با سایر ابزارهای این مجموعه به مقاله مادر توابع کمکی Performance و Metadata در SQL Server بازگردید.

خدمات برنامه‌نویسی و پایگاه داده

برنامه‌نویسی در اصفهان

قبول سفارش‌های برنامه‌نویسی و پایگاه داده: 09131253620

انجام پروژه‌های برنامه‌نویسی، آموزش برنامه‌نویسی و آموزش پایگاه داده SQL Server با رویکرد حرفه‌ای، مستند و قابل توسعه انجام می‌شود.

مجموعه‌ای معتبر با سابقه فعالیت حرفه‌ای از سال ۱۳۷۵ شمسی

از سال ۱۳۷۵ شمسی تاکنون در زمینه طراحی و اجرای پروژه‌های برنامه‌نویسی، پایگاه داده، سیستم‌های تحت وب، وب‌سایت و راهکارهای نرم‌افزاری فعالیت می‌کنیم.

برای سفارش پروژه‌های برنامه‌نویسی و پایگاه داده، سیستم‌های تحت وب، وب‌سایت و راهکارهای نرم‌افزاری جدید، با شماره تلفن همراه 09131253620 تماس حاصل فرمایید.

ایتا، واتساپ و تماس مستقیم: +989131253620

تماس با ما

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر