PDA

View Full Version : مشکل در لینک کردن فانکشن



aliasghar
سه شنبه 23 اسفند 1384, 12:44 عصر
سلام
یک فانکشن ساختم که یک پارامتر ورودی میگیرد و فقط یک رکورد با 2 فیلد باز می گرداند
مثل
SELECT * FROM dbo.GuysHesab('1005')
http://www.barnamenevis.org/forum/attachment.php?attachmentid=2838&stc=1&d=1142328784
حالا میخواهم این فانکشن را با یک جدول دیگر لینک کنم بطوری که پارامتر ورودی را از فیلد لینک شده با جدول دیگر بدست بیاورد
http://www.barnamenevis.org/forum/attachment.php?attachmentid=2839&stc=1&d=1142329287

در شکل دوم توجه کنید
من احتیاج دارم که Guy_Code را از جدول اولی با پارامتر ورودی فانکشن Joinکنم
شاید نتونسته باشم درست توضیح بدم
امیدوارم به بزرگی خودتون ببخشید

AminSobati
سه شنبه 23 اسفند 1384, 13:15 عصر
دوست عزیزم،
Table Valued Functionها در SQL Server 2000 نمیتونین پارامتر رو از جدول دیگه داخل همون Query دریافت کنند. این کار توسط Cross Apply و Outer Apply در SQL Server 2005 امکان پذیره. در 2000 من استفاده از Cursor و Temp Table رو میتونم پیشنهاد کنم.

aliasghar
سه شنبه 23 اسفند 1384, 16:53 عصر
میشه در استفاده از کرسر یا temp ها را برای حل این مشکل یک مثال بزنید
ممنون

AminSobati
سه شنبه 23 اسفند 1384, 17:49 عصر
یک Cursor درست کنین از تک تک IDهایی که باید داخل Function قرار بگیرند. در یک حلقه، IDها رو از Cursor بخونین و نتیجه تابع روی ID رو داخل جدول موقتی بریزید. در نهایت این جدول چیزیه که میخواستین

aliasghar
چهارشنبه 24 اسفند 1384, 07:41 صبح
ممنون
ولی چون فانکشن خروجی من از 2 فیلد تشکیل شده بود این 2 فیلد را بصورت جداگانه در 2 تا اسکالر فانکشن نوشتم و بعد تونستم اسکالر فانکشن ها را به عنوان یک فیلد با جدول اصلی جوین کنم

از نظر شما این راه مشکل ندارد و اینکه اصولاً کدام بهتر است؟
ممنون

AminSobati
چهارشنبه 24 اسفند 1384, 10:38 صبح
علی اصغر جان من متوجه نشدم چجوری جای یک TVF رو با SVF عوض کردی!

aliasghar
چهارشنبه 24 اسفند 1384, 17:32 عصر
امین آقا من TVF و SVF را نمی شناسم هر چه هم در BOF گشتم لغاتی با این شکل نبود ولی متن فانکشن اول و دو فانکشن دوم را مینویسم

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




Create FUNCTION GuysBestan (@GCode Varchar(5))
RETURNS
@Tmp_F TABLE
(
M_Bedeh Money,
M_Bestan Money
)
AS
BEGIN
INSERT @Tmp_F
SELECT ISNULL(SUM(Acc.Bestan), 0) AS Expr1, ISNULL(SUM(Acc.Bedeh), 0) AS Expr2
FROM dbo.Guys G INNER JOIN
dbo.Guys_Acc G_Acc ON G.Guy_Code = G_Acc.G_Code INNER JOIN
dbo.AutoCode Auto ON G_Acc.P_Code = Auto.Acc_Bedeh OR G_Acc.P_Code = Auto.Acc_Bestan INNER JOIN
dbo.Accounting_Code Acc ON G_Acc.Acc_Code = Acc.Acc_Code
WHERE (G.Guy_Code = '1001')
RETURN
END



هر چه سعی کردم این فانکشن را با یک جدول دیگر لینک کنم بطوری که مقدار ورودی یعنی
G.Guy_Code را از جدول دیگر بگیرد نتوانستم تا اینکه این فانکشن را به 2 تا تبدیل کردم به شکل زیر:


ALTER FUNCTION GuysBedeh (@GCode Varchar(5))
RETURNS Money AS
BEGIN
Declare @S_Bedeh Money
SELECT @S_Bedeh = ISNULL(SUM(Acc.Bedeh), 0)
FROM dbo.Guys G INNER JOIN
dbo.Guys_Acc G_Acc ON G.Guy_Code = G_Acc.G_Code INNER JOIN
dbo.AutoCode Auto ON G_Acc.P_Code = Auto.Acc_Bedeh OR G_Acc.P_Code = Auto.Acc_Bestan INNER JOIN
dbo.Accounting_Code Acc ON G_Acc.Acc_Code = Acc.Acc_Code
WHERE (G.Guy_Code = @GCode)
RETURN @S_Bedeh
END


و سپس این را به عنوان یک فیلد جدول صدا زدم مثل این
select Guy_Code,dbo.GuysBestan(Guy_Code) from dbo.Guys

راستش درست جواب داد ولی نمی دونم کارم درست است یا نه؟

AminSobati
چهارشنبه 24 اسفند 1384, 18:52 عصر
TVF=Table Valued Function
SVF=Scalar Valued Function
حق با شماست، در BOL به این اختصارات اشاره ای نشده و اغلب در کتابها و مقالات کاربرد داره...
در مورد تابع اول شما، ظاهرا خروجیه اون تنها یک رکورد خواهد بود که با این حساب (در این مورد خاص) شما نیازی به TVF ندارید.
تابع دوم شما، اگر ایندکس مناسب براش وجود داشته باشه میتونه خیلی سریع عمل کنه. اما استفاده کردن از تابع، باعث میشه جزئیات Query اصلی که از تابع کمک میگیره، در Exec Plan نمایان نشه چون محتویات تابع رو نمیشه در Exec Plan دید.
با توجه به اینکه تابع دوم اساسا یک Query ساده هستش، شما میتونستین این Query رو به عنوان یک Subquery در Query اصلی به کار ببرید. حداقل برای بهینه سازی، من جای شما باشم این کار رو انجام میدم چون تمام Exec Plan رو میبینین و به کمبود ایندکسهای مورد نیاز پی میبرید.

aliasghar
پنج شنبه 25 اسفند 1384, 16:45 عصر
ممنونم :قلب: