PDA

View Full Version : چگونه از یک حلقه تودرتو استفاده کنیم؟



لوسیمی
دوشنبه 16 بهمن 1385, 15:25 عصر
سلام
چگونه از یک حلقه تودرتو استفاده کنیم؟
به طور مثال حلقه بیرونی سطورجدول را خوانده و حلقه درونی از سطر بعدی که در حلقه بیرونی fetch شده شروع می کند.اما حلقه زیر مانند یک حلقه کار میکند!

fetch next from cur_Test
into @reg,@name,@entity_num,@borrow_date,@return_date,@ prolongation_num
while @@fetch_status = 0
begin
set @ef =0
set @num = @entity_num
set @N = @N + 1
fetch absolute @N from cur_Test
into @reg1,@name1,@entity_num1,@borrow_date1,@return_da te1,@prolongation_num1
while @@fetch_status = 0
begin
if @reg1 = @reg and @borrow_date1< @return_date and @borrow_date<@return_date1
set @num =@num - 1
if @num=0
set @ef=@ef+1
set @num = @entity_num
fetch absolute @N from cur_Test
into @reg1,@name1,@entity_num1,@borrow_date1,@return_da te1,@prolongation_num1
end
print @reg print @name print @entity_num print @borrow_date print @return_date print @prolongation_num print @ef
fetch next from cur_Test
into @reg,@name,@entity_num,@borrow_date,@return_date,@ prolongation_num
end

zerobit-ltd
دوشنبه 16 بهمن 1385, 16:57 عصر
فکر کنم اگر تو while دوم هم دستور set @N = @N + 1 رو قرار بدی، درست بشه.

لوسیمی
سه شنبه 17 بهمن 1385, 07:21 صبح
سلام
با تشکر
من این دستور را تو حلقه استفاده کردم اما فقط سطر اول را خوانده و چاپ می کند و تا پایان پیش نمی رود

zerobit-ltd
سه شنبه 17 بهمن 1385, 13:42 عصر
اگر دقیقا توضیح بدید که چی مد نظر شما هستش، بیشتر می تونیم کمک کنیم.

whitehat
سه شنبه 17 بهمن 1385, 14:11 عصر
لطفا نحوه تعریف کرسر را نیز بنویسید(آیا در کرسر شما بیش از یک سطر وجود دارد؟)

لوسیمی
سه شنبه 17 بهمن 1385, 20:39 عصر
سلام
بله در کرسر بیش از یک سطر وجود دارد ، می خواهم لیست کتابهایی را به دست آورم که زمانهایی وجود داشته که تمامی موجودی به امانت گرفته شده است (به عبارتی کاربری برای به امانت گرفتن کتابی به کتابخانه رجوع کند اماتمامی موجودی به امانت رفته باشد)و این لیست به ترتیب اتمام موجودی چاپ شود .
دراین کرسر حلقه درونی به ازای هر سطرکه از حلقه بیرونی fetch می شود تا پایان جدول یکی یکی سطرها را fetch کرده وبررسی میکند که هر کدام از کتابها چند بار در یک زمان به امانت رفته اند
entity_num :موجودی هر کتاب در کتابخانه و
borrow_date:تاریخ امانت و
return_date:تاریخ برگشت و
prolongation_num:شمار تمدید می باشد وکد کلی به صورت زیر می باشد




declare @reg nvarchar(200),@name nvarchar(200),@entity_num int
@, borrow_date datetime,@return_date datetime,@prolongation_num int,
@reg1 nvarchar(200),@name1 nvarchar(200),@entity_num1 int , borrow_date1 datetime,@return_date1 datetime,@prolongation_num1int , @N int,@ef int,@num int
set @N = 1
set @num=0
declare cur_Test cursor scroll
for select books.reg,Books.Name,books.entity_num,borrow.borro w_date,borrow.return_date,borrow.prolongation_num
from Books inner join Borrow
on Books.Reg = Borrow.Reg
where Books.entity_Num > 1
open cur_Test
print 'reg name entity_num borrow_date return_date prolongation_num ef'
fetch next from cur_Test
into @reg,@name,@entity_num,@borrow_date,@return_date,@ prolongation_num
while @@fetch_status = 0
begin
set @ef =0
set @num = @entity_num
set @N = @N + 1
fetch absolute @N from cur_Test
into @reg1,@name1,@entity_num1,@borrow_date1,@return_da te1,@prolongation_num1
while @@fetch_status = 0
begin
if @reg1 = @reg and @borrow_date1< @return_date and @borrow_date<@return_date1
set @num =@num - 1
if @num=0
set @ef=@ef+1
set @num = @entity_num
set @N = @N + 1
fetch absolute @N from cur_Test
into @reg1,@name1,@entity_num1,@borrow_date1,@return_da te1,@prolongation_num1
end
print @reg print @name print @entity_num print @borrow_date print @return_date print @prolongation_num print @ef
fetch next from cur_Test
into @reg,@name,@entity_num,@borrow_date,@return_date,@ prolongation_num
end
close cur_Test
deallocate cur_Test
go

zerobit-ltd
سه شنبه 17 بهمن 1385, 23:23 عصر
حلقه اول فقط یکبار اجرا می شه. چون حلقه دوم تا آخر cursor حرکت می کنه و وقتی که fetch_staus تو حلقه دوم نا مساوی صفر می شه، طبیعتا تو حلقه اول هم باید fetch_status نا مساوی صفر باشه. برای همینه که همیشه سطر اول رو می خونه.
در ضمن مگه شما توی cursor رکوردهارو دونه دونه جلو نمی رید؟ اگر این طوره پس چرا از absolute استفاده می کنید؟ تو کدی که شما نوشتید، با هر بار اجرای حلقه دوم، چند رکورد به جلو fetch می شه. مثلا تو اولین بار اجرای حلقه دوم، N@ برابر 2 هستش. پس دوتا رکورد به جلو fetch می کنیم. تو دومین اجرای حلقه دوم، N@ برابر با 3 می شه. حالا از رکوردی که تو اجرای قبلی حلقه روش بودیم، 3 تا به جلو حرکت می کنیم. یعنی از روی دوتا رکورد پرش می کنیم. تو اجرای بعدی 4 تا و الی آخر.

لوسیمی
چهارشنبه 18 بهمن 1385, 07:43 صبح
با تشکر
پس چگونه یک حلقه تو درتو ایجاد کنم؟می توان برای حلقه دوم درون همین کرسر ، کرسر دیگری ایجاد نمود؟

zerobit-ltd
چهارشنبه 18 بهمن 1385, 12:39 عصر
شاید بهترین کار همین باشه.

لوسیمی
چهارشنبه 18 بهمن 1385, 20:31 عصر
با این کار تنها تمام جدول خوانده شده و چاپ می شود وشرطها چک نمی شود

zerobit-ltd
چهارشنبه 18 بهمن 1385, 21:04 عصر
if @reg1 = @reg and @borrow_date1< @return_date and @borrow_date<@return_date1
set @num =@num - 1
if @num=0
set @ef=@ef+1
set @num = @entity_num
set @N = @N + 1

این if هایی که نوشتید، نیازی به begin . . . end ندارن؟ یعنی بلاک کد نیستن؟
بعدشم متاسفانه من درست هنوز نفهمیدم صورت مساله چیه. تا اینجاش هم یه سری خطای منطقی رو تونستیم در بیاریم. اگر بتونید source کامل رو به همراه داده های فرضی در اختیار ما قرار بدید، بیشتر می تونیم کمک کنیم.

لوسیمی
پنج شنبه 19 بهمن 1385, 09:13 صبح
لطفاً به من کمک کنید

whitehat
پنج شنبه 19 بهمن 1385, 10:25 صبح
می خواهم لیست کتابهایی را به دست آورم که زمانهایی وجود داشته که تمامی موجودی به امانت گرفته شده است (به عبارتی کاربری برای به امانت گرفتن کتابی به کتابخانه رجوع کند اماتمامی موجودی به امانت رفته باشد)و این لیست به ترتیب اتمام موجودی چاپ شود .
منظور خود را در این مورد دقیق تر بیان کنید ، ضمن اینکه ساختار جداول خود را بنویسید .
برداشتی که من از عبارت بالا می کنم اینکه می خواهید "لیست کتابهایی را بدست آورید که در بازه زمانی موجودی در کتابخانه نداشته است" ، را بدست آورید.در این صورت میشه با یک Query ساده و یک حلقه آنرا بدست آورد

لوسیمی
یک شنبه 29 بهمن 1385, 12:35 عصر
بله دقیقاً می خواهم به همین صورت که شما گفتید search کنم ،چه طور با یک کوئری ساده این کار رو انجام بدم.

whitehat
یک شنبه 29 بهمن 1385, 20:57 عصر
با توجه به فیلد هایی که قبلا نوشتید و با فرض اینکه در صورت عدم وجود کتاب در کتابخانه تاریخ Return برابر Null می باشد .برای این کار کافیه لیست کتابهای پس آورده نشده را پیدا کرده و از موجودی کسر کنید.


SELECT Borrow.Reg,count(Borrow.Reg)-entity_num as BookCount
FROM
Barrow INNER JOIN BookS
ON Books.Reg = Borrow.Reg
WHERE (@Return_Date is NULL)
group by Borrow.Reg,entity_num

حال می توانید از Query بالا یک Select بگیرید که مقدار BookCount آنها صفر باشد. برای اینکه تا تاریخ خاصی را مشخص کنید به جای جدول Barrow یک SubQuery بنویسید که تا آن تاریخ را برگرداند .
موفق باشید