یوسف زالی
جمعه 31 تیر 1390, 19:40 عصر
سلام.
با اجازه این بار می خوام در مورد Stored Procedure ها کمی بنویسم:
Stored Procedure یا SP اصلا چی هست:
مجموعه چند دستور پشت سر هم هستند که در قالب یک شی ذخیره میشن. این دستورات تقریبا میتونن هرچیزی باشن. (دستوراتی که می تونن در قالب یک Batch باشن. مثلا مجاز نیستیم در یک SP یک SP دیگه بسازیم. همون دستوراتی که بدون گذاشتن GO بین اونها بشه ازشون استفاده کرد. اطلاعات بیشتر = سرچ کلمه GO در همین سایت)
کاربرد:
گاهی ما نیاز داریم که چند تا کار رو همیشه انجام بدیم. مثلا برای ثبت سفارش اول تست کنیم ببینیم شرایط خاصی وجود داره یا نه، بعد جدولی رو آپدیت کنیم، بعد سلکت کنیم...
خوبی SP اینه که در اون می تونیم شرط - حلقه - تراکنش - فراخوانی یک SP دیگه - ساخت گزارش وابسته به پارامتر و ... داشته باشیم.
فرقش با View چیه؟
در View فقط Select گذاشته می شه و بدون پارامتر از اون استفاده میشه.
در SP هر کاری میشه کرد. پارامتر هم میشه پاس داد. مثل پروسیجر های IDE هست.
SP ها و اصولا تمام دستورات حتی اونهایی که در کامند ها نوشته میشه همه روی سرور ران میشه.
موضوع SP با موضوع کامند هایی که در IDE ساخته میشه دو چیز متفاوته.
شما می تونی همون کارهایی که در SP می کنی در کامند کنی ولی SP این اجازه رو میده که کد شما خواناتر بشه و کوتاهتر..
یکی دیگه از مزیتهای SP هم اینه که روی سرور اس کیو ال اصطلاحا کش میشه. یعنی بعد از ایجاد اون به صورت کامپایل شده استفاده میشه و سرعت اجراش چندین برابر کامند میشه.
کش شدن یه داستان دیگه داره که خیلی واردش نمی شم (چون بلد نیستم! :لبخند:)
اما بریم سراغ تعریف SP.
مثال های سریع:
Create Procedure SPName as blabla
Alter Procedure SPName as blabla
Create Proc SPName (@Param1 as DataType, @Param2 as DataType ) as blabla
Create Procedure SPName @Param1 DataType, @Param2 DataType = DefaultValue as blabla
یک مثال ساده:
پروسیجری که سال مالی میگیره و داده های سال مورد نظر رو سلکت می کنه:
Create Procedure SelectWithYear @FiscalYear int as
select * from Accounts where AccountYear = @FiscalYear
پروسیجری که داده هایی رو به روز می کنه:
Create Proc P1 @price decimal, @amount decimal, @goodcode int as
begin
if @amount > 0
update TBL_Goods set GoodPrice = @Price , GoodAmnt = @Amount
where GoodCode = @GoodCode
else
begin
set @amount = 1
insert into TBL_Goods select @GoodCode, @amount, @Price
end
end
این فقط مثاله و در عمل ممکنه هیچ کاربردی نداشته باشه.
فراخوانی یک SP:
در خود SQL برای فراخوانی یک SP از دستور EXEC یا همون EXECUTE استفاده میشه.
مثال بالا:
Exec P1 4500, 20, 21003
همونطوری که می بینید پارامتر ها رو مقابل اسم SP نوشتیم.
اگر در UI از شی ADOStoredProc استفاده می کنین کافیه که اون رو ExecProc کنید.
ADOSP.ExecProc
اما اگر در SP یک سلکت داشتید و خواستید اون رو از UI با ADOStoredProc اجرا کنید اون رو Open کنید.
ADOSP.Open
اگر از کامند استفاده می کردید شکل فراخوانی در SQL رو به کار ببرید.
Exec P1 blabla
دقیقا مثل دستوراتی که تا به حال در کامند ها استفاده می کردید.
نکته ها:
اون DefaultValue چی بود جلوی تعریف SP بالاییه؟
مواقعی که برای پارامتر ورودی مقداری معین نکرده بودیم اون مقدار به SP فرستاده میشه.
نمی تونیم پارامتری به SP دارای پارامتر پاس ندیم اگر default نداشت.
آیا SP می تونه مقداری return کنه؟ خب به چه دردی می خوره؟
بله. اما این مقدار همیشه باید یک عدد صحیح باشه.
در مواقعی خصوصا در کنترل خطا ها به کار میاد.
مثلا تصور کنید اگر شرطی برقرار نبود ما 1- بر می گردونیم و تو UI تست می کنیم که خروجی اون اگر 1- بود پیغامی نمایش داده بشه.
یا مثلا پس از Insert در جدول می تونیم Identity@@ رو برگردونیم تا بفهمیم ID ردیفی که الان زدم چند شد.
create procedure P1 as
insert into TBL1 values(1, 2) -- dade haye nemune
return @@identity
چه شکلی کد برگشتی رو میگیریم؟
در SQL:
declare @ret int
Exec @ret = SPName params
در ADOStoredProc :
ADOSP.Parameters.ParamByName('@Return_Value').Valu e
آیا در SP میشه هم Select کرد هم Insert کرد؟
بله اما توصیه میشه که SP های Select جدا از SP های دستکاری داده ها نوشته بشن.
آیا میشه ترتیب پارامتر ها رو جابجا پاس کرد؟
بله. با آوردن مستقیم نام پارامتر در فراخوانی:
Execute SPName @Amountt = 250, @GoodCode = 21003, @Price = 5500
دیگه عقلم به جایی نمی رسه فعلا.
اگر سوال داشتید بگید راهنمایی کنم.
موفق باشید.
با اجازه این بار می خوام در مورد Stored Procedure ها کمی بنویسم:
Stored Procedure یا SP اصلا چی هست:
مجموعه چند دستور پشت سر هم هستند که در قالب یک شی ذخیره میشن. این دستورات تقریبا میتونن هرچیزی باشن. (دستوراتی که می تونن در قالب یک Batch باشن. مثلا مجاز نیستیم در یک SP یک SP دیگه بسازیم. همون دستوراتی که بدون گذاشتن GO بین اونها بشه ازشون استفاده کرد. اطلاعات بیشتر = سرچ کلمه GO در همین سایت)
کاربرد:
گاهی ما نیاز داریم که چند تا کار رو همیشه انجام بدیم. مثلا برای ثبت سفارش اول تست کنیم ببینیم شرایط خاصی وجود داره یا نه، بعد جدولی رو آپدیت کنیم، بعد سلکت کنیم...
خوبی SP اینه که در اون می تونیم شرط - حلقه - تراکنش - فراخوانی یک SP دیگه - ساخت گزارش وابسته به پارامتر و ... داشته باشیم.
فرقش با View چیه؟
در View فقط Select گذاشته می شه و بدون پارامتر از اون استفاده میشه.
در SP هر کاری میشه کرد. پارامتر هم میشه پاس داد. مثل پروسیجر های IDE هست.
SP ها و اصولا تمام دستورات حتی اونهایی که در کامند ها نوشته میشه همه روی سرور ران میشه.
موضوع SP با موضوع کامند هایی که در IDE ساخته میشه دو چیز متفاوته.
شما می تونی همون کارهایی که در SP می کنی در کامند کنی ولی SP این اجازه رو میده که کد شما خواناتر بشه و کوتاهتر..
یکی دیگه از مزیتهای SP هم اینه که روی سرور اس کیو ال اصطلاحا کش میشه. یعنی بعد از ایجاد اون به صورت کامپایل شده استفاده میشه و سرعت اجراش چندین برابر کامند میشه.
کش شدن یه داستان دیگه داره که خیلی واردش نمی شم (چون بلد نیستم! :لبخند:)
اما بریم سراغ تعریف SP.
مثال های سریع:
Create Procedure SPName as blabla
Alter Procedure SPName as blabla
Create Proc SPName (@Param1 as DataType, @Param2 as DataType ) as blabla
Create Procedure SPName @Param1 DataType, @Param2 DataType = DefaultValue as blabla
یک مثال ساده:
پروسیجری که سال مالی میگیره و داده های سال مورد نظر رو سلکت می کنه:
Create Procedure SelectWithYear @FiscalYear int as
select * from Accounts where AccountYear = @FiscalYear
پروسیجری که داده هایی رو به روز می کنه:
Create Proc P1 @price decimal, @amount decimal, @goodcode int as
begin
if @amount > 0
update TBL_Goods set GoodPrice = @Price , GoodAmnt = @Amount
where GoodCode = @GoodCode
else
begin
set @amount = 1
insert into TBL_Goods select @GoodCode, @amount, @Price
end
end
این فقط مثاله و در عمل ممکنه هیچ کاربردی نداشته باشه.
فراخوانی یک SP:
در خود SQL برای فراخوانی یک SP از دستور EXEC یا همون EXECUTE استفاده میشه.
مثال بالا:
Exec P1 4500, 20, 21003
همونطوری که می بینید پارامتر ها رو مقابل اسم SP نوشتیم.
اگر در UI از شی ADOStoredProc استفاده می کنین کافیه که اون رو ExecProc کنید.
ADOSP.ExecProc
اما اگر در SP یک سلکت داشتید و خواستید اون رو از UI با ADOStoredProc اجرا کنید اون رو Open کنید.
ADOSP.Open
اگر از کامند استفاده می کردید شکل فراخوانی در SQL رو به کار ببرید.
Exec P1 blabla
دقیقا مثل دستوراتی که تا به حال در کامند ها استفاده می کردید.
نکته ها:
اون DefaultValue چی بود جلوی تعریف SP بالاییه؟
مواقعی که برای پارامتر ورودی مقداری معین نکرده بودیم اون مقدار به SP فرستاده میشه.
نمی تونیم پارامتری به SP دارای پارامتر پاس ندیم اگر default نداشت.
آیا SP می تونه مقداری return کنه؟ خب به چه دردی می خوره؟
بله. اما این مقدار همیشه باید یک عدد صحیح باشه.
در مواقعی خصوصا در کنترل خطا ها به کار میاد.
مثلا تصور کنید اگر شرطی برقرار نبود ما 1- بر می گردونیم و تو UI تست می کنیم که خروجی اون اگر 1- بود پیغامی نمایش داده بشه.
یا مثلا پس از Insert در جدول می تونیم Identity@@ رو برگردونیم تا بفهمیم ID ردیفی که الان زدم چند شد.
create procedure P1 as
insert into TBL1 values(1, 2) -- dade haye nemune
return @@identity
چه شکلی کد برگشتی رو میگیریم؟
در SQL:
declare @ret int
Exec @ret = SPName params
در ADOStoredProc :
ADOSP.Parameters.ParamByName('@Return_Value').Valu e
آیا در SP میشه هم Select کرد هم Insert کرد؟
بله اما توصیه میشه که SP های Select جدا از SP های دستکاری داده ها نوشته بشن.
آیا میشه ترتیب پارامتر ها رو جابجا پاس کرد؟
بله. با آوردن مستقیم نام پارامتر در فراخوانی:
Execute SPName @Amountt = 250, @GoodCode = 21003, @Price = 5500
دیگه عقلم به جایی نمی رسه فعلا.
اگر سوال داشتید بگید راهنمایی کنم.
موفق باشید.