آموزش و سوالات مربوط به استفاده از دستورات Sql در دلفی

آموزشها تا اينجا چطور بود؟

  • برو بابا دلت خوشه

    رای: 0 0.0%
  • حيف فضايي كه به تاپيك اختصاص داده شده

    رای: 0 0.0%

  • مجموع رای دهندگان
    18

farhad110

Member
سلام
نمیدونم چرا تالار برنامه نویسی این فروم اینقدر خلوته؟!!! راستش در این تاپیک میخوام آموزشهای مربوط به استفاده از دستورات SQL در دلفی رو بذارم شاید مورد توجه دوستان قرار بگیره.
به چند دلیل:
- برای استفاده از اکثر دستورات sql نوع دیتابیس مورد استفاده در پروژه مهم نیست (paradox,ado,interbase,…)
- بیشتر مشکلاتی که در این تالار مطرح شدند رو میشه با استفاده از دستورات sql خیلی راحت تر حل کرد
- Sql در زبانهای برنامه نویسی دیگه هم قابل استفاده هست پس یادگیری اون لازمه

از اونجا که نمیدونم این آموزش چقدر طرفدار داره، لطفا دوستان نظراتشون رو درباره شروع یا عدم شروع اعلام کنند.

البته یکی از دلایل خلوتی این تالار که نظر شخصی من هست و امیدوارم مدیران رسیدگی کنند اینه که delphi , vb , c , pascal , *.net , ... همه یکجا هستند و کاربری که تازه وارد هست واقعا نمیدونه اگر سوالی رو مطرح کنه با جواب روبرو میشه یا نه...
منتظر نظرات دوستان عزیز هستم
پیروز باشید

در تاریخ 6/1/87 نظر سنجی به این تاپیک اضافه شد

مقاله مربوط به اين آموزشها، تا پست #48 را از لينك زير دريافت كنيد:

http://rapidshare.com/files/109998956/Learning_T-SQL.rar
 
آخرین ویرایش:

farhad110

Member
منتظر نظرات دوستان عزیز هستم
متشکرم از نظرات سازنده دوستان :)
تاپیک تا حالا 21 بازدید داشته، یعنی بعد از 1 روز تمام، با این تعداد بازدید هیچکس نظری نداره؟
؟؟؟؟؟...
 

MnavidM

Active Member
فرهاد جان ، شما آموزش رو شروع کن ، نظرات هم کم کم ارایه میشه.
 

farhad110

Member
بله نوید عزیز. حق با شماست. الهی به امید تو...

چند نکته برای شروع:
- آموزشها از مبتدی شروع میشه و در ادامه به دستورات پیچیده می رسیم (پس پروفشنال ها شاکی نشن)
- در تمام آموزشها فرض بر این هست که دوستان در ارتباط دادن پایگاه داده با برنامه کاربردی مشکلی ندارند
- دستورات sql به حروف کوچک و بزرگ حساس نیستند (select با SELECT فرقی ندارند)
- تمامی دستوراتی که در اینجا گفته میشه، تست شده هست
- دستورات در کامپوننت های ADO به کار گرفته میشه

قبل از هر چیز مقدمه ای بر SQL (Structured Query Language):
SQL زبان پرس و جویی هست که توسط ANSI (American National Standards Institute) استاندارد شده و برای دستکاری دیتابیس ها، بازیابی و update داده ها در بانک های اطلاعاتی مفید می باشد.
SQL در دیتابیسهای MS Access, Paradox, DB2, Informix, MS SQL Server, My SQL, Oracle, Sybase و غیره استفاده میشود.
متاسفانه ورژن های مختلفی از این زبان وجود دارد (SQL/PSM, SQL PL, T-SQL, MySQL, PL/SQL, PL/pgSQL , ...) اما برای اینکه همه آنها با استاندارد ANSI سازگاری داشته باشند باید از کلمات کلیدی یکسان در استفاده های مشابه پشتیبانی کنند. (مانند SELECT, UPDATE, DELETE, INSERT, WHERE و غیره)

چرا SQL ؟
SQL زبان پرس و جوی ساخت یافته است
SQL به شما اجازه میدهد تا به آسانی به دیتابیس ها دسترسی داشته باشید
SQL میتواند برای دیتابیس ها پرس و جو ایجاد کند
SQL میتواند داده ها را از دیتابیس بازیابی کند
SQL میتواند رکورد جدیدی در دیتابیس درج کند
SQL میتواند رکوردی را از دیتابیس حذف کند
SQL میتواند رکوردهای دیتابیس را به روز کند
SQL برای یادگیری آسان است

منابع:
کد:
[LEFT]http://www.w3schools.com
http://wikipedia.org
[/LEFT]

امیدوارم مورد توجه قرار بگیره و با همکاری اساتید گرامی به حل مشکلاتی که برای دوستان عزیز پیش میاد کمک کنیم.
 

farhad110

Member
اولین دستوری رو که میخوام بگم دستور select هست.
شکل کلی دستور:
کد:
[LEFT]SELECT column_name(s) FROM table_name[/LEFT]
فرض کنید جدولی با نام inventory مربوط به مشخصات کالا داریم که دارای فیلدهای no , name , cost , color , weight هست. (در ادامه آموزشها از همین جدول برای مثال ها استفاده میکنم)

کد:
[LEFT]select name,cost from inventory[/LEFT]

تمامی فیلدهای مربوط به ستون name,cost رو به ما نشون میده
حالا اگر بخوایم که تمامی فیلدها رو ببینیم نیازی نیست که نام همه فیلدها رو بنویسیم، کافیه به جای نام فیلدها " * " رو قرار بدیم. به صورت زیر:

کد:
[LEFT]select * from inventory[/LEFT]

حالا این دستورات رو چطور در دلفی استفاده کنیم؟ از تب ADO یه کامپوننت ADOQuery به فرم اضافه کنید و کد رو در یه button به صورت زیر بنویسید:

کد:
[LEFT]ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from table_name');
ADOQuery1.Open;[/LEFT]

سوالی که اینجا هست اینه که چطور نتایج دلخواه رو بر اساس یه مقدار متغیر نمایش بدیم؟ برای این کار باید از دستور where استفاده کرد.

کد:
[LEFT] SELECT column FROM table WHERE condition[/LEFT]

در قسمت condition میتونیم از شرط های مختلف استفاده کنیم
فرض کنید در همون جدول مشخصات کالا میخوایم کالاهایی که نام اونها در یک edit نوشته میشه رو نمایش بدیم:

کد:
[LEFT]ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from inventory where name=:param');
ADOQuery1.Parameters.ParamValues['param']:=Edit1.Text;
ADOQuery1.Open;[/LEFT]

همونطور که می بینید در مثال بالا از "پارامتر" استفاده شده.

عملگرهای مقایسه ای در sql (که میتونیم برای شرط های مختلف در قسمت condition استفاده کنیم):

کد:
[LEFT]= , <> , < , > , <= , >=[/LEFT]

<> به معنای نا مساوی هست.
همچنین میتونید از عملگرهای منطقی AND و OR برای پیاده سازیهای مختلف استفاده کنید.

موفق باشید
 

farhad110

Member
دستور دیگه ای که کاربرد زیادی درselect داره ORDER BY هست که برای مرتب سازی نتایج بر اساس یه فیلد خاص استفاده میشه.
شکل کلی دستور:

کد:
[LEFT]SELECT * FROM table_name ORDER BY column[/LEFT]

توجه: اگر به جای * از نام فیلد استفاده کنید، مرتب سازی باید بر اساس فیلدی باشه که در نتیجه هم نمایش داده میشه.
میشه در قسمت order by از نام چند فیلد استفاده کرد. مزیت این کار این هست که اگر در فیلد اولی دو مقدار یکسان وجود داشته باشه، همون مقادیر بر اساس فیلد دیگه ای هم مرتب میشن.

کد:
[LEFT]select * from inventory order by name,weight[/LEFT]

در اینجا اگر دو کالا با نام یکسان وجود داشته باشه، بر اساس وزن مرتب میشن

بعد از نام ستونها در قسمت order by اگر DESC رو قرار بدین، نتایج به صورت نزولی مرتب میشن و در صورتی که ASC قرار داشته باشه به صورت صعودی. حالت پیش فرض در زمانی که شما حالت مرتب سازی رو مشخص نکنین، صعودی هست.

برای ادامه کار منتظر نظرات دوستان هستم.
موفق باشید.
 

farhad110

Member
ادامه آموزشها:
فرض کنید شما میخواین تمام مقادیر بین دو مقدار مشخص رو داشته باشین. مثلا مقادیری که وزن اونها از 15 بیشتر و از 75 کمتر باشه. با توجه به آموزشهایی که تا حالا گفته شده با استفاده از where و عملگر and میشه این کار رو به صورت زیر انجام داد:

کد:
[LEFT]select * from inventory where weight>15 and weight<75[/LEFT]

اما یه راه دیگه هم هست. میتونین به جای نوشتن شرط های مختلف از between استفاده کنید:

کد:
[LEFT]with ADOQuery1 do begin
  close;
  sql.Clear;
  sql.add('select * from inventory where weight between 15 and 75');
  open;
  end;[/LEFT]

کد بالا مشخصات تمام کالاهایی رو برمیگردونه که وزن اونها بین 15 و 75 هست.
 

farhad110

Member
بعضی وقتها پیش میاد که چند مقدار خاص از یه فیلد رو میخوایم. باید از 5 یا 6 شرط مختلف استفاده کرد؟
جواب منفیه. شما میتونین از گزینه in در دستور select استفاده کنین (فرض کنید دنبال کالاهایی هستیم که رنگ اونها قرمز، سفید، آبی و سبز هست):
کد:
[LEFT]with ADOQuery1 do begin
  close;
  sql.Clear;
  sql.add('select * from inventory where color in ("قرمز","سفيد","آبي","سبز");
  open;
  end;[/LEFT]

تا به زودی
پیروز باشید
 

farhad110

Member
سلام دوباره، ظاهرا که تا اینجای کار مشکل خاصی نیست.
توی پست قبلی یادم رفت که در مورد between , in یه توضیح بدم که چطور میشه مقدار مورد جستجو رو از کاربر دریافت کنن.
اگر قرار باشه کاربر از edit استفاده کنه و مقادیر مورد نظر رو وارد کنه، در اکثر دستورات sql مقادیر متنی حتما باید بین "" قرار بگیره ("متغیر") ولی برای مقادیر عددی نیازی به " " نیست.
مثال برای between زمانی که در فیلد عددی جستجو میکنیم:

کد:
[LEFT]with adoquery1 do begin
close;
sql.clear;
sql.Add('select * from inventory where weight between '+Edit1.Text+' and '+Edit2.Text);
open;
end;[/LEFT]

مثال برای in زمانی که در فیلد متنی (رشته) جستجو میکنیم:

کد:
[LEFT]ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from inventory where name in ("'+Edit1.Text+'","'+Edit2.Text+'","'+Edit3.Text+'","'+Edit4.Text+'")');
ADOQuery1.Open;[/LEFT]

توجه داشته باشید که برعکس where که به تعریف پارامتر نیاز بود، اینجا نیازی به اینکار نیست و فقط کافیه متغیر رو بین دستورات به شکل صحیح جا بدیم.

توجه: در دستور in فرقی نداره که مقدار عددی باشه یا رشته، حتما از پرانتز استفاده کنید.

تا اینجا اگر سوالی هست بفرمایید، وگرنه ادامه آموزشها...
پیروز باشید
 

Blaster6

Member
ممنون که همت کردید این کار مفید را شروع کردید. sql همه جا لازم است و به فرمایش شما با استفاده از sql کارها راحت تر انجام می شود. خواهشا ادامه دهید. خیلی عالی گفتید.
 

farhad110

Member
سلام دوباره و ممنون از شما دوست عزیز.
خوشبختانه تا اینجا که ظاهرا مشکلی نیست. پس ادامه:
در حالت عادی وقتی که از query ها استفاده میشه title مربوط به dbgrid نام فیلدهایی هست که در دستورات sql استفاده شده و معمولا به زبان انگلیسی هست. پس تکلیف برنامه های ما که به زبان فارسی هست چیه؟
برای حل این مشکل میتونید از Alias استفاده کنید. شکل کلی دستور به صورت زیر هست:

کد:
[LEFT]SELECT column AS column_alias FROM table[/LEFT]

حالا میخوایم که نتایج در dbgrid به صورتی نشون داده شه که دو فیلد name,color انتخاب شه و title مربوط به اونها "نام و رنگ" باشه:

کد:
[LEFT]with ADOQuery1 do begin
  close;
  sql.Clear;
  sql.add('select name as نام, color as رنگ from inventory');
  open;
  end;[/LEFT]

حتی اگر نام جدول هم خیلی طولانی هست و شما رو کلافه کرده میتونید از Alias به همین صورت که توضیح داده شده برای کوتاه کردن نام جدول استفاده کنید و جدول رو با نام دلخواه در برنامه خودتون به کار بگیرید.

پیروز باشید
 

MnavidM

Active Member
فرهاد جان ، خوب پیش میری. دستت درد نکنه.

تاپیک به مهم تبدیل گردید.
 

farhad110

Member
خواهش میکنم نوید جان و ممنون به خاطر مهم شدن تاپیک.

امروز میخوام DISTINCT رو بگم:
تا حالا پیش اومده که بخواین تمام مقادیر یک فیلد رو توی combobox یا یه جدول دیگه داشته باشین؟ اگر همچین موردی بوده حتما میدونید که تمام مقادیر تکراری موجود در فیلد، در نتیجه حاصل هست. ممکنه چندین مقدار تکراری در یک فیلد وجود داشته باشه و بی دلیل به لیست مورد نظر شما اضافه شده باشه. راه حل این مشکل استفاده از DISTINCT در SQL هست.
شکل کلی دستور به صورت زیر هست:

کد:
[LEFT]SELECT DISTINCT column FROM table[/LEFT]

به طور کلی این مورد به شما کمک میکنه مقادیر منحصر به فرد یک فیلد رو داشته باشید.
فرض کنید لیست کالاهای موجود در جدول نمونه رو میخوایم تا بدونیم که چه کالاهایی موجود هست، مطمئنا نیازی به نام های تکراری نداریم:

کد:
[LEFT]with adoquery1 do begin
close;
sql.clear;
sql.add('select distinct name from inventory');
open;
end;[/LEFT]

پیروز باشید
 

farhad110

Member
سلام
یکی دیگه از دستوراتی که زمان جستجو خیلی کارآمد هست، دستور LIKE هست که به همراه where استفاده میشه. این دستور برای زمانی هست که ما به دنبال تمام مقادیری هستیم که با یک یا چند حرف مشخص شروع میشه و یا تمام میشه، و یا حتی این چند حرف میتونه جزیی از نتیجه باشه.

شکل کلی دستور:

کد:
[LEFT]SELECT column FROM table
WHERE column LIKE pattern[/LEFT]

در قسمت pattern مشخص میکنیم که نتیجه حاصل بر چه اساسی باشه.
به مثال توجه کنید:

کد:
[LEFT]with ADOQuery1 do begin
close;
sql.Clear;
sql.Add('select * from inventory where name like "'+Edit6.Text+'%"');
open;
end;[/LEFT]

فرض میکنیم که مقادیر فیلد name قطعات سخت افزاری هستند. در مثال بالا اگر در edit1 مقدار "مانیتور" وارد شه، تمام مقادیری که با "مانیتور" شروع شده مثل "مانیتور Samsung، مانیتور LG ، مانیتور BenQ و ..." به نمایش در میاد.
با کمی خلاقیت اگر این کد رو در رویداد OnChange یک ادیت قرار بدیم با تایپ اولین حرف مثلا "م" تمام مقادیر "مانیتور، ماوس، مادر بورد" و بقیه مقادیری که با "م" شروع میشه به نمایش در میاد.

اگر به محل کاربرد "%" دقت کنید، خودتون میتونید شرط هایی که با نیاز شما سازگارتر هستند بنویسید.

پیروز باشید.
 

farhad110

Member
سلام. نکته ای که فراموش کردم در مورد select بگم اینه که select میتونه اطلاعات چند جدول رو با هم در یک query به شما نمایش بده. پس شما میتونید اطلاعاتی رو که میخواین از دو یا چند جدول انتخاب کنید.
این کار به JOIN معروف هست.

کد:
[LEFT]SELECT table_1.column1, table_1.column2, table_2.column
FROM table_1, table_2
WHERE condition[/LEFT]

کاربرد join در جداول master/detail بیشتر هست که جدولها بر اساس یک فیلد کلید با هم ارتباط دارند. فرض کنید در همین جدول inventory فیلد no مربوط به کد کالا، کلید هست. و جدول دیگه ای هم وجود داره به نام جدول orders که سفارش اشخاص بر اساس کد کالا در اون ذخیره میشه (پس فیلد no که در inventory کلید اصلی هست، در orders به عنوان کلید خارجی استفاده میشه) فیلدهای جدول orders میتونه "person_id(کلید اصلی) – no – fname – lname " باشه.

حالا ما میخوایم ببینیم چه افرادی چه کالاهایی رو سفارش دادند:
کد:
[LEFT]with adoquery1 do begin
close;
sql.Clear;
sql.Add('select orders.fname, orders.lname, inventory.name from orders, inventory where inventory.no=orders.no');
open;
end;[/LEFT]

نتیحه حاصل شامل نام و نام خانوادگی اشخاص از جدول orders و نام کالا از جدول inventory هست.

پیروز باشید
 

farhad110

Member
سلام
JOIN رو که در پست قبلی توضیح دادم موارد INNER JOIN , LEFT JOIN , RIGHT JOIN رو داره که توضیح میدم:
شکل کلی دستور در INNER JOIN :

کد:
[LEFT]SELECT field1, field2, field3
FROM first_table
INNER JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield[/LEFT]

شکل کلی دستور در LEFT JOIN :

کد:
[LEFT]SELECT field1, field2, field3
FROM first_table
LEFT JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield[/LEFT]

شکل کلی دستور در RIGHT JOIN :

کد:
[LEFT]SELECT field1, field2, field3
FROM first_table
RIGHT JOIN second_table
ON first_table.keyfield = second_table.foreign_keyfield[/LEFT]

مثال برای Inner Join :
کد:
[LEFT]with adoquery1 do begin
close;
sql.Clear;
sql.Add('select inventory.name, inventory."cost", orders.fname, orders.lname');
sql.Add('from inventory');
sql.Add('inner join orders');
sql.Add('on inventory.no=orders.no');
open;
end;[/LEFT]

تفاوت inner , left , right :

در Inner join تمام رکوردهای دو جدول، هر جا که شرط مطابقت داشته باشه نمایش داده میشه و اگر در جدول اول رکوردی وجود داشته باشه که با هیچ رکوردی از جدول دوم مطابقت نداشته باشه، در نتیجه نهایی نمایش داده نمیشه.
در Left join تمام رکوردها از جدول اول نمایش داده میشه، حتی اگر با هیچ رکوردی از جدول دوم مطابقت نداشته باشه.
Right join برعکس left join عمل میکنه و تمام رکوردهای جدول دوم رو نمایش میده، حتی اگر با هم مطابقت نداشته باشند.

با روش آزمون و خطا و مثالهای مختلف میتونین دقیقا متوجه شین که کار این دستورات چی هست.
پیروز باشید
 

farhad110

Member
یکی دیگه از توابع sql که میتونه مفید باشه IS NULL هست.
این تابع زمانی کاربرد داره که شما میخوای تمام فیلدهای null (خالی) رو پیدا کنی.

شکل کلی دستور:

کد:
[LEFT]SELECT Column FROM table WHERE column IS NULL[/LEFT]

کد زیر تمام رکوردهایی رو برمیگردونه که فیلد name اونها خالی هست:

کد:
[LEFT]with adoquery1 do begin
close;
sql.Clear;
sql.Add('select * from inventory where name is null');
open;
end;[/LEFT]

توجه کنید که null با space (" ") تفاوت داره.

اگر خواستید رکوردهای پر شده رو پیدا کنید، دستور رو به صورت زیر تغییر بدید:

کد:
[LEFT]select * from table where FieldName is not null[/LEFT]

تا به زودی...
پیروز باشید
 

farhad110

Member
استفاده از محاسبات ریاضی:
در حالت عادی و قتی که از table ها استفاده میشه، برای محاسبات روی تمام مقادیر یه فیلد، میومدیم و یه فیلد جدید از نوع calculate درست میکردیم و در OnCalcFields مربوط به جدول چند خط کد مینوشتیم. اینکار با استفاده از دستورات sql فوق العاده راحت هست.
شکل کلی دستور:

کد:
SELECT field1,field2,field3 <arithmatic operation> AS AliasName FROM table

به جای قسمت <arithmatic operation> یه عبارت محاسباتی قرار میگیره.
به مثال توجه کنید (تمام مقادیر فیلد cost با 2000 جمع میشه و در ستون new_cost قرار میگیره):

کد:
with adoquery1 do begin
close;
sql.Clear;
sql.Add('select name,cost+2000 as new_cost from inventory');
open;
end;

پیروز باشید
 

farhad110

Member
سلام دوباره پس از مدتها!
Sql یه سری تابع خیلی مفید برای انجام عملیات روی فیلدها داره که میتونه خیلی مفید باشه. این توابع در دو دسته کلی قرار گرفته: Aggregate Functions و Scalar functions .

توابع Aggregate :
کد:
SUM(column)
مجموع مقادیر فیلد

AVG(column)
میانگین یک فیلد

MAX(column)
بیشترین مقدار فیلد

MIN(column)
کمترین مقدار فیلد

COUNT(column)
تعداد سطرهای یک فیلد (بدون محاسبه مقادیر Null)

COUNT(*)
تعداد کل رکوردهای جدول

FIRST(column)
اولین مقدار فیلد

LAST(column)
آخرین مقدار فیلد
البته 4 تا تابع دیگه هم هست که فکر میکنم مربوط به محاسبه واریانس و ... باشه. ریاضی دانها کمک کنند:


کد:
[LEFT]STDEV(column)
STDEVP(column)
VAR(column)
VARP(column)
[/LEFT]

توی پست بعدی توابع Scalar رو توضیح میدم.
پیروز باشید
 

farhad110

Member
توابع Scalar :
برعکس توابع Aggregate که بر روی تمام مقادیر فیلد عمل میکنه، این توابع مقادیر رو تک تک پردازش میکنه و نتیجه رو نمایش میده.

کد:
UCASE(column)
تبدیل کاراکترهای فیلد به حروف بزرگ (برای کاراکترهای a تا z)


کد:
LCASE(column)
تبدیل کاراکترهای فیلد به حروف کوچک (برای کاراکترهای A تا Z)


کد:
MID(column,start,end)
از محل start به میزان end کاراکتر از فیلد جدا کرده و نمایش میدهد (start و end اعداد صحیح هستند)


کد:
LEN(column)
مشخص کردن طول رشته های فیلد


کد:
INSTR(column,”ch”)
نمایش محل وقوع کاراکتر ch در فیلد


کد:
LEFT(column, number)
جدا کردن تعداد کاراکتر مشخص، از سمت چپ مقادیر فیلد


کد:
RIGHT(column, number)
جدا کردن تعداد کاراکتر مشخص، از سمت راست مقادیر فیلد


کد:
ROUND(column, decimals)
رند کردن اعداد اعشاری و مشخص کردن دقت اعشار


کد:
NOW()
نمایش تاریخ و زمان

سوالی بود در خدمتم.
پیروز باشید
 

جدیدترین ارسال ها

بالا