نصب و راه‌اندازی Oracle Database 12C RAC در ویندوز سرور ۲۰۱۲ با استفاده از VirtualBox

این نوشته درباره چگونگی نصب و پیکربندی Oracle Database 12C RAC در ویندوز سرور ۲۰۱۲ ورژن Standard با استفاده از VirtualBox و بدون فضای ذخیره‌سازی مشترک اضافی به صورت یک پیکربندی کامل است.

مقدمه

یکی از بزرگترین مشکلات به هنگام آزمایش محیط‌های RAC، نیاز آنها به فضای ذخیره‌سازی مشترک است. در یک محیط عملی، فضای ذخیره‌سازی مشترک معمولاً توسط یک دستگاه پیشرفته‌ی NAS یا SAN تامین می‌شود، اما اگر قصد شما تجربه‌ی نصب و استفاده از RAC باشد، هر دوی این گزینه‌ها بسیار بیشتر از آن‌چه باید برای شما خرج برمی‌دارند. راهکار ارزان‌تر، استفاده از یک دیسک فایروایر (FireWire) متصل است تا امکان دسترسی، دیسک‌(های) یکسان برای ماشین‌ها فراهم شود. هر چند که این راهکار هم به پول احتیاج دارد و نیازمند حداقل ۲ سرور است. راهکار سوم، استفاده از مجازی‌سازی برای شبیه‌سازی فضای ذخیره‌سازی مشترک است.

با استفاده از VirtualBox می‌توان چندین ماشین‌مجازی (VM) را بر روی یک سرور اجرا کرد و اجرای هر دو گروه RAC بر روی یک ماشین را ممکن می‌سازد. به علاوه چنین‌کاری شما را در قادر خواهد ساخت دیسک‌های مجازی مشترک راه‌اندازی کنید و بر مشکلات مربوط بر گرانی فضاهای ذخیره‌سازی مشترک فائق بیابید.

ادامه مطلب...
۰۸ ارديبهشت ۹۴ ، ۱۹:۲۱ ۲ نظر
مهدی غفاری

تراکنش‌های خودمختار

تراکنش‌های خودمختار به شما اجازه می‌دهند که محیط یک تراکنش فراخوانی را ترک کنید، تراکنش‌های خودمختار انجام دهید، و بدون تاثیرگذاری بر روی شرایط یک تراکنش فراخوانی به آن برگردید. تراکنش‌های خودمختار با تراکنش‌های فراخوانی پیوندی ندارند، بنابراین تنها داده‌های متعهد را می‌توان بین هر دو تراکنش به اشتراک گذاشت. 
انواع بلوک‌های PL/SQL می‌توانند به عنوان تراکنش‌های خودمختار تعریف شوند: 
پروسه ها و توابع ذخیره شده 
روش های محلی و توابع تعریف شده در یک بلوک اعلان PL/SQL. 
پروسه‌ها و توابع بسته‌بندی شده. 
روش‌های تایپ
بلوک‌های ناشناس در سطح بالا 
ساده‌ترین راه برای درک معاملات خودمختار این است که در عمل آنها را ببینید. برای این کار، ما یک جدول آزمون ایجاد و آن را با دو ردیف پر می‌کنیم. توجه کنید که داده‌ها متعهد نیستند.

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

دو تا از ریف‌هایی که توسط جلسه‌ی کنونی ما (تراکنش) عقب کشیده شده اند، در حالیکه ردیف‌های قرارداده‌شده توسط تراکنش‌های خودمختار باقی مانده آند. حضور دستوردهنده‌ی کامپایلر PRAGMA AUTONOMOUS_TRANSACTION باعث شده که بلاک خودمختار در تراکنش خودش اجرا شود، و به همین خاطر جمله داخللی متعهد بر روی تراکنش فراخوانی تاثیری نداشته است. در نتیجه رول‌بک همچنان قادر به تاثیرگذاری بر روی دی‌ام‌ال اعمال شده توسط جمله‌ی کنونی بود
تراکنش‌های خودمختار عموما توسط روال لاگ‌کردن خطاها استفاده می‌شوند. در چنین جاهایی، پیام/ های خطا می‌بایست بدون توجه به وضعیت تعهد/رول‌بک تراکنش نگهداری شوند. برای نمونه، جدول زیر شامل پیام‌های خطای اساسی می‌شود.
ما بری لاگ کردن پیام های خطا به عنوان یک تراکنش‌های خودمختار، یک فرآیند تعریف می‌کنیم.
کد زیر بر روی خطا تمرکز می‌کند، که گرفته شده و لاگ شده است.
با توجه به این کادر می‌توانیم ببینیم که تراکنش LOG_ERRORS  از تراکنش خودمختار جدا بوده است. اگر چنین نبود، می‌توانستیم توقع داشه باشیم که اولین کد قرار داده شده در بلاک خودمختار توسط جمله متعهد در فرآیند theLOG_ERRORS نشان داده شود.
مراقب باشید که به چه شکلی ازتراکنش خودختار استفاده می‌کنید. اگر از آنها بدون ترتیب و آرایش خاصی استفاده شود می‌تواند منجر به ددلاک شده و در جلسه رهیابی اختلال ایجاد کنند. برای روشن کردن این نکته به این نقل قول از تام کایت توجه کنید:
«...در بیشتر مواقعی که شما مجبور به استفاده از تراکنش خودمختار هستید، این بدین معناست که احتمالا شما یک مشکل جدی در رابطه با تمامیت داده ها دارید که هنوز درباره‌اش فکری نکرده‌اید.
مردم کجاها از آنها استفاده می‌کنند؟
-در آن آغازگری که فرآیندی که متعهد می‌شود رافرا می‌خواند (نه یک روال لاگ‌کردن خطا). چنین چیزی موقع رول‌بک کردن دردناک است.
-در آن آغازگری که برای جدول در حال جهش، مانع ایجاد می‌کند. درد چنین چیزی حتی بیشتر از قبلی است Smile

با لاگ‌کردن خطاها مشکلی نیست؛
اما با بیشتر چیزهای دیگه، هست.

۰۸ ارديبهشت ۹۴ ، ۱۷:۲۵ ۰ نظر
مهدی غفاری

اجرای trigger همزمان با logon به سیستم

میخوام یه trigger بنویسم که با login هر کاربر اجرا بشه و مثلاً نام کاربر رو ذخیره کنه:

CREATE OR REPLACE TRIGGER logonauditing
AFTER LOGON ON application.schema
DECLARE
machinename VARCHAR2(64);
osuserid VARCHAR2(30);
session_id_part1 NUMBER;
session_id_part2 NUMBER;
CURSOR c1 IS
SELECT osuser, machine, sid, serial#
FROM v$session WHERE audsid = userenv( 'sessionid' );
BEGIN
OPEN c1;
FETCH c1 INTO osuserid, machinename, session_id_part1, session_id_part2;
INSERT INTO LOGON_table(osuser, machine, logon_time, session_id_1, session_id_2)
VALUES ( osuserid, machinename, sysdate,session_id_part1, session_id_part2);
CLOSE c1;
COMMIT;
END;

نکته: میشه از AUDIT CONNECT به جای trigger استفاده کرد (اوراکل فعالیت‌های ورود و خروج رو تو audit trail ذخیره می‌کنه)، می‌تونید پیشنهاد تام در این باره رو از اینجا ببینید.

۰۸ ارديبهشت ۹۴ ، ۱۷:۲۲ ۰ نظر
مهدی غفاری

PL/SQL در مقابل SQLj: مقایسه‌ی سرعت در عملیات‌های ریاضی

اوراکل از زمان اوراکل 8i یک ماشین مجازی جاوا را به عنوان بخشی از پایگاه داده‌اش منتشر کرده است. خاطرم هست که چند سال پیش از کسی شنیدم که می‌گفت JVM اوراکل از PL/SQL در اجرای عملیات‌های ریاضی سریع‌تر است، اما هیچوقت به این گفته به شکل جدی نگاه نکردم. در این نوشته من یک مقایسه‌ی تطبیقی بر مبنای چند عملیات ریاضی پایه میان JVM اوراکل و PL/SQL انجام می‌دهم.
توجه کنید که من یک برنامه‌نویس PL/SQL هستم و از همین دید به قضیه نگاه می‌کنم. دلیل اینکه تمام آزمایش‌ها هم از PL/SQL فراخوانده شده‌اند همین است.

ادامه مطلب...
۰۸ ارديبهشت ۹۴ ، ۱۷:۱۶ ۰ نظر
مهدی غفاری

FTP از PL/SQL

گاهی اوقات بهتر است که کارهای FTP را بجای تکیه‌کردن بر بروی CRON یا AT، مستقیما از PL/SQL آغاز کنید.

شل اسکریپت

روش اول بر روی فرآیندی بر پایه‌ی جاوا اتکا دارد که می‌تواند برای آغاز کردن یک شل اسکریپت، و به طبع آن اجرا کردن فرآیندی انتقالی، به‌کار گرفته شود. این روش در دستورهای شل از  PL/SQL توضیح داده شده است. شل اسکریپت ممکن است شبیه چیزی باشد که به دنبال می‌آید:

#! /bin/ksh

# Move to appropriate directory on local server
cd /extracts

# FTP all files in directory
ftp -inv ftp.company.com <<EOF
user ftpuser ftppassword
# Move to appropriate directory on remote server.
cd /loads
ascii
mput *.*
bye
EOF

ادامه مطلب...
۰۸ ارديبهشت ۹۴ ، ۱۷:۱۱ ۰ نظر
مهدی غفاری

نحوه اختصاص‌دادن مستقیم role‌ها به برنامه‌های PL/SQL در اوراکل ۱۲c

کنترل دسترسی به شکل کد-مبنا (CBAC):

اختصاص‌دادن نقش به واحدهای برنامه‌نویسی PL/SQL در پایگاه داده‌ اوراکل 12.1

به طور پیش‌فرض: واحدهای برنامه‌نویسی PL/SQL با استفاده از اختیارات تعریف‌کننده‌ها ساخته می‌شوند و به همین خاطر هم با تمام اجازه‌ای که دارند، مستقیما به کاربری که آن‌ها را به‌وجود آورده، داده می‌شوند. چنین چیزی در زمانی که می‌خواهید کاری با اجازه بالا را به کاربری با اجازه پایین واگذار کنید، بسیار مفید خواهد بود. در این مواقع می‌توان کارها را در لفاف یه واحد برنامه‌ای PL/SQL پوشاند، و همراه با آن، اجازه اجراکردن آن را به کاربری با اجازه پایین اختصاص‌داد. مشکل تعریف‌کننده‌های اختیارات این است که خیلی ساده می‌توان اجازه‌ی بیش از حد به یک کاربر اختصاص‌داد.

ادامه مطلب...
۰۸ ارديبهشت ۹۴ ، ۱۷:۰۴ ۱ نظر
مهدی غفاری

رفع مشکل IO ERROR در SQL Developer

اگر بعد از اجرای SQL Developer هنگام اتصال به اوراکل به پیغام خطای زیر برخوردید مراحل را دنبال کنید:

An error was encountered performing the requested operation:

IO ERROR: The Network Adapter could not establish the connection.

Vendor code 17002

ادامه مطلب...
۰۸ ارديبهشت ۹۴ ، ۱۴:۴۰ ۱ نظر
مهدی غفاری

جستجوی انعطاف‌پذیر

نکته: دیتابیس اوراکل قابلیت PREPARE STATEMENT رو ساپورت میکنه

هرگاه بخواهیم در دستور SELECT خود، از کاربر ورودی دریافت نماییم، از & استفاده می‌کنیم. برای این مثال، از جدول PERSON استفاده خواهیم‌کرد.

دستور زیر تمام رکورد‌های جدول PERSON را به شرطی که فیلد NAME آن مساوی با ورودی کاربر باشد لیست می‌کند. دقت داشته باشید، بعد از اجرای کوئری پایگاه‌داده از شما مقدار ورودی را خواهد پرسید، به دستور زیر توجه کنید:

در پرس‌وجوی فوق از کاربر ورودی گرفته می‌شود، سپس جستجو در جدول PERSON آغاز می‌گردد و در انتها خروجی را به کاربر نمایش می‌دهد:

SELECT * FROM T5 WHERE AGE = &PLEASE_ENTER_YOUR_AGE;
ENTER VALUE FOR PLEASE_ENTER_YOUR_AGE: 10
AGE NAME
---- ------------
10 HOSSEIN

حالا می‌خوام INJECT کنم، می‌بینید که INJECT را قبول میکنه!!

SELECT * FROM T5 WHERE AGE = &PLEASE_ENTER_YOUR_AGE;
ENTER VALUE FOR PLEASE_ENTER_YOUR_AGE: 10 OR 1=1
AGE NAME
---- ----------
50 HAMID
20 AKBAR
10 HOSSEIN
30 HOSSEIN
15 AKBAR

در حقیقت عمل prepare statement‌ هم همینه یعنی پارامترها جدا میره سمت دیتابیس و دستور sql جدا میره سمت دیتابیس

نکته: من از قصد علامت & رو گذاشتم تا SQL INJECT رو قبول کنه ولی در فصل‌های آینده به این موضوع می‌رسیم که چجوری جلوی INJECT را در PREPARE STATEMENT بگیریم و دیگه دستور SQL رو به عنوان ورودی نگیره(پشت & یه علامت دیگه می‌ذاریم):

۰۱ ارديبهشت ۹۴ ، ۲۰:۵۵ ۰ نظر
مهدی غفاری

نحوه ذخیره تاریخ و زمان در جدول

به دستورات زیر دقت کنید:

SQL> CREATE TABLE MYDATE(BIRTHDATE DATE);
Table created.
SQL> INSERT INTO MYDATE VALUES (TO_DATE('22/09/14','DD/MM/YY'));
1 row created.
SQL> SELECT * FROM MYDATE;
BD
-------
22-SEP-14
SQL> ALTER SESSION SET NLS_CALENDAR='PERSIAN';
session altered
SQL> SELECT * FROM MYDATE;
BIRTHDATE
------------------
31 SHAHRIVAR 1393

ادامه مطلب...
۰۱ ارديبهشت ۹۴ ، ۱۸:۴۹ ۲ نظر
مهدی غفاری

توابع تاریخ و زمان

خیلی خوشحال می‌شدم تو این نوشته‌ها یه جاوای درست و حسابی هم میگفتم که باهم وارد jdbc بشیم و برخورد jdbc با type date رو بررسی کنیم. چون همیشه تو برنامه‌نویسی جاوا برنامه‌نویس‌ها تاریخ و زمان رو یا string می‌گیرن یا long، همیشه هم تو سطح اوراکل همه چیز رو اونجوری که دوست دارن می‌گیرن (البته اگه دیتابیس دست خودشون باشه)، به هر حال یه نقطه‌ای باید باشه که این ۲ تا رو به طور صحیح به هم وصل کنه.

جدول زیر در این پست مفروض است:

END_DATE START_DATE
02-May-90 02-May-89
10-May-89 04-May-89
10-May-90 04-May-89
04-Apr-89 04-Apr-89
04-May-89 04-Apr-89
10-May-89 04-Apr-89
10-May-91 04-Apr-89

این جدول T_DATE نام دارد. نوع داده‌های این جدول شامل موارد زیر می‌باشد.

  • فیلد START_DATE از نوع DATE
  • فیلد END_ DATE از نوع DATE

ادامه مطلب...
۰۱ ارديبهشت ۹۴ ، ۱۶:۰۹ ۶ نظر
مهدی غفاری