PDA

View Full Version : سوال: بازگشت مقدار Stored Procedure به برنامه



hadisalahi2
سه شنبه 13 مهر 1389, 20:10 عصر
با سلام به همگی دوستان.
من یک Stored Procedure به صورت زیر تعریف کردم



CREATE procedure Re_LeaveMerit
@PersonnelID numeric
,@LeaveType Nvarchar(13)

as
Declare @Resulat int
Select @Resulat=Sum(LeaveTime) From LeaveMeritTable
where (PersonnelID = @PersonnelID ) and (LeaveType=@LeaveType)
return @Resulat
GO


داخل دلفی یک ADoStoredProcedure قرار دادم و پارامتر ها رو به صورت زیر به پروسیجر ارسال می کنم



Function TDBForm.Get_LeaveMerit_Value(PersonnelID,LeaveType :String):String;
var TempStr:string[40];
TempInt:Integer;
begin
ADOStoredProc1.Parameters.ParamByName('@PersonnelI D').Value:=PersonnelID;
ADOStoredProc1.Parameters.ParamByName('@LeaveType' ).Value:=LeaveType;
ADOStoredProc1.Open;
end;


ولی متاسفانه بعد از دستور Open پیغام خطای زیر رو میده


'ADOStoredProc1: CommandText does not return a result set'.

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

hadisalahi2
چهارشنبه 14 مهر 1389, 08:30 صبح
یعنی هیچ کس با Stored Procedure کار نکرده؟
هر سوالی من در مورد SP پرسیدم متاسفانه حتا یک جواب هم داده نشده.
دوستان ما رو از ظرات ارزشمندشون بی بهره نگذارند
یا حق

BORHAN TEC
چهارشنبه 14 مهر 1389, 08:57 صبح
در dbExpress به این شکل است:
ابتدا یک SP ایجاد می کنیم. مانند زیر:

CREATE PROCEDURE SELECT_COUNTRIES RETURNS (
RCOUNTRY VARCHAR(15),
RCURRENCY VARCHAR(10)
) AS
BEGIN
FOR SELECT
COUNTRY, CURRENCY FROM COUNTRY
INTO
:rCOUNTRY, :rCURRENCY
DO
SUSPEND;
END

سپس در دلفی از کد زیر استفاده می شود:

SQLDataSet.CommandType := ctQuery;
SQLDataSet.CommandText := ''Select * from SELECT_COUNTRIES';
SQLDataSet.Open;

BORHAN TEC
چهارشنبه 14 مهر 1389, 09:24 صبح
در dbGo:

ADOStoredProc.DataSource := DataSourceName ;
ADOStoredProc.ProcedureName := ProcName;
ADOStoredProc.Parameters.ParamByName('@PersonnelID ').Value := PersonnelID;
ADOStoredProc.Parameters.ParamByName('@LeaveType') .Value := LeaveType;
ADOStoredProc.ExecProc;
حالا با استفاده از همان DataSource میتونید از نتایج بدست آمده استفاده کنید.
البته هنوز این کد رو تست نکردم. :افسرده:
اگه جواب نداد بگید تا درستش کنم!!!

hadisalahi2
چهارشنبه 14 مهر 1389, 09:47 صبح
خوب اینکه با کدهای من فرقی نمیکرد.
من میخوام از اون مقدار برگشتی که در دستور Select با Sum محاسبه میشه استفاده کنم.
اگه نه کدهای شما که هیچ کار خاصی انجام نمیده.
الان موقع اجرای Stored Procedure خطا میده . شما اگه ممکنه ببینید روش برگشت مقدار به دلفی در دستور SQL درسته نوشته شده؟
اگه هم روشی خودتون یاد دارید از پیشنهادتون ممنون میشم.
در کل من میخوام یک مقدار محاسبه شده در SP رو به برنامه دلفی برگردونم حالا به هر روش ممکن.
یا حق

BORHAN TEC
چهارشنبه 14 مهر 1389, 10:36 صبح
راستش الان فقط این کد دم دستم بود که با dbExpress نوشتمش!!!

function TAnbar.GetId(aName: string): string;overload;
var
dbxCommand : TDBXCommand;
dbxReader : TDBXReader;
begin
dbxCommand :=frmDataModule.con.DBXConnection.CreateCommand();
try
dbxCommand.Text := 'SELECT ID FROM STORAGES WHERE NAME = ' + SingleCot + Trim(aName) + SingleCot;
dbxReader := dbxCommand.ExecuteQuery();
try
dbxReader.Next;
Result := dbxReader.Value[0].GetString();
finally
dbxReader.Free
end;
finally
FreeAndNil(dbxCommand);
end;
end;
البته یادم میاد که قبلاً با TADOCommand هم این کار رو کرده بودم!!! :متفکر:

BORHAN TEC
چهارشنبه 14 مهر 1389, 10:56 صبح
الان موقع اجرای Stored Procedure خطا میده . شما اگه ممکنه ببینید روش برگشت مقدار به دلفی در دستور SQL درسته نوشته شده؟

:متفکر: در اون دستور SQL باید بجای procedure از function استفاده کنید.

homayoon_fara
چهارشنبه 14 مهر 1389, 11:51 صبح
سلام دوست عزیز
این مشکل راحت حل میشه
فقط کافیه که به جای ADOStoredProc1.Open; بنویسی ADOStoredProc1.ExecProc;

دستور اولی که نوشتی (ADOStoredProc1.Open) وقتی اجرا میشه ، آخرش باید یک دیتاست به برنامه برگرده اگر دیتاست برنگرده اون ارور ظاهر میشه. اما دستور دوم منتظر دیتاست در خروجی پروسیجر نمیمونه.

موفق باشی.

hadisalahi2
چهارشنبه 14 مهر 1389, 12:21 عصر
فکر کنم شما اصلا به کد من توجه نکردید. چون من میخوام یک عدد رو که حاصل جمع یک فیلده به دلفی برگردونم وگرنه با دستور Select معمولی و برگشت رکوردها یا خوندن مقدار یک فیلد که مشکلی ندارم. من میخوام بدونم کجای دستور من مشکل داره که موقع اجرای دستورات خطای یاد شده رو میده. لازم به ذکره که این دستورات داخل SP که نوشتم هیچ مشکل Syntax نداره ولی نمیدونم چرا موقع اجرا در دلفی این پیغام خطا رو میده.

hadisalahi2
چهارشنبه 14 مهر 1389, 12:33 عصر
سلام دوست عزیز
این مشکل راحت حل میشه
فقط کافیه که به جای ADOStoredProc1.Open; بنویسی ADOStoredProc1.ExecProc;

دستور اولی که نوشتی (ADOStoredProc1.Open) وقتی اجرا میشه ، آخرش باید یک دیتاست به برنامه برگرده اگر دیتاست برنگرده اون ارور ظاهر میشه. اما دستور دوم منتظر دیتاست در خروجی پروسیجر نمیمونه.

موفق باشی.

با تشکر.
این تغییر رو انجام دادم ، دلفی بدون خطا Sp رو اجرا میکنه.
حالا چطور باید اون مقدار برگشتی رو تو دلفی بخونم.چطور اون مقدار رو مثلا داخل یک متغیر بریزم؟

hadisalahi2
چهارشنبه 14 مهر 1389, 12:37 عصر
البته وقتی با دستور زیر میخوام اون مقدار Result رو بخونم بازهم خطا میده که این پارامتر قابل شناسایی نیست



TempInt:=ADOStoredProc1.Parameters.ParamByName('@R esult').Value;

homayoon_fara
چهارشنبه 14 مهر 1389, 12:57 عصر
این هم به صورت زیر قابل اجراست
با همون اسمی که تو SQL متغیر برگشتی تعریف کردی، تو پارامترهای ADOStoredProcedure هم متغیر تعریف کن
اینجا میشه @Resulat بعد نوع اون رو اینجوری قرار بده : Direction=pdReturnValue
حالا خط زیر همونی میشه که می خوای:

i:=ADOStoredProc1.Parameters.ParamByName('@Resulat ').Value;

(البته اگه در حین Design Time به دیتابیس وصل باشی به طور اتومات خود این متغیر در لیست پارامتر های ADOStoredProcedure اضافه میشه و کلا تمام متغیر هایی که توی پروسیجرت تعریف کردی توی لیست پارامتر ها اسمشون میاد)
موفق باشی

K.Mohammadreza
چهارشنبه 14 مهر 1389, 15:32 عصر
با سلام
این لینک http://www.ibphoenix.com/main.nfs?a=ibphoenix&s=1241006165:25&page=ibp_sps_delphi

و این لینک http://www.google.com/search?hl=fa&q=Stored+Procedure+and+Back+Result+in+Delphi&lr=

و این لینک http://www.daniweb.com/forums/thread141614.html فکر کنم کمک کنه که مشکتونو حل کنید

hadisalahi2
پنج شنبه 15 مهر 1389, 10:30 صبح
با سلام
این لینک http://www.ibphoenix.com/main.nfs?a=ibphoenix&s=1241006165:25&page=ibp_sps_delphi

و این لینک http://www.google.com/search?hl=fa&q=Stored+Procedure+and+Back+Result+in+Delphi&lr=

و این لینک http://www.daniweb.com/forums/thread141614.html فکر کنم کمک کنه که مشکتونو حل کنید

با تشکر
هیچ کدوم از اینها نتونست کار من رو راه بندازه
همه چی داشت به غیر از اون چیزی که من میخواستم

hadisalahi2
پنج شنبه 15 مهر 1389, 10:36 صبح
این هم به صورت زیر قابل اجراست
با همون اسمی که تو SQL متغیر برگشتی تعریف کردی، تو پارامترهای ADOStoredProcedure هم متغیر تعریف کن
اینجا میشه @Resulat بعد نوع اون رو اینجوری قرار بده : Direction=pdReturnValue
حالا خط زیر همونی میشه که می خوای:

i:=ADOStoredProc1.Parameters.ParamByName('@Resulat ').Value;

(البته اگه در حین Design Time به دیتابیس وصل باشی به طور اتومات خود این متغیر در لیست پارامتر های ADOStoredProcedure اضافه میشه و کلا تمام متغیر هایی که توی پروسیجرت تعریف کردی توی لیست پارامتر ها اسمشون میاد)
موفق باشی

متاسفانه روش شما هم جواب نداد و هنگام خواندن مقدار Result پیغام میده که این پارامتر رو نمی شناسم.
هم در حالت طراحی تست کردم و هم در حالت اجرا.
موقع اجرا پارمتر @Result رو شناسایی میکنه ولی موقع خوندن نمیتونه مقدارش رو بخونه

homayoon_fara
پنج شنبه 15 مهر 1389, 11:47 صبح
سلام
عجب ، پس کار نکرد

یه مثال نوشتم که کار میکنه. تستش کن. (پروژه با دلفی 2009 و دیتابیسش با SQL2008)

تو فایل ضمیمه یه فایله با نام DB.BAK یه دیتابیس تو sql بساز با نام DB بعد این فایل رو روی دیتابیست Restore کن، فقط موقع Restore کردن حتما گزینه "Over write the existing database" رو که تو مونی Option هست رو تیک بزن.

بعد از اینکه دیتابیست درست Restore شد ، حالا پروژه رو تو دلفی باز کن و ADOConnection1.ConnectionString رو مطابق با تنضیمات SQL سرورت تنظیم کن.

حالا میتونی برنامه رو اجرا کنی.
موفق باشی.

hadisalahi2
پنج شنبه 15 مهر 1389, 12:08 عصر
متاسفانه نتونستم فایل پشتیبان رو بازیابی کنم.
اگه ممکنه همون دستوراتی رو که در Sp نوشتی برام بنویس تا خودم وارد دیتابیس کنم.
یا حق

homayoon_fara
پنج شنبه 15 مهر 1389, 12:17 عصر
SQL سرورت چه ورژنیه؟

hadisalahi2
پنج شنبه 15 مهر 1389, 12:51 عصر
SQL سرورت چه ورژنیه؟

SQl Server 2000

M aJi D
جمعه 16 مهر 1389, 01:45 صبح
سلام.
دوست عزيز براي برگردوندن مقداري از بانك به دلفي بايد اولاً نوع دادت را انتخاب كني دوماً بريزيش تو 1 متغيير اينجوري:

adoquary.sql.text :="select ....."
adoquary.parameters.....
adoquary.open.
تااينجا فقط استور پروسيجر انجام ميشه و جستجو ميكنه.بعد بايد بريزيش تو 1 متغيير كه نوعشم بايد با نتيجه ي جستجوت همسان باشه :
x:integer;
x := adoquary.fields[0].asinteger;
يا
x:string;
x := adoquary.fields[0].asstring;

موفق باشي

homayoon_fara
جمعه 16 مهر 1389, 10:20 صبح
سلام
دیتابیس رو تبدیل کردم به SQL2000.
تو فایلی که فرستادم 2 تا فایله ، یکی با پسوند BAK و دیگری با پسوند sql.

اول فایل DB.BAK رو Restore کن روی دیتابیس DB اگر احیانا باز ارور داد ، این کارو انجام بده:
یه دیتابیس به نام DB بساز بعد Query Analyzer باز کن و توش فایل دومی "DB.sql" که برات فرستادم رو Open کن
بعد کلید F5 رو بزن تا اجرا بشه. اون وقت دیتابیس، اطلاعات داخلش و StoredProcedure به طور اتومات ساخته میشه

دیگه امیدوارم ایرادی به وجود نیاد.

hadisalahi2
جمعه 16 مهر 1389, 10:22 صبح
سلام.
دوست عزيز براي برگردوندن مقداري از بانك به دلفي بايد اولاً نوع دادت را انتخاب كني دوماً بريزيش تو 1 متغيير اينجوري:

adoquary.sql.text :="select ....."
adoquary.parameters.....
adoquary.open.
تااينجا فقط استور پروسيجر انجام ميشه و جستجو ميكنه.بعد بايد بريزيش تو 1 متغيير كه نوعشم بايد با نتيجه ي جستجوت همسان باشه :
x:integer;
x := adoquary.fields[0].asinteger;
يا
x:string;
x := adoquary.fields[0].asstring;

موفق باشي

دوست عزیز مثل اینکه شما اصلا به سوال من توجه نکردید.
من میخوام با SP این کار انجام بشه نه با ADOQuery
یا حق

homayoon_fara
جمعه 16 مهر 1389, 10:27 صبح
اتفاقا شما به جواب من توجه نمیکنی

اگه کارایی که گفتم و انجام میدادی ، میدیدی که چطور میشه از تو دلفی مقدار برگشتی SP رو Fetch کرد.

این مثالی که فرستادم کاملا نحوه کار با SP رو از تو دلفی نشونت میده اما متاسفانه گوش به حرف نمیدی
حتی حاظر نشدی این فایل رو یک بار دانلود کنی ببینی چی داخلشه.
فایل DB.sql یه فایل script هستش نه یه query معمولی. یک بار که از تو query analyzer اجراش کنی دیتابیست ساخته میشه بعد مثالی که برات فرستادم درست کار میکنه

hadisalahi2
جمعه 16 مهر 1389, 10:56 صبح
دوست عزیز جناب homayoon_fara من منظورم شما نبودید.
منظور من اون دوست قبلی بود آقای M aJi D بود نه شما.
من فایل شما رو دانلود کردم و اتفاقا کار من رو هم راه انداخت.
من دقیقا روش های کاری شما رو انجام داده بودم و فقط یک اشتباه کوچیک کرده بودم. من به جای اینکه موقع خواندن مقدار پارامتر از نام Return_Value استفاده کنم از نام Result استفاده میکردم و به همین دلیل برنامه نمی تونست اون پارامتر رو پیدا کنه.
به خاطر وقتی که گذاشتید صمیمانه ازتون تشکر میکنم.
موفق باشید.
یا حق

homayoon_fara
جمعه 16 مهر 1389, 11:05 صبح
سلام دوست عزیز
خوشحالم که مشکل حل شد
عذر میخوام که تند رفتم. ببخشید

موفق و پیروز باشی

hadisalahi2
جمعه 16 مهر 1389, 11:57 صبح
نکته جالب که توی این پست یاد گرفتن این بود که من فکر میکردم متد
ExecProc فقط برای زمانی استفاده میشه که بخوایم یکی از دستورات
Update,Delete,Insert رو استفاده کنیم.
اما حالا فهمیدم که برای اجرای دستورات Select که دارای خروجی محاسباتی هستند نیز باید از این متد استفاده کرد.