PDA

View Full Version : مبتدی: حلقه for با Stored Procedures



saeed_r67
جمعه 23 مهر 1389, 20:03 عصر
سلام .
از اساتید میشه خواهش کنم که :
یه نمونه ساده for با Stored Procedures (http://barnamenevis.org/forum/showthread.php?t=253379) بزارید که بشه با وی بی اجراش کرد.(مثلا یه فیلد از بانک را رو با شرط خاصی بگیره و بعد انجام تغییرات در فیلد دیگری بریزه). یه جور جنبه آموزشی داشته باشه . ممنون.

حمیدرضاصادقیان
شنبه 24 مهر 1389, 09:09 صبح
سلام.به نظر من شما یک نمونه مثال بزن به همراه چندتا داده بعد دقیقا روند کار رو مشخص کنید.
شاید اصلا نیازی به حلقه FOR نباشه.
در ضمن در Sql server برای حلقه فقط while داریم .

saeed_r67
شنبه 24 مهر 1389, 14:15 عصر
سلام.به نظر من شما یک نمونه مثال بزن به همراه چندتا داده بعد دقیقا روند کار رو مشخص کنید.
شاید اصلا نیازی به حلقه FOR نباشه.
در ضمن در Sql server برای حلقه فقط while داریم .

سلام واقعا از همتون ممنون که برای حل مشکل مشارکت میکنید.
من یه برنامه صندوق نوشتم و قراره به سپرده سود تعلق بگیره . من باید ابتدا فاصله افتتاح سپرده تا تاریخ امروز رو با یه dll محاسبه کنم بعد به تعداد روزش براش سود بریزم .خوب اگه از update استفاده کنم چه جوری باید dll رو توش اسفاده کنم . پس فکر کردم با Stored Procedures میشه.که دقیقا یه حلقه شبیه vb ولی با Stored Procedures که سرعتش بیشتر باشه .
مثال:
دو فیلد با نام tarikh و mojodi در جدول table1 هست .که باید بیام و فاصله فیلد تاریخ رو با تاریخ امروز مقایسه کنم و اختلافش رو بدست بیارم . مثلا اختلاف به روزشون شد 5 روز . حالا باید برای محاسبه سودش این فرمول رو پیاده سازی کنم و برزیم رو فیلد mojodi .مدت (به روز ) ضرب در فیلد mojodi تقسیم بر 36500 حالا باید مقدارش رو بریزم تو فیلد mojodi . یعنی :
mojodi =mojodi +( tarikhroz - tarikh * mojodi / 36500)

tarikhroz = تاریخ فعلی
tarikh = فیلد جدول table1 که حاوی تاریخ ثبت نام می باشد فرضا تاریخ چند روز پیش =
1389/07/01
mojodi= فیلد جدول table1 که حاوی مبلغ سرمایه گذاری شده است . مثلا مبلغ = 2000000

tarikhroz - tarikh = که باید توسط dll محاسبه بشه یعنی تاریخ ثبت و تاریخ روز رو به dll میدم و اختلافشون به روز رو میده .(dll رو زمیمه کردم)
بازم ممنون

behrouzlo
شنبه 24 مهر 1389, 15:17 عصر
نیازی به حلقه نیست شما اگر تاریختان به صورت میلادی ذخیره شده باشد که قضییه حل شده است در غیر اینصورت تاریخیتان را به صورت میلادی تبدیل کنید و از تابع datediff تعداد روزها را به دست آورد

saeed_r67
شنبه 24 مهر 1389, 15:57 عصر
نیازی به حلقه نیست شما اگر تاریختان به صورت میلادی ذخیره شده باشد که قضییه حل شده است در غیر اینصورت تاریخیتان را به صورت میلادی تبدیل کنید و از تابع datediff تعداد روزها را به دست آورد

تاریخ من شمسی . میشه واسه فرضیه تون یه مثال ساده بزنید .

behrouzlo
شنبه 24 مهر 1389, 17:57 عصر
با دو Stored Procedures زیر تست کنید. اولی فقط لیست را نمایش می دهد و دوم Update می کند


Create PROCEDURE GainList
@Date CHAR(10) AS
Declare @MDate CHAR(10) = ''
SET @MDate = dbo.ShamsiToMiladi(@Date)

SELECT Code,mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 )
FROM table1

Create PROCEDURE GainUpdate
@Date CHAR(10) AS
Declare @MDate CHAR(10) = ''
SET @MDate = dbo.ShamsiToMiladi(@Date)

UPDATE table1 SET mojodi = mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 ), tarikh = @Date

تابع dbo.ShamsiToMiladi که تاریخ شمسی را به میلادی تبدیل می کند را می توانید با جستجو از سایت پیدا کنید

saeed_r67
شنبه 24 مهر 1389, 18:26 عصر
با دو Stored Procedures زیر تست کنید. اولی فقط لیست را نمایش می دهد و دوم Update می کند


Create PROCEDURE GainList
@Date CHAR(10) AS
Declare @MDate CHAR(10) = ''
SET @MDate = dbo.ShamsiToMiladi(@Date)

SELECT Code,mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 )
FROM table1

Create PROCEDURE GainUpdate
@Date CHAR(10) AS
Declare @MDate CHAR(10) = ''
SET @MDate = dbo.ShamsiToMiladi(@Date)

UPDATE table1 SET mojodi = mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 ), tarikh = @Date

تابع dbo.ShamsiToMiladi که تاریخ شمسی را به میلادی تبدیل می کند را می توانید با جستجو از سایت پیدا کنید

ممنون از لطفتون .
اگه براتون امکان داره یه خورده توضیح در موردش میدین .
UPDATE table1 SET mojodi = mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 ), tarikh = @Date

***(DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate ) ******
********bo.ShamsiToMiladi(tarikh)***********
فیلد تاریخم تو بانک به صورت شمسی ذخیره میشه .
چه جوری تو VB6 اجراش کنم .
بازم مرسی

saeed_r67
شنبه 24 مهر 1389, 18:39 عصر
UPDATE table1 SET mojodi = mojodi + (DATEDIFF(Day,dbo.ShamsiToMiladi(tarikh),@MDate)* mojodi / 36500 )

اگه دستور فقط UPDATE اینجور که شما نوشتید اجرا بشه دیگه حتی به Stored Procedures هم نیاز ندارم . ولی فکر نکنم طریقه نوشتنش صحیح باشه ، چون ER داد .
اگه بشه دستور UPDATE رو اینجور که نوشتید بتونیم اجرا کنیم که عالی میشه .

saeed_r67
شنبه 24 مهر 1389, 21:10 عصر
سلام .
من یه پروژه میزارم که کمک کنید ممنون میشم. بانک اصلی من SQL است .
ممنون که وقت میزارید.
DLL برای محاسبه اختلاف روز
ماژول هم برای تبدیل تاریخ سیستم به تاریخ شمسی

behrouzlo
یک شنبه 25 مهر 1389, 10:02 صبح
شما تابع ShamsiToMiladi را در Sql Server خود ایجاد کردید یا نه؟ صد در صد به شما باید خطا بدهد چون این تابع روی پایگاه داده شما وجود ندارد

saeed_r67
یک شنبه 25 مهر 1389, 12:13 عصر
شما تابع ShamsiToMiladi را در Sql Server خود ایجاد کردید یا نه؟ صد در صد به شما باید خطا بدهد چون این تابع روی پایگاه داده شما وجود ندارد

سلام . خسته نباشید.
بله من تابع رو تو sql ایجاد نکردم .
من می خواستم که کدی که لصف کردید و گذاشتید رو توسط vb6 اجرا کنم . ولی er داد.اگه واستون مقدوره نحوه ، اجراش تو وی بی رو توضیح بدید . اگه ضمیمه که گذاشتم ، یه نگاه بندازید و کمکم کنید ممنون میشم. اگه واستون مقدور نیست بازم ممنون از لطفی که تا الان گذاشتید .
با تشکر از همه .

Rejnev
پنج شنبه 29 مهر 1389, 18:18 عصر
با سلام
براي اين مسئله هم ميشه تماما از sql و ساخت توابع و روالها توسط آن استفاده كرد و هم از تابع محاسبه اختلاف دو تاريخ كه موجوده و تركيب اون با sql.
*در مورد اول ما به يك تابع در اس كيو ال نياز خواهيم داشت كه اختلاف دوتاريخ رو به ما بده.
بقيه موارد هم با يك دستور select قابل محاسبه خواهد بود.
من در اين مورد استفاده از يك روال(SP) رو پيشنهاد ميكنم كه پارامترهايي از قبيل تاريخ فعلي و احتمالا كد شخص و ... رو گرفته و كوئري را تحويل ميدهد. براي استفاده از اون در vb هم كافيه روال رو با پارامترهاي مناسب اجرا كنيد.
*در مورد دوم يعني استفاده از ويژوال بيسك براي محاسبه اختلاف دو تاريخ هم نياز به يك كوئري خواهيم داشت كه داده هاي خام رو در يك ديتاست(ديتاتيبل ، ليست يا ...) ريخته و با يك حلقه در خود vb ركوردها رو پيمايش كرده و محاسبه رو انجام بديم.
--------------
براي پياده سازي مورد اول
توابع زير رو در بانكتون ايجاد كنيد(اينها رو از همين سايت گرفتم)



CREATE FUNCTION fn_ShamsiDateStrPart (@ADateStr varchar(10), @ADatePart char) RETURNS int
AS
BEGIN
declare @FY varchar(4), @FM varchar(2), @FD varchar(2),
@SlashPos1 int, @SlashPos2 int
if @ADateStr = '' return null
set @SlashPos1 = CHARINDEX('/', @ADateStr)
if (@SlashPos1 = 0) or ((@SlashPos1 <> 3) and (@SlashPos1 <> 5)) return null
set @SlashPos2 = CHARINDEX('/', @ADateStr, @SlashPos1 + 1)
if @SlashPos2 = 0 return null
set @FY = Cast(SUBSTRING (@ADateStr, 1 , @SlashPos1 - 1 ) as int)
set @FM = Cast(SUBSTRING (@ADateStr, @SlashPos1 + 1, @SlashPos2 - @SlashPos1 - 1) as int)
set @FD = Cast(SUBSTRING (@ADateStr, @SlashPos2 + 1, LEN(@ADateStr) - @SlashPos2) as int)
return
case @ADatePart
when 'Y' then @FY
when 'M' then @FM
when 'D' then @FD
end
END
GO
CREATE FUNCTION fDateDiff(@FDate varchar(10), @LDate varchar(10)) RETURNS int
AS
BEGIN
declare @FY int, @FM int, @FD int, @LY int, @LM int, @LD int,
@FirstM int, @FirstD int, @LastM int, @LastD int,
@YDiff int, @LDiff int, @FDiff int
set @FY = dbo.fn_ShamsiDateStrPart(@FDate, 'Y')
set @FM = dbo.fn_ShamsiDateStrPart(@FDate, 'M')
set @FD = dbo.fn_ShamsiDateStrPart(@FDate, 'D')
set @LastM = 12
set @LastD = 30
set @LDiff = ((@LastM - @FM) * 30) + (@LastD - @FD)
set @LY = dbo.fn_ShamsiDateStrPart(@LDate, 'Y')
set @LM = dbo.fn_ShamsiDateStrPart(@LDate, 'M')
set @LD = dbo.fn_ShamsiDateStrPart(@LDate, 'D')
set @FirstM = 1
set @FirstD = 1
set @FDiff = ((@LM - @FirstM) * 30) + (@LD - @FirstD)+1
set @YDiff = (@LY - (@FY + 1)) * 360;
return @LDiff + @FDiff + @YDiff
END

با فرض اينكه جدول شما همچين ستونهايي داره (البته معلوم نيست موجودي مال كيه!)
mojoodi مبلغي كه مشتري پرداخت كرده
tarikh تاريخ دريافت
خروجي زير رو ميخواهيم بگيريم:


mojoodi----tarikh----sood
-------------------------------
100000----1389/03/29----3000
50000-----1389/01/01----5000



create proc SoodProcedure @tarikhRooz char(10) as
begin
select
mojoodi,
tarikh,
mojoodi +( fDateDiff(@tarikhRooz , tarikh) * mojoodi / 36500)
[sood]
from table1
end

فك كنم بانك اكسس توابع و روالها رو پشتيباني نميكنه و بايد به sql سوئيچ كنيد يا روش دوم رو پيش بگيريد
براي اجراي اين روال هم بايد توي vb اونو exec كنيد و در يك ديتاست بريزيد و...
----------------------
براي روش دوم هم اين select رو بگيريد



select
mojoodi,
tarikh,
0[sood]
from table1

و با يك حلقه در vb جدول حاصله رو تغيير بده
مثلا:



dim now as string
now="1389/07/29"
for i=0 to data1.recordset.count
data1.recordset.fields[2].value=data1.recordset.fields[1].value+(DateDiff(now,tarikh) * data1.recordset.fields[0].value / 36500)
next i

البته اين شبه كد بود!