PDA

View Full Version : مشکل در پیاده سازیه حلقه while با کمک datareader



fereshte22
سه شنبه 18 اردیبهشت 1386, 14:11 عصر
سلام
من یک فیلد (شروع زمان اضافه شدن فیلد در دیتابیس) دارم .میخواهم در یکی از صفحاتم اختلاف این زمان با زمان کنونی محاسبه شود.و برای محاسبه این اختلاف یک فیلد در جدولم قرار دادهام.(مقدار اولیه اش را صفر قرار دادهام)حالا مشکل من در مقدار دهی به این فیلد است.من اختلاف ساعت را محاسبه میکنم ولی نمیدونم که چه طور این مقدار را اپدیت کنم.
البته با datareader جدول را میخونم و رکوردها را بازیابی میکنم ولی نمیدونم که چطوری حلقه را پیاده سازی کنم.یه چیزی شبیه کد زیر نوشتم ولی هرچه جای con.open , con.close را تغییر میدهم ساختار حلقه ام درست نمیشود.
کسی میتونه من را راهنمایی کند که مشکلم چیه؟
ایا راه بهتری سراغ دارید


con.Open()
strsql = "select *from sabadkharid "
cmd = New SqlCommand(strsql, con)
dr = cmd.ExecuteReader
Dim ss AsDate
dr.Read()


While dr.Read
ss = dr("startTime")
runLength = ss.Subtract(Now)
con.Close()
updatesql = "update sabadkharid set difrence='" & runLength.TotalHours & "'"
updatesql &= "where flag='" & 0 & "'"
cmdselect = New SqlCommand(updatesql, con)
con.Open()
cmdselect.ExecuteNonQuery()
con.Close()
con.Open()
EndWhile
dr.Close()
con.Close()

SalarSoft
چهارشنبه 19 اردیبهشت 1386, 06:37 صبح
نکته مهمی که باید در نظر داشته باشی اینه که تا کارت با SqlDataReader تموم نشده نباید connection رو ببندی



If (con.State <> ConnectionState.Open) Then con.Open()
Try
Dim strsql As String = "select * from sabadkharid "
cmd = New SqlCommand(strsql, con)
reader = cmd.ExecuteReader

While reader.Read
ss = reader("startTime")
runLength = ss.Subtract(Now)
updatesql = "update sabadkharid set difrence='" & runLength.TotalHours & "'"
updatesql &= "where flag='" & 0 & "'"
cmd.CommandText = updatesql
cmd.ExecuteNonQuery()
End While
Finally
If (reader IsNot Nothing) Then
reader.Close()
End If
con.Close()
End Try

fereshte22
چهارشنبه 19 اردیبهشت 1386, 08:58 صبح
من وقتی کد شما را اجرا میکنم روی این خط خطامیدهد


cmd.ExecuteNonQuery()

خطایش هم این است که هم اکنون یک datareader در ارتباط با این command وجود دارد که ابتدا باید بسته شود
datareader را کجا باید بست؟

__H2__
چهارشنبه 19 اردیبهشت 1386, 10:01 صبح
سلام
نمیدانم برای چه مدام Connection را میبندید و باز میکنید؟؟؟؟؟؟؟
اگر همچنان مایل به استفاده از آن درپیت و نا زیبا هستید حداقل از این استفاده کنید.


Using con As New System.Data.SqlClient.SqlConnection("")
Dim cmd As New System.Data.SqlClient.SqlCommand("select *from sabadkharid ", con)
con.Open()

Using dr As System.Data.SqlClient.SqlDataReader = cmd.ExecuteReader
Dim ss As Date
Dim runLength As TimeSpan

Do While dr.Read
ss = CDate(dr("startTime"))
runLength = ss.Subtract(Now)
cmd.CommandText = _
"update sabadkharid " & _
"set difrence='" & runLength.TotalHours & "' " & _
"where flag='0'"

cmd.ExecuteNonQuery()
Loop
End Using
End Using

fereshte22
چهارشنبه 19 اردیبهشت 1386, 11:40 صبح
دوست عزیز کد شما هم همون خطایی که برای کد SalarSoft می داد را میدهد.نمیدونم مشکلش چیه؟



اگر همچنان مایل به استفاده از آن درپیت و نا زیبا هستید حداقل از این استفاده کنید

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

__H2__
چهارشنبه 19 اردیبهشت 1386, 15:16 عصر
سلام
نمیگویم که کدهای من آسمانی هستند ولی با وجودی که تستشان نکرده ام ایراد در آنها بعید است!
یا Connectionstring ایراد دارد.
یا startTime مقدار null دارد.
و یا فیلد difrence نوع string نیست و عددی است (احتمال زیاد)
ویا فیلد flag از نوع String نیست و عددی است (احتمال زیاد)


دقیقاَ چه کار میخواهید بکنید؟ اختلاف زمانی همه تاریخ ها را با امروز به ساعت بدست آورید؟
اینکارها را با یک تک دستور SQL انجام میدهند (UPDATE) نه با یک حلقه خود ساخته!
شما هدفتان را مشخص کنید من هم انشا ا... تا فردا سری به توابع تاریخ SQL میزنم. که جواب صحیح و قطعی دهم.

fereshte22
چهارشنبه 19 اردیبهشت 1386, 17:01 عصر
سلام
من همه مواردی که شما فرموده بودید را چک کردم ولی مشکلم حل نشد

من میخواهم در فایل global خود کدی بنویسم که در جدول سبد خرید چک کند و رکوردهایی که مقدار فلگ انها برابر یک است و یا زمان اضافه شدن انها مربوط به یک ساعت پیش است را حذف کند(مقدار فلگ ابتدا صفر است ولی وقتی کاربر دکمه خرید نهایی را میزند یک میشود)
حالا ممکن است کاربر دکمه خرید را نزند و منصرف شود و یا dc شود. به همین دلیل من میخواهم که چک کنم و رکوردهایی که فلگ انها صفر است ولی زمان اضافه شدن انها مربوط به یک ساعت پیش است به طور خودکار حذف شود

__H2__
پنج شنبه 20 اردیبهشت 1386, 12:53 عصر
سلام
سبد خرید را در Session قرار دهید و بعد از خرید نهایی آن را به بانک منتقل کنید.
بدین ترتیب به صورت خودکار با قطع شدن کاربر سبد خریدش هم از بین میرود.

بحرحال برای برای تفریق دو تاریخ از هم و دریافت عدد به صورت تعداد دقایق باید از دستور SQL زیر استفاده کنید.


DATEDIFF(minute, FieldDateName, GETDATE())

fereshte22
شنبه 22 اردیبهشت 1386, 12:08 عصر
سلام
راستش من تا حالا از دستورات sql در برنامه ام استفاده نکرده ام و نمیدونم دقیقا این دستورات را به چه صورت به کار ببرم.در query editor ؟ چون من در query editor جدول خودم این دستور را نوشتم ولی روی FieldDateName که من به جاش نام فیلدم را گذاشتم خطا داد.
اگه راهنمایی کنید ممنون میشوم.
در ضمن من با sql2005 کار میکنم

__H2__
شنبه 22 اردیبهشت 1386, 13:40 عصر
سلام
چطور تا حالا از SQL استفاده نکرده اید؟!!!! خود شما در خطوط برنامه فوق از دستور UPDATE مربوط به زبان SQL استفاده کرده اید و دستور SQL را با یک Command اجرا کرده اید.!!!! پس نام این را چه میگذارد؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟


در ضمن به نظر مکیرسد شما میخواهید پس از انقضای وقت کاربر اطلاعات سبد خرید او را حذف کنید، پس برای چه آنها را UPDATE کرده اید؟؟؟؟؟


dbCom.CommandText = "DELETE [sabadkharid] WHERE (DATEDIFF(minute, [finalTime], GETDATE()) > 60)"
dbCom.ExecuteNonQuery()


مثلاً در دستور فوق فرض شده شما در جدول فیلدی به نام FinalTime دارید که حاوی آخرین تاریخ (=آخرین زمان) حضور و ارتباط کاربر با سایتتان است (یعنی هر وقت کاربر با سایت مراوده داشته شما مدام این فیلد را با مقدار زمان جاری پر کرده اید) در این صورت اجرای دستور SQL فوق موجب میشود کلیه اطلاعاتی که بیش از 60 دقیقه از آخرین اتصال کاربراش به سایت گذشته را پاک شوند و نیازی به هیچ حلقه ای ندارد.

البته همچنان فکر میکنم برای کارهای معمولی ذخیره سبد خرید به عنوان یک System.Data.DataTable در Session بهتر است.

همچنان سوالی داشتید هستیم! موفق باشید.

fereshte22
شنبه 22 اردیبهشت 1386, 15:02 عصر
سلاماز راهنمایتون ممنون هستم.دستتون درد نکند.در مورد سوالی که من در مورد دستورات sql پرسیده بودم ببینید مثلا همین تابع datediff اگر به همین صورت بنویسیمش و یا خروجیاش را مساویه یک متغییر قرار بدهیم بر روی minute و getdate خطا میگیرد که تعریف نشده است.یا مثلا دستوراتی که در قسمت sql همین سایت گفته میشود.من میبینم که دوستان توی برنامه هاشون از sp استفاده میکنند و یا خیلی از توابع هست که وقتی من اونهارا استفاده میکنم خطا میگیرد.من نمیدونستم این کد ها را در کجا مینوسند و فکر میکردم حتما باید به عنوان spباید بنویسیمشون .خلاصه ابهاماتی از این قبیل دارم.

__H2__
شنبه 22 اردیبهشت 1386, 15:29 عصر
سلام
زبان SQL کلاً برای خودش عالمی جدا دارد و باید جداگانه آنرا یاد بگیرید. نوشتن صحیح دستورات هم لازم است مثلا در همین VB اگر من بنویسم Sin(1)=5 بدون شک خطا میدهد چون Sin یک تابع است و نمیتوان آن را برابر با چیزی قرار داد. قواعد زبان SQL هم همینطور است و اگر درست به کار گرفته نشود بدون شک خطای منطقی ای را شامل میشود.
من خودم به عنوان مرجع همیشه از Help ای که همراه آن نصب میشود استفاده میکنم.
مثلاَ من برای اجرای Help آن از این طریق عمل میکنم (SQL Server 2005 Develop):
Start->All program->Microsoft SQL Server 2005->Documentation and Tutorials->SQL Server Books Online

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

برای اجرای دستورات SQL درون برنامه خودتان هم باید از شیث Command (فرمان)استفاده کنید. اصولاَ این شی مخصوص همین است.

شما باید دستورات SQL را به صورت String در آورده و تحویل مشخصه CommandText بدهید سپس این شی سه دستور نهایی برای اجرای دستورات SQL در اختیار شما قرار میدهد.

ExecuteNonQuery
برای اجرای دستورات SQL ای مناسب است که چیزی بر نمیگردانند، مثلاَ همان دستور DELETE من در پست قبلی که قرار نیست چیزی برگرداند. (البته این تابع تعداد کلی سطرهاییی را که تغییری کرده اند باز میگرداند، هر تغییری.)
DataAdapter ها از همین دستور برای ذخیره کردن محتویات DataSet ها در بانک واقعی استفاده میکنند.

ExecuteScalar
برای اجرای دستورات SQL ای مناسب است که یک مقدار واحد را برمیگردانند، مثلاً دستوری که تعداد اعضا (COUNT) را محاسبه و برمیگرداند.

ExecuteReader
برای اجرای دستورات SQL ای مناسب است که یک جدول را برمیگردانند (SELECT) و یک مکان نمای روبه جلو به ما میدهد که با آن میتوان کلیه سطرها و ستون ها را استخراج کرد.
DataAdapter ها از همین دستور برای پر کردن DataSet ها استفاده میکنند.


پیشنهاد میکنم اگر مطالعه نکرده اید، حتماً کتابی در مورد زبان پایگاه اطلاعات SQL مطالعه کنید.
امیدوارم ابهامتان رفع شده باشد.