PDA

View Full Version : حرفه ای: راهی برای کم کردن تعداد فراخوانی function ها در این کوئری



Rejnev
چهارشنبه 23 دی 1388, 22:05 عصر
سلام
برای مشاهده گردش حساب اشخاص فرض کنید کوئری ای بصورت زیر نوشتیم



select
code,
Name,
Daryaft(code),
Pardakht(code),
Daryaft(code) - Pardakht(code),
case when (Daryaft(code) - Pardakht(code))>0 then 'bestankar'
when (Daryaft(code) - Pardakht(code))<0 then 'bedehkar'
else 'biHesab'
end


که فرضا توابع daryaft و pardakht (دریافت و پرداخت) کد شخص رو گرفته و مجموع پرداختی های شخص رو از جدول مربوطه به خود برمیگردونند.
مشکلی که هست اینه که هر تابع چهار بار فراخوانی شده که بهینه نیست!
چکارش باید کرد.
در این مورد آیا استفاده از cursor پیشنهاد میشه؟

بهنام بهمنی
چهارشنبه 23 دی 1388, 22:24 عصر
1- تا حد امکان از Cursor استفاده نکنيد و سعي کنيد با بقيه دستورات به نتيجه مورد نظر برسيد
2- جهت بهينه سازي -آيا نمي تواني يک Function يا sp بنوسي که کد را گرفته و حاصل را يکدفه برگرداند و يا در يک جدول موقت ذخيره کند؟

Rejnev
چهارشنبه 23 دی 1388, 22:45 عصر
1- یک Function یا sp بنویس که کد را گرفته و حاصل را یکدفه برگرداند و یا در یک جدول موقت ذخیره کند؟

function که فقط یک مقدار رو برمیگردونه.
StoredProc هم توی select نمیشه فراخونی بشه.
tempTable هم فکر نکنم جواب بده(بازدهی) اگه روشی با جدول موقت میدونید لطفا بگید

benyaminrahimi
چهارشنبه 23 دی 1388, 23:00 عصر
function که فقط یک مقدار رو برمیگردونه.
StoredProc هم توی select نمیشه فراخونی بشه.
tempTable هم فکر نکنم جواب بده(بازدهی) اگه روشی با جدول موقت میدونید لطفا بگید


CREATE FUNCTION f_se_check()
RETURNS TABLE
AS RETURN
select * from ...... gggg

:متعجب:
نه دوست عزیز فاکشن میتونه تو خروجی یک دیتا ست رو هم بر گردونه مثال خواستی بگو
---------------
شما میتونی تو یک فانکشن- دریافتی ها وپرداختی های همرو حساب کنی (با استغاده از توابع خودت)

مي توني به صورت يک فانکشن يا temp table داشته باشيد

بعد این فانکشن رو با تیبل جوین می کنی و از روی این دوقدار مانده و ماهیت رو بدست میاری

اینطوری برای هر رکورد
یک بار از تابع دریافت و یک بار از تابع پرداخت استفاده می کنی
چطوره؟:متفکر:


راستي با توجه به کدتون من نفهميدم چطوري مي خواي با کرسر اينو بهينه کني

ممکنه برعکس بشه

Rejnev
چهارشنبه 23 دی 1388, 23:09 عصر
معذرت اصلا یادم نبود returns table :اشتباه:
یعنی تابع حساب تمامی اشخاص رو در جدول برگردونه؟
لطفا بیشتر توضیح بدین

benyaminrahimi
چهارشنبه 23 دی 1388, 23:18 عصر
معذرت اصلا یادم نبود returns table :اشتباه:
یعنی تابع حساب تمامی اشخاص رو در جدول برگردونه؟
لطفا بیشتر توضیح بدین

تو جدول نه تو يک تمپ تيبل يا فانکشن
جدول با اين object جديد join ميشه

Rejnev
پنج شنبه 24 دی 1388, 17:07 عصر
یعنی میگید تابع خروجی زیر رو برگردونه



create function func() returns @retFunc table (code int,daryaft float ,pardakht float) as
begin
insert into @retFunc(code,daryaft,pardakht) (select code,sum(daryaft),sum(pardakht) from tbl group by code)
return
end


code daryaft pardakht
1 5000 3000
2 10000 6000

بعد انتخاب کنیم



select
t.code,
t.name,
f.daryaft ,
f.pardakht,
f.daryaft-f.pardakht, case ...
from tbl t,func() f
where t.code=f.code

bad_boy_2007
پنج شنبه 24 دی 1388, 22:54 عصر
سلام رفیق
به هیچ عنوان برای این کار از فانکشن استفاده نکن

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

ولی فرض کنید عملیات مشتری شامل موارد ذیل است :

دریافت نقد در جدول DaryaftN
دریافت چک در جدول DaryaftCH
پرداخت نقد در جدول PardakhtN
پرداخت چک در جدول PCheck


اول از همه یک ویو درست کن که تمام این داده ها را با کد حساب مشتری و ستون بدهکار و بستانکار با هم یکجا نشون بده .
[در ضمن چون تخصص من تحلیل سیستمهای مالی هست بد نمیدونم توجهت رو به این نکته جلب کنم که اگر قصد داری سیستمت رو دوبل کنی یا سیسمت دوبل هست از همینجا هم میتونی ریز اقلام اسنادت رو در بیاری (SanadDetail ها)]



Select CustomerID , 0 as Debit , Price as Credit from DaryaftN
union All
Select CustomerID , 0 as Debit , Price as Credit from DaryaftCH
union All
Select Price as Debit , 0 as Credit , CustomerID from PardakhtN
union All
Select Price as Debit , 0 as Credit , CustomerID from PardakhtCheck



حالا از این ویو برای هر کاری که دوست داری استفاده کن :

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


Select Sum(Credit-Debit) from VCustomer Where CustomerID=@ID

سومیش میتونه این باشه که میخوای مانده حساب مشتری رو در یک تاریخ بخصوص بدست بیاری (مثلا در پایین فاکتور ها مینوسید مانده از قبل X ، یا در گزارش گردش حساب مشتری از تاریخ X تا Y برای اولین رکورد باید مانده تا تاریخ X را بدست بیاری)
خلاصه برای کلیه اهداف فوق نیاز به همچنین View ای داری ...
[Debit=Bedehkar] , [Credit=Bestankar]

Rejnev
پنج شنبه 24 دی 1388, 23:11 عصر
عالیه :تشویق::تشویق:
خیلی روش جالبی بود
ممنون:لبخندساده: