View Full Version : مشکل با متد execute
MNosouhi
یک شنبه 26 آذر 1385, 12:06 عصر
برای اینکه رکورد جدیدی وارد جدول کنم از دستورات sql استفاده کرده ام ، حالا نیاز دارم که بعد از insert شماره فیلد کلیدم که از نوع autoinc است را به دست آورم ، کد زیر را نوشته ام :
ClientDataSet2.Close;
ClientDataSet2.CommandText:='insert into books (bname) values (''ee'') SELECT @@IDENTITY as lastid FROM books';
ClientDataSet2.Execute;
دستور بالا بدون مشکل اجرا می شود ، اما نمی دونم حالا چطوری این مقداری رو که بر میگردونه رو بگیرم ، یعنی میخام مقداری که به عنوان Identity (یا همون شماره رکورد) بر میگردونه رو داخل یه متغیر قرار بدم.
از sql2000 هم استفاده می کنم.
mzjahromi
دوشنبه 27 آذر 1385, 07:36 صبح
اینو ببین (http://barnamenevis.org/forum/showpost.php?p=102604&postcount=5)
و این یکی (http://barnamenevis.org/forum/showpost.php?p=138341&postcount=6)
فکر کنم دقیقا مشخص باشه چیکار باید کرد. میتونی بدون هیچ مشکلی دستورات رو جدا جدا ارسال کنی
حرفه ای
دوشنبه 27 آذر 1385, 08:28 صبح
می تونی با ارسال مجدد یک دستور SQL شماره آخرین رکورد را پیدا کنی
به عنوان مثال
SELECT MAX (Field1) FROM Table1
MNosouhi
دوشنبه 27 آذر 1385, 12:28 عصر
مشکلی دستورات رو جدا جدا ارسال کنی
ممنون . همینه
می تونی با ارسال مجدد یک دستور SQL شماره آخرین رکورد را پیدا کنی
به عنوان مثال
SELECT MAX (Field1) FROM Table1
اگر چند کاربر همزمان رکوردی را وارد کنند ، رئش شما درست جواب نمیده.
ghabil
دوشنبه 27 آذر 1385, 13:49 عصر
من نمیفهمم چرا دستورات رو جدا جدا ارسال کنه ؟!! مقدار Identity در قالب یک پارامتر همینطوری برمیگرده اونم با یک بار اتصال به دیتابیس. این مقدار رو هم از توی پارامترهای دیتاست CleintDataSet.Parameters.ParamByName().Value میتونید بخونید.
ضمنا یادت باشه اگر در دیتابیس تریگر داری حتما از تابع IDENT_CURRENT بجای @@Identityاستفاده کن.
.
MNosouhi
دوشنبه 27 آذر 1385, 14:21 عصر
مقدار رو هم از توی پارامترهای دیتاست CleintDataSet.Parameters.ParamByName().Value میتونید بخونید.
ممنون از جوابتون ، اما من نتونستم این کار بکنم ، چون مقداری رو بر نمی گردونه.
اصلا مشکل همین بود که دستور اجرا میشد ، اما جوابش قابل دستیابی نبود.
ghabil
دوشنبه 27 آذر 1385, 16:34 عصر
آهان الا دیدم چی کم گذاشتی:
'insert into books (bname) values (''ee'') SELECT :RetID = @@IDENTITY FROM book
البته قبلا هم گفتم اینطوری پارامتر ساختن بسیار کند هست بهتره از پارامترهای ؟ استفاده بشه.
بعد
CleintDataSet.Parameters.ParamByName('RetID').Valu e
MNosouhi
دوشنبه 27 آذر 1385, 17:50 عصر
من این رو نوشتم ، a پارامتری هست که تعریف کرده ام :
ClientDataSet2.Close;
ClientDataSet2.CommandText:='insert into books (bname) values (''ee'') SELECT :a = @@IDENTITY FROM book';
ClientDataSet2.Execute;
Caption:=ClientDataSet2.Params.ParamValues['a']
اما بسته به اینکه paramType رو چی وارد کرده باشم یا هیچی بر نمی گردونه یا صفر بر می گردونه.
البته قبلا هم گفتم اینطوری پارامتر ساختن بسیار کند هست بهتره از پارامترهای ؟ استفاده بشه.
میشه بیشتر توضیح بدید.
Number1
دوشنبه 27 آذر 1385, 18:41 عصر
اصلا بگید که این کار رو برای چه هدفی میخاهید انجام بدید
چرا باید شماره ی فیلد کلید رو بدست بیارید
شاید راه حل های بهتری وجود داشته باشند تا سیستم را دولوپ کنید
شما دقیقا میخاهید چکار کنید
MNosouhi
سه شنبه 28 آذر 1385, 11:00 صبح
البته قبلا هم گفتم اینطوری پارامتر ساختن بسیار کند هست بهتره از پارامترهای ؟ استفاده بشه.
آقای کوشا منتظرم.
ghabil
سه شنبه 28 آذر 1385, 11:55 صبح
مثال :
CommandText := 'insert into table(field) values(?) select ? = @@IDENTITY
CDS.Params.CreateParam(ftString, '', ptInput).Value = 'test';
CDS.Params.CreateParam(ftInteger, '', pdOutPut);
CDS.Execute;
Id:= Params[1].Value
این روش بسیار سریعتر هست نسبت به روشهایی که خود پارسر پارامترهارو پیدا میکنه.
حرفه ای
سه شنبه 28 آذر 1385, 15:32 عصر
بچه ها اگه Multitier کار می کنید می تونید شما آخرین رکورد رو به صورت یک تابع تحت سرور بر روی سرور نگه داشته و مدیریت کنید نه SQL Server یا Oracle شما شلوغ میشه و نه سرعت شما کاهش پیدا می کنه راه حلی سریع اما بسیار کارآمد
امتحان کنید مسلماً ضرر نداره
اَرژنگ
سه شنبه 28 آذر 1385, 16:03 عصر
بچه ها اگه Multitier کار می کنید می تونید شما آخرین رکورد رو به صورت یک تابع تحت سرور بر روی سرور نگه داشته و مدیریت کنید نه SQL Server یا Oracle شما شلوغ میشه و نه سرعت شما کاهش پیدا می کنه راه حلی سریع اما بسیار کارآمد
امتحان کنید مسلماً ضرر نداره
با عرضه پوزش، ولی من جوابتان را درک نکردم.
فرض کنید ۲ کاربر داریم ، A و B:
شماره آخرین رکورد در سرور X
A یک تکورد اینسرت میکند
شماره آخرین رکورد در سرور 1+X
B یک رکورد اینسرت میکند
شماره آخرین رکورد در سرور 2+X
حالا چگونه شماره رکورد A را میشه برگرداند؟
حالا همین سناریو را برایه هزاران کاربر مجسم کنید (در کارهایه بانکی ده ها هزاران رکورد باهم اینسرت میشن )، و امکان اینکه صف کردن اینکار قابل قبول نیست، چونه اگر هر اینسرت در نیم ثانیه انجام بشه، ۱۰۰ مین کاربر باید ۵۰ ثانیه منتظر بماند.
ghabil
سه شنبه 28 آذر 1385, 17:23 عصر
بچه ها اگه Multitier کار می کنید می تونید شما آخرین رکورد رو به صورت یک تابع تحت سرور بر روی سرور نگه داشته و مدیریت کنید نه SQL Server یا Oracle شما شلوغ میشه و نه سرعت شما کاهش پیدا می کنه راه حلی سریع اما بسیار کارآمد
امتحان کنید مسلماً ضرر نداره
جدا از ایراداتی که به اون چیزی که میخواستی بگی و فکر میکنم همونم اشتباه گفتی وارده :
تو سرور از کجا بیاریمش به هر حال باید از دیتابیس بگیریم دیگه نه ؟!
این شلوغ نشدن دیتابیس و کم نشدن سرعت رو هم بیشتر توضیح بده بیزحمت.
یکی دیگه از دوستان هم فکر کنم گفته بود دولوپه یا همچین چیزی اونم میشه یک توضیح بدن یاد بگیریم.
اَرژنگ
سه شنبه 28 آذر 1385, 18:26 عصر
جدا از ایراداتی که به اون چیزی که میخواستی بگی و فکر میکنم همونم اشتباه گفتی وارده :
تو سرور از کجا بیاریمش به هر حال باید از دیتابیس بگیریم دیگه نه ؟!
نه ، اگر تمامه عملیات به داتابیس باید از میدل تیر که بر رویه سرور هست انجام میشه ، میشه که در یک متغییر ترد سیف نگهداری بشن.
ghabil
چهارشنبه 29 آذر 1385, 00:13 صبح
نه اینطور نیست: مثلا روی سرور Backup برگردونده بشه یا اینکه مثلا یک رکورد رو کاربر توسط Interprise Manager مستقیما وارد کنه ، یا به هر دلیل دیگه (مثلا اجرای یک StordeProcedure یا Trigger) تغییراتی در دیتا ایجاد بشه که در سطح سرور نبوده ....
مقدار فیلد Identity همیشه باید از دیتابیس خونده بشه این یک اصل هست. روش خوندنش هم همون Select زدن بعد از ترنس اکشن هست.
اَرژنگ
چهارشنبه 29 آذر 1385, 03:43 صبح
نه اینطور نیست: مثلا روی سرور Backup برگردونده بشه یا اینکه مثلا یک رکورد رو کاربر توسط Interprise Manager مستقیما وارد کنه ، یا به هر دلیل دیگه (مثلا اجرای یک StordeProcedure یا Trigger) تغییراتی در دیتا ایجاد بشه که در سطح سرور نبوده ....
من گفتم:
"نه ، اگر تمامه عملیات به داتابیس باید از میدل تیر که بر رویه سرور هست انجام میشه ، میشه که در یک متغییر ترد سیف نگهداری بشن."
۱)اگر تمامه عملیات به داتابیس باید از میدل تیر که بر رویه سرور هست انجام میشه ،در آن حالت هیچ کاربری نمیتونه مستقیماٰ رکورد به داتابیس وارد کنه.
۲)برگردانده بکاپ ، دوباره این نقض همان چیزی که گفتم، یعنی تمامه عملیات بر داتبیس از رویه یک میدل تیر انجام بشه٫
فیلده آیدنتیدتی همیشه آتو اینکرمنت نیست ، و استفاده از گوئید اصلاْ احتیاجی به خواندن آیدنتیتی نمیگذاره، چونکه قبل از اینسرت میدل تیر میتونه آیدنتیت را مشخص کنه و اینسرت کنه.
۳) در طراحی ۳ لایه ، لایه UI در مورد داتابیس کاملاْ بیخبره و به جز لایه Business Logic Layer هیچ احتیاجی به دانستن آیدنیتتی در داتابیس نداره
۴)در n-tier architecture تمامه مسائل Transaction از لایههایه بالاتر از Logical Tier مخفی هستند.
۵) در طراحیه ۲ لایه اگر چندین کاربر داریم اون اصل صدق میکنه:
مقدار فیلد Identity همیشه باید از دیتابیس خونده بشه این یک اصل هست. روش خوندنش هم همون Select زدن بعد از ترنس اکشن هست.
mzjahromi
چهارشنبه 29 آذر 1385, 07:03 صبح
یه چیز دیگه که در رد نگهداری متغیر روی سرور میشه گفت اینه که همیشه سرور یکی نیست. ممکنه دو نسخه از سرور روی دو کامپیوتر جداگانه اجرا کنه(حتی روی یک سیستم هم تضمینی برای اجرا شدن تنها یک نسخه از سرور نیست)
ghabil
چهارشنبه 29 آذر 1385, 09:44 صبح
من گفتم:
"نه ، اگر تمامه عملیات به داتابیس باید از میدل تیر که بر رویه سرور هست انجام میشه ، میشه که در یک متغییر ترد سیف نگهداری بشن."
۱)اگر تمامه عملیات به داتابیس باید از میدل تیر که بر رویه سرور هست انجام میشه ،در آن حالت هیچ کاربری نمیتونه مستقیماٰ رکورد به داتابیس وارد کنه.
۲)برگردانده بکاپ ، دوباره این نقض همان چیزی که گفتم، یعنی تمامه عملیات بر داتبیس از رویه یک میدل تیر انجام بشه٫
فیلده آیدنتیدتی همیشه آتو اینکرمنت نیست ، و استفاده از گوئید اصلاْ احتیاجی به خواندن آیدنتیتی نمیگذاره، چونکه قبل از اینسرت میدل تیر میتونه آیدنتیت را مشخص کنه و اینسرت کنه.
۳) در طراحی ۳ لایه ، لایه UI در مورد داتابیس کاملاْ بیخبره و به جز لایه Business Logic Layer هیچ احتیاجی به دانستن آیدنیتتی در داتابیس نداره
۴)در n-tier architecture تمامه مسائل Transaction از لایههایه بالاتر از Logical Tier مخفی هستند.
۵) در طراحیه ۲ لایه اگر چندین کاربر داریم اون اصل صدق میکنه:
دوست عزیز توی برنامه نویسی حرفه ای حساب کردن روی اگر ، یعنی پذیرفتن دردسر و الا اصلا Exception Handeling بی معنیه چون اگر کاربر درست از سیستم استفاده کنه که خطایی اتفاق نمیفته و تمام بحثهای Data Consistency هم در دیتابیسهای برای حذف همین اگرها هستند.
اما از این بحث گذشته توی روشی که شما میگید اگر سرور Down بشه تکلیف متغییر گلبال شما چی میشه ؟!
اَرژنگ
جمعه 01 دی 1385, 14:06 عصر
دوست عزیز توی برنامه نویسی حرفه ای حساب کردن روی اگر ، یعنی پذیرفتن دردسر و الا اصلا Exception Handeling بی معنیه چون اگر کاربر درست از سیستم استفاده کنه که خطایی اتفاق نمیفته و تمام بحثهای Data Consistency هم در دیتابیسهای برای حذف همین اگرها هستند.
اما از این بحث گذشته توی روشی که شما میگید اگر سرور Down بشه تکلیف متغییر گلبال شما چی میشه ؟!
دوست عزیز،
در برنامه نویسی حرفهای، یک میدل تیر وجود داره که همه باید از ایپیآی آن استفاده کنند.
در جاهایه بزرگ، مانند بانکها و پست، همینطوری نمیزارند که هر برنامه نویسی با داتابیس کار کند.
در سطح بالا داشتن یک میدل تیر حداقله.
در ضمن اگری که من گفتم در مورد داشتن میدل تیر بود و نه اینکه از برنامهنویسها درخواست کنند که با داتابیس ارتباط برقرار نکنند.
اگر به سیستمهایه ORM نگاه بندازید میبینید که برنامهنویس هیچ احتیاجی برایه ارتباط به داتابیس نداره.
در ضمن خودم برنامههایه سه لایه نوشتم که مقدار کلیدی را از داتابیس نمیگیرند (روش استفاده از گوئید برایه کلید).
۱ ساله پیش من هم دقیقاً نظر شما را داشتم.
در ضمن، بنا بر قابل دسترسی نبودن سرور، همانطوری میشه پرسید که اگر داتابیس قابل دسترسی نباشه چی میشه؟
عفت بزرگه
جمعه 01 دی 1385, 14:17 عصر
دوستان برنامه نویسی چند لایه به شما کمک میکنه همه چیز مدیریت کنید . و تمام تحرکها برای منبع داده رو به کلاسهای میانی واگذار می کنید . اما لازمه آن استفاده از oop و نوشتن sp است . با این دو شما میتوانید کاری کنید که دیگه لازم نباشه حتی برنامه نویس سطحهای بعد حتی بدونه توی دیتا بیس چه جدولها و 0000 هست عیب یابی بهتر میشه . تغییرات در کدها و حتی دیتا بیس فقط دیگه یک کارن نه یک فاجعه
ghabil
جمعه 01 دی 1385, 14:33 عصر
باشه سعی میکنم یکمی بیشتر توضیح بدم ولی تو هم دقت کن بی زحمت :
قرار هست شما یک کد جدید غیر تکراری از اطلاعاتت داشته باشی ، شکی در این که برای بدست آوردن این اطلاعات باید دیتاهای قبلی موجود در دیتابیس مورد بررسی قرار بگیرند و بعد با توجه به اونها این کد ساخته بشه نداریم انشاا...
حالا دوتا کار میتونیم بکنیم از دیتابیس بخواهیم که زمان ثبت اطلاعات و در حین ترنس اکشن خودش بره این کد رو با توجه به اطلاعات بدست بیاره که با توجه به Atomic از ACID مطمئن هم هستیم که این کد در هیچ شرایطی به شخص دیگری اختصاص نخواهد یافت (بدون نیاز به لاک کردن یا هر ترفند دیگه ای) ضمنا دیتابیس بعد از این که این کد رو بدست آورد مقدار اون رو برای ما به لایه میانی برمیگردونه . پس میبینی که اون چیزهایی که در مورد دسترسی به دیتابیس و این حرفها گقتی اصلا در این بحث محلی از اعراب ندارند.
اما چیزی که شما میگید اینه که ما اطلاعات لازم برای بدست آوردن کد جدید رو از دیتابیس بخونیم بیاریم به لایه میانی بعد اونها رو پردازش کنیم بعد مقدار پردازش رو به دیتابیس برگردونیم و ثبت کنیم : هم اتمیک نیست ، هم نیتیو نیست ، هم لایه میانی و دیتابیس روی یک کامپیوتر نباشند روی شبکه بار میزاره(که خیلی برات مهمه) ، اما اتمیک نبودنش بسیار حیاتیتر از بقیه ماجراست .
در مورد ای پی آی هم که گقتی متاسفانه به این موضوع ارتباطی نداره.
در مورد CRM هم متاسفانه باید خدمتت عرض کنم که CRM, MIS, HIRS و ... سیستمهای مدیریتی هستند که فارق از بحث آیتی هم معنا دارند و هیچ ربطی به اینکه دیتابیسشون یا مطنق نرم افزار مربوطشون چطور طراحی میشه ندارند و میشه 2 لایه 3 لایه یا چند لایه طراحی بشند با هر روش و متدی.
امیدوارم توضیحاتم کافی ، فارق از خلط مبحث و مغلطه بوده باشه.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.