تفاوت تبدیل ضمنی و صریح داده ها در SqlParameter

سلام وقت همگی به خیر
فرض کنید پروسیجر زیر رو داریم :
PHP:
CREATE PROCEDURE procName
    @ID int,
    @Name nvarchar(50),
    @Image varbinary(max),
    @Admin bit
AS
BEGIN
    .
    .
    .
END
GO
حالا با هر دو روش زیر میشه داده ها رو به این پروسیجر پاس داد.
روش اول :
PHP:
.
.
.
SqlParameter idParam = new SqlParameter("@ID", id);
SqlParameter nameParam = new SqlParameter("@Name", name);
SqlParameter identificationCardParam = new SqlParameter("@Image", image);
SqlParameter adminParam = new SqlParameter("@Admin", admin);
.
.
.
روش دوم :
PHP:
.
.
.
SqlParameter idParam = new SqlParameter("@ID", SqlDbType.Int);
idParam.Value = id;
SqlParameter nameParam = new SqlParameter("@Name", SqlDbType.NVarChar);
nameParam.Value = name;
SqlParameter imageParam = new SqlParameter("@Image", SqlDbType.VarBinary);
imageParam.Value = image;
SqlParameter adminParam = new SqlParameter("@Admin", SqlDbType.Bit);
adminParam.Value = admin;
.
.
.
من حدس میزنم که در روش اول تبدیل داده ها به روش ضمنی صورت میگیره و در روش دوم به صورت صریح. حالا من میخوام بدونم تفاوت این دو روش در چیه ؟
مزیت های روش دوم نسبت به روش اول چیه ؟
آیا روش اول در هیچ حالتی به مشکل نمی خوره ؟ آیا حالتی وجود داره که روش اول پاسخگو نباشه ؟
اگر هیچ تفاوتی ندارن پس چرا چنین سازنده ای برای SqlParameter گذاشتن که تووش بشه نوع رو به صورت صریح مشخص کرد ؟
خیلی ممنونم
 

the_king

مدیرکل انجمن
سلام وقت همگی به خیر
فرض کنید پروسیجر زیر رو داریم :
PHP:
CREATE PROCEDURE procName
    @ID int,
    @Name nvarchar(50),
    @Image varbinary(max),
    @Admin bit
AS
BEGIN
    .
    .
    .
END
GO
حالا با هر دو روش زیر میشه داده ها رو به این پروسیجر پاس داد.
روش اول :
PHP:
.
.
.
SqlParameter idParam = new SqlParameter("@ID", id);
SqlParameter nameParam = new SqlParameter("@Name", name);
SqlParameter identificationCardParam = new SqlParameter("@Image", image);
SqlParameter adminParam = new SqlParameter("@Admin", admin);
.
.
.
روش دوم :
PHP:
.
.
.
SqlParameter idParam = new SqlParameter("@ID", SqlDbType.Int);
idParam.Value = id;
SqlParameter nameParam = new SqlParameter("@Name", SqlDbType.NVarChar);
nameParam.Value = name;
SqlParameter imageParam = new SqlParameter("@Image", SqlDbType.VarBinary);
imageParam.Value = image;
SqlParameter adminParam = new SqlParameter("@Admin", SqlDbType.Bit);
adminParam.Value = admin;
.
.
.
من حدس میزنم که در روش اول تبدیل داده ها به روش ضمنی صورت میگیره و در روش دوم به صورت صریح. حالا من میخوام بدونم تفاوت این دو روش در چیه ؟
مزیت های روش دوم نسبت به روش اول چیه ؟
آیا روش اول در هیچ حالتی به مشکل نمی خوره ؟ آیا حالتی وجود داره که روش اول پاسخگو نباشه ؟
اگر هیچ تفاوتی ندارن پس چرا چنین سازنده ای برای SqlParameter گذاشتن که تووش بشه نوع رو به صورت صریح مشخص کرد ؟
خیلی ممنونم

تفاوت شون که کاملا مشخصه، در پارامتر دوم (روش اول) مقدار الزاما با متغیر نیست، (new SqlParameter("@ID", 12 بر اساس مقدار 12 باید نوع داده رو مشخص کنه که Int رو انتخاب می کنه.
همانطور که 12 می تونه به انواع داده مختلفی تعلق داشته باشه این Int هم الزاما نوع داده مطلوب نیست. در ضمن حتی اگر با یک متغیر نوع داده رو قبلا مشخص کرده باشید، انواع مختلف
داده ای مثل Decimal و Money و SmallMoney در پایگاه داده وجود دارند که در #C همه شون صرفا یک معادل decimal دارند. طبیعی است که اگر صریحا نوع داده را مثل روش دوم مشخص نکنید
ممکنه نوع داده مطلوب تان بکار برده نشه، اما اینکه انتخاب نوع داده صحیح چقدر در عملکرد موثره به کاربرد اون پارامتر بستگی داره، در دستورات SQL که قالب متنی دارند و پارامتری که بکار می برید
به مقدار رشته ای تبدیل می شه، معمولا مقایسه مقدار یک فیلد با یک پارامتر تاثیر مخرب نداره و اتفاق ناگواری نمی افته. مثلا شرط id=12 بررسی میشه، چه اهمیتی داره که در اصل اون 12 یک tinyint باشه یا int
اگر برانون راحت تره ئه می توانید از روش اول استفاده کنید، فقط در نظر بگیرید که نوع داده انتخاب شده الزاما اونی نیست که باید باشه.
 
تفاوت شون که کاملا مشخصه، در پارامتر دوم (روش اول) مقدار الزاما با متغیر نیست، (new SqlParameter("@ID", 12 بر اساس مقدار 12 باید نوع داده رو مشخص...
یعنی شما میفرمایید که کامپایلر بر اساس خود مقدار Object که پاس داده میشه، نوع داده رو تشخیص میده درسته ؟
خب حالا یه سوال، وقتی کامپایلر نوع داده رو تشخیص میده و اون رو به پروسیجر پاس میده، خب اون Object باید در متغیر متناظرش در پروسیجر قرار بگیره دیگه، درسته ؟
حالا وقتی نوع متغیر در پروسیجر مشخص شده، Object پاس داده شده مجبور نمیشه با یه تبدیل ضمنی به نوع داده ای متغیر متناظرش در پروسیجر تبدیل بشه تا بتونه در اون قرار بگیره ؟ یعنی مثلا متغیر Image هر نوعی براش توسط کامپایلر مشخص شده باشه، در نهایت وقتی میخواد توو متغیر متناظرش در پروسیجر قرار بگیره، مجبور نیست به نوع varbinary تبدیل بشه تا بتونه در اون متغیر قرار بگیره ؟ در این صورت مهم نیست که ما در سازنده SqlParameter نوعی رو برای Object مشخص می کنیم یا نه، چون در هر صورت اون Object تبدیل به نوع داده ای متغیر متناظرش در پروسیجر میشه درسته ؟
خیلی ممنونم
 
آخرین ویرایش:

the_king

مدیرکل انجمن
یعنی شما میفرمایید که کامپایلر بر اساس خود مقدار Object که پاس داده میشه، نوع داده رو تشخیص میده درسته ؟
خب حالا یه سوال، وقتی کامپایلر نوع داده رو تشخیص میده و اون رو به پروسیجر پاس میده، خب اون Object باید در متغیر متناظرش در پروسیجر قرار بگیره دیگه، درسته ؟
حالا وقتی نوع متغیر در پروسیجر مشخص شده، Object پاس داده شده مجبور نمیشه با یه تبدیل ضمنی به نوع داده ای متغیر متناظرش در پروسیجر تبدیل بشه تا بتونه در اون قرار بگیره ؟ یعنی مثلا متغیر Image هر نوعی براش توسط کامپایلر مشخص شده باشه، در نهایت وقتی میخواد توو متغیر متناظرش در پروسیجر قرار بگیره، مجبور نیست به نوع varbinary تبدیل بشه تا بتونه در اون متغیر قرار بگیره ؟ در این صورت مهم نیست که ما در سازنده SqlParameter نوعی رو برای Object مشخص می کنیم یا نه، چون در هر صورت اون Object تبدیل به نوع داده ای متغیر متناظرش در پروسیجر میشه درسته ؟
خیلی ممنونم

مساله مربوط به همون پاس دادنه، SQL Server که #C رو نمی فهمه که همینطور مستقیم مقدار از داخل SqlParameter بره تو Procedure.
شما در کد #C تون دارید غیر مستقیم کد SQL می نویسید، هر مقداری که می نویسید نهایتا باید به دستورات SQL تبدیل بشه.
کامپایلر باید دستورات شما رو به زبان SQL تبدیل کنه که قالب متنی داره. مقدار اون پارامتر در حین پاس دادن به SQL Server به معادل متنی اش تبدیل میشه که دستوری مثل EXEC بتونه ازش استفاده کنه.
اینکه پارامتر رو در Procedure از چه نوعی تعریف کرده اید برای اجرا شدن دستورات SQL مهمه اما تبدیل مقدار SqlParameter به معادل متنی اش مستقل ئه و کاری به تعریف Procedure و پارامتر هاش نداره.
معمولا مشکلی پیش نمیاد چون معادل متنی اغلب انواع داده ای شبیه هم هستند.
 

جدیدترین ارسال ها

بالا