ESC را فشار دهید تا بسته شود

زمیوس آموزش، یادگیری و سرگرمی

آموزش کامل پکیج UTL_TCP در Oracle — راهنمای کاربردی برای برقراری ارتباطات TCP از درون PL/SQL

در دنیای امروزی که ارتباطات نرم‌افزارها از طریق شبکه حرف اول را می‌زند، اوراکل هم برای توسعه‌دهندگانی که به ارتباطات سطح پایین نیاز دارند، ابزار قدرتمندی در اختیار گذاشته:

پکیجی به نام UTL_TCP.

با استفاده از این پکیج می‌توانی از درون دیتابیس مستقیماً با هر سرویس TCP ارتباط بگیری؛

چه یک سرور داخلی لاگین، دستگاه صنعتی IoT یا حتی یک ماژول حسابداری بیمه‌ای که پیام JSON دریافت می‌کند — همه از طریق PL/SQL!

در این مقاله آموزش Oracle در بخش آموزش پکیج های اوراکلی در مورد پکیج UTL_TCP صبحت کنیم.

اگر با پایگاه داده اوراکل کار کرده باشی، حتماً اسم Materialized View به گوشت خورده. این ساختار، در واقع یک جدول ذخیره‌شده از نتایج یک Query است که می‌تونه به صورت دوره‌ای یا دستی آپدیت بشه. پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.

در این مقاله شما می خوانید

🚀 پکیج UTL_TCP چیست و چه کاری انجام می‌دهد؟

به زبان ساده، UTL_TCP در Oracle Database مثل یک کلاینت TCP کوچک درون دیتابیس است.

این پکیج اجازه می‌دهد با استفاده از PL/SQL:

  • به هر سرور TCP/IP متصل شوی
  • داده ارسال کنی
  • پاسخ دریافت کنی
  • جریان داده را به‌صورت متنی یا باینری کنترل کنی

در واقع همان کاری که در زبان‌هایی مثل Python یا #C با Socket انجام می‌دهی، در اوراکل با UTL_TCP هم شدنی است.

⚙️ ساختار و توابع کلیدی پکیج UTL_TCP

برای استفاده حرفه‌ای از UTL_TCP، باید توابع و قابلیت‌های اصلی آن را بشناسی. در ادامه همه‌ی موارد مهم را توضیح داده‌ام همراه با کاربردهای واقعی هرکدام:

تابع / پروسیجر توضیح عملکرد نکات مهم
UTL_TCP.OPEN_CONNECTION ایجاد اتصال با هاست و پورت مشخص لازم است قبل از هر ارسال داده فراخوانی شود.
UTL_TCP.CLOSE_CONNECTION بستن ارتباط باز همیشه در بلوک Exception هم بنویس تا اتصال در هر شرایطی بسته شود.
UTL_TCP.WRITE_LINE ارسال رشته متنی با CR/LF در انتها مناسب برای سرویس‌هایی که پاسخ خطی می‌دهند.
UTL_TCP.WRITE_RAW ارسال داده باینری RAW کاربرد در Stream یا فایل Base64.
UTL_TCP.GET_LINE خواندن پاسخ تا رسیدن به خط جدید اگر TRUE بدهی، کاراکترهای انتهایی حذف می‌شوند.
UTL_TCP.READ_RAW دریافت داده باینری با طول مشخص برای فایل، تصویر یا جریان بزرگ داده (LOB) کاربرد دارد.
UTL_TCP.FLUSH ارسال فوری داده‌های بافر بدون آن داده ممکن است ارسال نشود.
UTL_TCP.END_OF_INPUT اکسپشن اختصاصی برای پایان ورودی برای کنترل حلقه دریافت پاسخ ضروری است.

🧭 تنظیمات امنیتی: ACL یا مجوز دسترسی شبکه

از نسخه ۱۱g، اوراکل دسترسی به شبکه را محدود کرده است.

اگر ACL ست نشده باشد، با خطای معروف ORA-24247 روبه‌رو می‌شوی.

برای فعال‌سازی دسترسی TCP، باید با DBMS_NETWORK_ACL_ADMIN مجوز صادر کنی:

				
					BEGIN
  DBMS_NETWORK_ACL_ADMIN.create_acl(
    acl         => 'utl_tcp_acl.xml',
    description => 'Allow UTL_TCP networking for HR',
    principal   => 'HR',
    is_grant    => TRUE,
    privilege   => 'connect'
  );

  DBMS_NETWORK_ACL_ADMIN.assign_acl(
    acl  => 'utl_tcp_acl.xml',
    host => 'example.com',
    lower_port => ۸۰۰۰,
    upper_port => ۸۰۰۰
  );

  COMMIT;
END;
/

				
			

بعد از اجرای این بلاک، کاربر HR اجازه دارد از پکیج UTL_TCP برای اتصال به میزبان مشخص‌شده استفاده کند.

💬 مثالی از ارتباط با سرویس TCP با پکیج UTL_TCP

				
					DECLARE
  l_conn UTL_TCP.connection;
  l_line VARCHAR2(32767);
BEGIN
  l_conn := UTL_TCP.open_connection('example.com', 8080, charset => 'UTF8');
  UTL_TCP.write_line(l_conn, 'HELLO FROM ORACLE');
  UTL_TCP.flush(l_conn);

  LOOP
    BEGIN
      l_line := UTL_TCP.get_line(l_conn, TRUE);
      DBMS_OUTPUT.put_line('Server response: ' || l_line);
    EXCEPTION
      WHEN UTL_TCP.end_of_input THEN EXIT;
    END;
  END LOOP;

  UTL_TCP.close_connection(l_conn);
END;
/

				
			

✅ اجرای صحیح، مشروط به تنظیم ACL و باز بودن پورت ۸۰۸۰ در سرور مقصد است.

💡 سناریوی واقعی: ارتباط با سیستم داخلی بیمه با پکیج UTL_TCP

در پروژه‌های بیمه‌ای، سیستم‌های داخلی اغلب روی پورت خاصی منتظر دریافت پیام TCP هستند.

کد زیر ارتباط با چنین سیستمی را از درون دیتابیس نشان می‌دهد:

				
					DECLARE
  l_conn  UTL_TCP.connection;
  l_req   VARCHAR2(32767);
  l_resp  VARCHAR2(32767);
BEGIN
  l_req := '{"transaction":"POLICY_INQUIRY","policy_no":"A89011"}';
  l_conn := UTL_TCP.open_connection('192.168.10.15', 9100, charset => 'UTF8');
  UTL_TCP.write_line(l_conn, l_req);
  UTL_TCP.flush(l_conn);

  LOOP
    BEGIN
      l_resp := UTL_TCP.get_line(l_conn, TRUE);
      DBMS_OUTPUT.put_line('Response: ' || l_resp);
    EXCEPTION
      WHEN UTL_TCP.end_of_input THEN EXIT;
    END;
  END LOOP;

  UTL_TCP.close_connection(l_conn);
END;
/

				
			

نتیجه معمولاً پاسخ JSON از سمت سیستم بیمه است که می‌توان با JSON_VALUE() یا JSON_TABLE() پردازش کرد.

🧱 مثالی پیشرفته‌تر: دریافت داده باینری از سرور با پکیج UTL_TCP

				
					DECLARE
  l_conn  UTL_TCP.connection;
  l_chunk RAW(32767);
BEGIN
  l_conn := UTL_TCP.open_connection('192.168.1.70', 7070);
  UTL_TCP.write_raw(l_conn, UTL_RAW.cast_to_raw('GET_FILE'));
  UTL_TCP.flush(l_conn);

  LOOP
    BEGIN
      l_chunk := UTL_TCP.read_raw(l_conn, 1024);
      DBMS_OUTPUT.put_line('Received chunk: ' || RAWTOHEX(l_chunk));
    EXCEPTION
      WHEN UTL_TCP.end_of_input THEN EXIT;
    END;
  END LOOP;

  UTL_TCP.close_connection(l_conn);
END;
/

				
			

🟢 این روش معمولاً برای مانیتورینگ سیستم‌ها، ارسال فایل بین سرویس‌ها و ارتباط با سخت‌افزار کاربرد دارد.

⚡ نکات حرفه‌ای برای بهینه‌سازی عملکرد پکیج UTL_TCP

  1. Buffer Size را متناسب با حجم داده تعیین کن (پیش‌فرض ۸۱۹۲ بایت است).
  2. از tx_timeout در OPEN_CONNECTION استفاده کن تا فرآیند قفل نشود.
  3. حتماً flush را پس از هر send بنویس.
  4. charset را AL32UTF8 تنظیم کن تا خطای کاراکتری نگیری.
  5. connection را همیشه در Exception block ببند تا نشت ارتباط رخ ندهد.

🚨 خطاهای متداول و راهکارها در پکیج UTL_TCP

کد خطا علت راه‌حل
ORA-24247 مجوز ACL وجود ندارد تعریف ACL با DBMS_NETWORK_ACL_ADMIN
ORA-29260 خطای شبکه یا بسته برگشتی بررسی فایروال، DNS و پورت
ORA-29263 Timeout در خواندن داده افزودن tx_timeout یا بررسی latency شبکه
ORA-06502 خطای تبدیل کاراکتر یا نوع داده تنظیم charset در open_connection به 'AL32UTF8'

🌍 کاربردهای واقعی پکیج UTL_TCP

پکیج UTL_TCP فقط برای آزمایش شبکه نیست؛ بلکه در پروژه‌های حرفه‌ای استفاده می‌شود:

  • ارتباط دیتابیس با سرورهای Log و QueueWriter داخلی
  • ارتباط سیستم‌های بیمه، مالی یا ERP سفارشی از طریق سوکت
  • ارسال داده به تجهیزات صنعتی (PLC / IoT)
  • اجرای handshake بین دیتابیس‌های جداگانه
  • ساخت ابزار مانیتورینگ و پینگ TCP در PL/SQL

سوالات متداول درباره پکیج UTL_TCP در اوراکل

پکیج UTL_TCP در دیتابیس اوراکل ابزاری برای ایجاد اتصال مستقیم TCP/IP از درون PL/SQL است.

به کمک آن می‌توانی داده را از داخل سرور دیتابیس به سرویس‌های خارجی بفرستی یا از آن‌ها پاسخ بگیری.

این پکیج مثل یک Socket Client داخلی عمل می‌کند و معمولاً برای ارتباط با سرویس‌های داخلی سازمان، دستگاه‌ها، یا سرورهای سفارشی استفاده می‌شود.

UTL_HTTP برای برقراری ارتباط با سرویس‌های وب (HTTP / HTTPS) طراحی شده، مثل REST API یا وب‌سرویس‌ها.

اما UTL_TCP در سطح پایین‌تر کار می‌کند؛ یعنی فقط با پروتکل TCP خام سر و کار دارد و برای سناریوهایی که ساختار پروتکل خاصی ندارند (مثل ارتباط با یک سوکت سفارشی یا سرور لاگ TCP) ایده‌آل است.

به زبان ساده:

🔹 اگر سرویس مقصد URL و header دارد UTL_HTTP

🔹 اگر فقط IP و Port دارد UTL_TCP

این خطا یکی از شایع‌ترین خطاهای هنگام استفاده از UTL_TCP است.

علتش این است که از اوراکل ۱۱g به بعد، همه ارتباطات شبکه‌ای نیاز به مجوز (ACL) دارند.

برای رفع آن باید با بسته‌ی DBMS_NETWORK_ACL_ADMIN یک ACL بسازی و کاربر را داخل آن اضافه کنی، مثلاً:

BEGIN

DBMS_NETWORK_ACL_ADMIN.create_acl( acl => ‘utl_tcp_acl.xml’, principal => ‘HR’, is_grant => TRUE, privilege => ‘connect’);

DBMS_NETWORK_ACL_ADMIN.assign_acl( acl => ‘utl_tcp_acl.xml’, host => ‘example.com’, lower_port => ۸۰۸۰);

COMMIT;

END; /

بعد از اجرای این کد، مشکل دسترسی شبکه حل می‌شود.

برای ارسال JSON به سرویس TCP داخلی، کافی است با UTL_TCP.OPEN_CONNECTION اتصال برقرار کرده و سپس داده را با WRITE_LINE بفرستی؛ مثلاً:

DECLARE

conn UTL_TCP.connection;

BEGIN

conn := UTL_TCP.open_connection(‘۱۹۲.۱۶۸.۱۰.۱۵’, ۹۱۰۰, charset => ‘UTF8’);

UTL_TCP.write_line(conn, ‘{“type”:”PING”}’); UTL_TCP.flush(conn);

DBMS_OUTPUT.put_line(UTL_TCP.get_line(conn, TRUE));

UTL_TCP.close_connection(conn);

END;

این روش در سازمان‌هایی مثل بیمه و بانکی که سرویس‌های TCP داخلی دارند بسیار پرکاربرد است و با ACL فعال به‌خوبی کار می‌کند.

جمع‌بندی

پکیج ‌UTL_TCP یکی از انعطاف‌پذیرترین بخش‌های اوراکل است.

اگر نیاز به ارتباط مستقیم TCP از درون PL/SQL داری، این ابزار دقیقاً همان چیزی است که باید یاد بگیری.

با این حال، چون دسترسی سطح پایین به شبکه دارد، امنیت (ACL) و مدیریت استثناها حیاتی است.

به‌صورت خلاصه:

🔹 برای ارتباط سفارشی و سرویس‌های خاص از UTL_TCP

🔹 برای APIهای HTTP از UTL_HTTP

🔹 و برای ارسال ایمیل از UTL_SMTP استفاده کن.

📥 اگر سوالی داری در مورد پکیج ‌UTL_TCP‌ در اوراکل داری، در بخش کامنت‌ها بپرس.

میثم راد

من یه برنامه نویسم که حسابی با دیتابیس اوراکل رفیقم! از اونایی ام که تا چیزی رو کامل نفهمم،ول کن نیستم، یادگرفتن برام مثل بازیه، و نوشتن اینجا کمک می کنه تا چیزایی که یاد گرفتم رو با بقیه به شریک بشم، با هم پیشرفت کنیم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *