PDA

View Full Version : مشکل با فارسی در کوئریهای اس کیو ال سرور (کوئریهای تنظیم شده در زمان اجرا)



عالیه.م
چهارشنبه 02 اردیبهشت 1394, 09:12 صبح
سلام.
من یه جدول در اس کیو ال سرور دارم و یه سری اطلاعات مربوط به تراکنشهای یک سیستم رو ذخیره میکنم و یک فیلد از نوع کاراکتر رو در این جدول در نظر گرفتم که مشخص میکنه که این تراکنش ورودیه، خروجیه، امانیه یا گزینه های دیگه. حالا میخوام در هر حالت مقدار فارسی مناسب رو برگردونم نه خود فیلد رو. با دستور زیر درست جواب میده

select KID,PName,case when WType='ib' then N'ورودی' else N'خروجی' end from InOutInfo where ID>1
اما مشکل اینه که من نمیخوام شرط دستورم ثابت باشه. یعنی شرط در هنگام اجرا توسط کاربر مشخص بشه.واسه همین اومدم یک استور پروسیجر گذاشتم و شرط رو به عنوان پارامتر ورودی گرفتم و کوئری رو هم با توجه به این روش توی یک متغیر ریختم تا آخر اجراش کنم.

declare @q nvarchar(100)
set @q='select KID,PName,case when WType=''ib'' then N''ورودی'' else N''خروجی'' end from InOutInfo'+@cond
exec(@q)


اما موقع اجرا برای من ؟؟؟؟ برمیگردونه در حالیکه من هم نوع متغیر رو یونیکد در نظر گرفتم و هم تو دستور از کاراکتر "ان" استفاده میکنم. جستجو کردم و جیزی نیافتم. کسی با این مشکل برنخورده تا حالا؟ :متفکر:

FastCode
چهارشنبه 02 اردیبهشت 1394, 09:57 صبح
راه حلش که خیلی سادست. ولی من واقعا درک نمیکنم نکته نوشتن SP اینجا چیه؟
اصلا چرا؟

عالیه.م
چهارشنبه 02 اردیبهشت 1394, 10:34 صبح
اصلا بدون sp. فرض کن با یک کوئری معمولی. اما شرطش قراره که از محیط برنامه نویسی با انتخاب کاربر تنظیم بشه

SabaSabouhi
چهارشنبه 02 اردیبهشت 1394, 12:43 عصر
سلام.
من یه جدول در اس کیو ال سرور دارم و یه سری اطلاعات مربوط به تراکنشهای یک سیستم رو ذخیره میکنم و یک فیلد از نوع کاراکتر رو در این جدول در نظر گرفتم که مشخص میکنه که این تراکنش ورودیه، خروجیه، امانیه یا گزینه های دیگه. حالا میخوام در هر حالت مقدار فارسی مناسب رو برگردونم نه خود فیلد رو. با دستور زیر درست جواب میده

select KID,PName,case when WType='ib' then N'ورودی' else N'خروجی' end from InOutInfo where ID>1
اما مشکل اینه که من نمیخوام شرط دستورم ثابت باشه. یعنی شرط در هنگام اجرا توسط کاربر مشخص بشه.واسه همین اومدم یک استور پروسیجر گذاشتم و شرط رو به عنوان پارامتر ورودی گرفتم و کوئری رو هم با توجه به این روش توی یک متغیر ریختم تا آخر اجراش کنم.

declare @q nvarchar(100)
set @q='select KID,PName,case when WType=''ib'' then N''ورودی'' else N''خروجی'' end from InOutInfo'+@cond
exec(@q)


اما موقع اجرا برای من ؟؟؟؟ برمیگردونه در حالیکه من هم نوع متغیر رو یونیکد در نظر گرفتم و هم تو دستور از کاراکتر "ان" استفاده میکنم. جستجو کردم و جیزی نیافتم. کسی با این مشکل برنخورده تا حالا؟ :متفکر:

سلام
بجای exec از EXEC sp_executesql استفاده کن.

صبا صبوحی

FastCode
چهارشنبه 02 اردیبهشت 1394, 13:02 عصر
هکرهایی که این کد رو میخونن نمیدونن از خوشحالی چطوری احساساتشون رو بیان کنند.
2EZ #SQLInjection#

عالیه.م
پنج شنبه 03 اردیبهشت 1394, 08:22 صبح
ممنون از پاسخت. اما نتیجه ای نگرفتم دوست عزیز :(

عالیه.م
پنج شنبه 03 اردیبهشت 1394, 08:29 صبح
هکرهایی که این کد رو میخونن نمیدونن از خوشحالی چطوری احساساتشون رو بیان کنند.
2EZ #SQLInjection#
دوست من. اینجا جاییه برای کمک به هم و نه تحقیر هم. اگر پاسخ من رو میتونی بدی ممنون میشم و اگر هم کد امنیتش پایینه باز هم ممنون میشم دلیلشو بگی تا اشکالم رو رفع کنم. صرف به چالش کشیدن کد بدون گفتن دلیل به من کمکی نمیکنی

FastCode
پنج شنبه 03 اردیبهشت 1394, 08:43 صبح
https://www.google.com/search?q=SQLInjection (https://www.google.de/search?q=SQLInjection)

عالیه.م
پنج شنبه 03 اردیبهشت 1394, 09:33 صبح
https://www.google.com/search?q=SQLInjection (https://www.google.de/search?q=SQLInjection)
ممنون. اما من دارم یک اپلیکیشن ویندوز مینویسم و کاری با وب ندارم. بنابراین از این بابت خیالم راحته. حالا شما روشی سراغ ندارید من بتونم به نتیجه ای که میخوام برسم؟

SabaSabouhi
جمعه 04 اردیبهشت 1394, 11:15 صبح
ممنون. اما من دارم یک اپلیکیشن ویندوز مینویسم و کاری با وب ندارم. بنابراین از این بابت خیالم راحته. حالا شما روشی سراغ ندارید من بتونم به نتیجه ای که میخوام برسم؟

سلام
من جواب رو به شما گفتم، نمی‌دونم اون رو امتحان کردی یا نه.
در ضمن گفته‌های دوستمون fastCode راجع به Sql Injection کاملاً درسته و ربطی به وب و ویندوز نداره، همه جا امکان‌پذیر هست.
شما می‌تونی تو خیلی از نرم‌افزارها که این مسائل رو رعایت نکردن بجای شناسه‌ی کاربر بنویسی --'Admin و بجای رمز هم بنویسی Saba.Sabouhi و بعد
با کمال تعجب خواهی دید که چقدر راحت می‌شه وارد نرم‌افزار شد، اون هم با اکانت Admin
تازه این ساده‌ترین کار هست، خیلی کارهای بد! می‌شه با این روش انجام داد. مثل حذف یا اضافه کردن رکورد به جدول‌های دیتابیس یا . . .
روش‌های استاندارد برای تفریح به وجود نیامدن. سعی کنیم چرخ رو دوباره اختراع نکنیم و از تجربه‌ی دیگران استفاده کنیم

صبا صبوحی

عالیه.م
یک شنبه 06 اردیبهشت 1394, 08:27 صبح
سلام
من جواب رو به شما گفتم، نمی‌دونم اون رو امتحان کردی یا نه.
در ضمن گفته‌های دوستمون fastCode راجع به Sql Injection کاملاً درسته و ربطی به وب و ویندوز نداره، همه جا امکان‌پذیر هست.
شما می‌تونی تو خیلی از نرم‌افزارها که این مسائل رو رعایت نکردن بجای شناسه‌ی کاربر بنویسی --'Admin و بجای رمز هم بنویسی Saba.Sabouhi و بعد
با کمال تعجب خواهی دید که چقدر راحت می‌شه وارد نرم‌افزار شد، اون هم با اکانت Admin
تازه این ساده‌ترین کار هست، خیلی کارهای بد! می‌شه با این روش انجام داد. مثل حذف یا اضافه کردن رکورد به جدول‌های دیتابیس یا . . .
روش‌های استاندارد برای تفریح به وجود نیامدن. سعی کنیم چرخ رو دوباره اختراع نکنیم و از تجربه‌ی دیگران استفاده کنیم

صبا صبوحی
بله امتحان کردم و جواب نگرفتم.

SabaSabouhi
یک شنبه 06 اردیبهشت 1394, 12:15 عصر
بله امتحان کردم و جواب نگرفتم.

سلام
حتماً درست استفاده نکردی، چون من بارها از این system procedure استفاده کردم و بسیار عالی کار می‌کنه.
این رو امتحان کن.


exec sp_sqlexec N'SELECT * FROM sys.tables'

یا



DECLARE @script AS NVARCHAR( 4000 ) = N'SELECT * FROM sys.tables'
exec sp_sqlexec @script



صبا صبوحی

عالیه.م
یک شنبه 06 اردیبهشت 1394, 12:23 عصر
سلام
حتماً درست استفاده نکردی، چون من بارها از این system procedure استفاده کردم و بسیار عالی کار می‌کنه.
این رو امتحان کن.


exec sp_sqlexec N'SELECT * FROM sys.tables'

یا



DECLARE @script AS NVARCHAR( 4000 ) = N'SELECT * FROM sys.tables'
exec sp_sqlexec @script



صبا صبوحی

مطابق کاری که شما گفتید تست کردم. باز هم ؟؟؟ برگردوند :(

declare @q as nvarchar(100)=N'select KID,PName,case when WType=''ib'' then N''ورودی'' else N''خروجی'' end from InOutInfo'
exec sp_sqlexec @q

SabaSabouhi
یک شنبه 06 اردیبهشت 1394, 14:04 عصر
مطابق کاری که شما گفتید تست کردم. باز هم ؟؟؟ برگردوند :(

declare @q as nvarchar(100)=N'select KID,PName,case when WType=''ib'' then N''ورودی'' else N''خروجی'' end from InOutInfo'
exec sp_sqlexec @q


سلام
عجیبه، چون وقتی ؟؟؟ بر می‌گردونه معنیش اینه که unicode نیست و nonunicode-language هم روی persian تنظیم نشده ( تو Control Panel~Regional Settings ) اما
اینجا رشته‌ها Unicode هستن. من متن شما رو یه کم ساده کردم، ( چون جدول شما رو نداشتم ) و درست جواب داد.


declare @q as nvarchar(60)=N'select case when 1=1 then N''ورودی'' else N''خروجی'' end '
exec sp_sqlexec @q




اگه این نتونست کمکی کنه، دیگه شرمنده‌ام. چیز دیگه‌ای به فکرم نمی‌رسه. این script شما نباید ؟؟؟ برگردونه.

صبا صبوحی

FastCode
یک شنبه 06 اردیبهشت 1394, 15:17 عصر
راه حلش اینه که یک متغیر بیرون دستور تعریف کنید و در select بهش مقدار بدید.
واقعا من فکر کردم یه راه جدید هست که من خبر ندارم.

ولی در کلا روشتون غلطه.
قبل از ۱۰ ثانیه من کل دیتابیس رو میارم جلو چشمتون.

عالیه.م
دوشنبه 07 اردیبهشت 1394, 10:21 صبح
سلام
عجیبه، چون وقتی ؟؟؟ بر می‌گردونه معنیش اینه که unicode نیست و nonunicode-language هم روی persian تنظیم نشده ( تو Control Panel~Regional Settings ) اما
اینجا رشته‌ها Unicode هستن. من متن شما رو یه کم ساده کردم، ( چون جدول شما رو نداشتم ) و درست جواب داد.


declare @q as nvarchar(60)=N'select case when 1=1 then N''ورودی'' else N''خروجی'' end '
exec sp_sqlexec @q




اگه این نتونست کمکی کنه، دیگه شرمنده‌ام. چیز دیگه‌ای به فکرم نمی‌رسه. این script شما نباید ؟؟؟ برگردونه.

صبا صبوحی

مرسی. یه چیزی فهمیدم. من یا اس کیو ال سرور اکسپرس کار میکنم و این کوئری اونجا ؟؟ برمیگردونه. اما تو نسخه غیر اکسپرس جواب درست میده. به نظر شما راهی هست که تو اکسپرس هم درست جواب بده؟

عالیه.م
دوشنبه 07 اردیبهشت 1394, 10:24 صبح
راه حلش اینه که یک متغیر بیرون دستور تعریف کنید و در select بهش مقدار بدید.
واقعا من فکر کردم یه راه جدید هست که من خبر ندارم.

ولی در کلا روشتون غلطه.
قبل از ۱۰ ثانیه من کل دیتابیس رو میارم جلو چشمتون.
از شما هم ممنون گرامی. الان متوجه شدم اشکال من در اس کیو ال اکسپرس وجود داره. خیلی علاقمندم که بدونم چطور این کار رو میکنید.
:چشمک:

FastCode
دوشنبه 07 اردیبهشت 1394, 21:05 عصر
اگر فقط با یک engine ایم اتفاق میافته به جز راهی که گفتم میتونید برید codepage ه global ه SQL رو بکنید مثلا persian_ci_as
خیلی خیلی سادش میشه این:
خروجی رو بدید:

' from InOutInfo;delete from InOutInfo --
اینطوری حتی کسی متوجه نمیشه چه خبره.