PDA

View Full Version : بهترین روش جستجوی عبارت فارسی در SQlServer



takavar_dez
پنج شنبه 23 تیر 1390, 23:00 عصر
با سلام

بهترین روش برای جستجوی یک کلمه فارسی در پایگاه داده چیه؟برای مثال اگه بخواهیم روی یکی از جداولمون با شرط اینکه ستون نام مساوی با کلمه "علی" و یا شامل اون باشه پرس و جو بزنیم آیا کد زیر درسته؟
البته این کد جواب نمیده و با وجود دیتای ارضا کننده شرط هیچ تاپلی برگشت داده نمیشه
لطفا توضیح بدید اشکال کار کجاست؟
با سپاس

Select *
From T_Test
Where (Fname = N'علی') or (Fname like N'%علی%')

takavar_dez
جمعه 24 تیر 1390, 13:22 عصر
این توضیح رو اضافه کنم که کدی که بالا گذاشتم برای کلمات انگلیسی هیچ مشکلی نداره اما من به جستجوی کلمات فارسی نیاز دارم!
چطور میشه مشکل کلمات فارسی در جستجو رو حل کرد؟!:متفکر:

یوسف زالی
جمعه 24 تیر 1390, 14:48 عصر
سلام.
مشکل شما احتمالا مربوط هست به Collation.
کلماتی که در جدول هست با کلمه ای که سرچ می کنید فرق داره.
خصوصا در ی و ک که عربی و فارسیش فرق داره.
می تونی کدی ران کنی که اطلاعات دیتابیس رو درست کنه و از اون به بعد موقع اینسرت حواست به دیتا باشه که در ی و ک فرم استانداردی داشته باشه.
تست کن. احتمالا می تونی کلمه حسن رو همین الان سرچ کنی. اگه تونستی و پیدا کرد حتما گیرت همینه.

takavar_dez
یک شنبه 26 تیر 1390, 15:00 عصر
سلام.
مشکل شما احتمالا مربوط هست به Collation.
کلماتی که در جدول هست با کلمه ای که سرچ می کنید فرق داره.
خصوصا در ی و ک که عربی و فارسیش فرق داره.
می تونی کدی ران کنی که اطلاعات دیتابیس رو درست کنه و از اون به بعد موقع اینسرت حواست به دیتا باشه که در ی و ک فرم استانداردی داشته باشه.
تست کن. احتمالا می تونی کلمه حسن رو همین الان سرچ کنی. اگه تونستی و پیدا کرد حتما گیرت همینه.
درسته مشکل همینه ممنونم
چه جور کدی رو میشه برای حل این مشکل ران کرد تا وقت اینسرت اطلاعات اونجور که بخوایم ذخیره بشه؟

یوسف زالی
یک شنبه 26 تیر 1390, 15:38 عصر
برای اینکه از این به بعد دچار این مشکل نشی ، باید قراردادی با خودت بگذاری:
کدوم ک و کدوم ی برای شما استاندارد محسوب می شه؟
برای مثال من اینجا فرض می کنم که استاندارد شما حروف فارسی هست و عربی ها باید به فارسی تبدیل بشن.
اونوقت موقع Insert اگر مثلا فیلد متنی شما نام باشد، به جای استفاده از Name باید بگذاریم
replace(Name, nchar(1603), nchar(1705)) -- jaye K arabi ro ba K farsi avaz mikonim

کد ک فارسی 1705 هست.
این کدها رو می تونی از دوراه بدست بیاری. برنامه CharMap ویندوز و خود SQL . مثلا این رو تست کن:

select UniCode('X') -- kode harfe morede nazar

Galawij
یک شنبه 26 تیر 1390, 20:39 عصر
و در ادامه ...
اگر قبلاً در بانک اطلاعاتیتون داده وارد کردید می تونید یک کرسر روی این دستور نوشته و در داخل یک روال فراخوانی کنید تا بانک اطلاعاتیتون به روز رسانی شود.
Exec(
'Update ['+@TableName+'] Set ['+@ColumnName+']=Replace(Replace(cast(['+@Columnname+']=As nvarchar(Max)),Nchar(1740),Nchar(1610)),Nchar(1705 ),Nchar(1603))'
)

takavar_dez
جمعه 31 تیر 1390, 12:45 عصر
و در ادامه ...
اگر قبلاً در بانک اطلاعاتیتون داده وارد کردید می تونید یک کرسر روی این دستور نوشته و در داخل یک روال فراخوانی کنید تا بانک اطلاعاتیتون به روز رسانی شود.
Exec(
'Update ['+@TableName+'] Set ['+@ColumnName+']=Replace(Replace(cast(['+@Columnname+']=As nvarchar(Max)),Nchar(1740),Nchar(1610)),Nchar(1705 ),Nchar(1603))'
)
دوست عزیز کرد من
ممنون از راهنماییتون
من روی مفهوم کرسر مشکل اساسی دارم اصلا نمی فهمم چیه؟! یه توضیح خوب از کرسر می تونید ارائه بدید؟

Galawij
یک شنبه 02 مرداد 1390, 08:36 صبح
سلام
هدف من از آن تکه کد این بود که خودتون بقیه راه را بریرد ولی مثل اینکه نیاز به توضیح بیشتر هست.
برای آموزش کرسر در همین سایت قبلاً توضیحاتی داده شده که می تونید به آن صفحات مراجعه کنید. برای مثال این لینک (http://barnamenevis.org/showthread.php?214403-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-Cursor-%D8%AF%D8%B1-sql)
ولی درادامه مابقی کد را با توضیحات براتون می ذارم.
در ابتدا دو متغیر برای نام جدول و نام ستون و یک متغیر از نوع کرسر تعریف می کنیم.
Declare @Table Nvarchar(500),@Col Nvarchar(500)
Declare @Table_Cursor Cursor
سپس ساختار دستور Select را برای کرسر با کلمه کلیدی For تعیین می کنید. در این دستور ما بین دو جدول سیستمی SysObject و SysColumns لیستی از ستون های با نوع داده های که برای کاراکتر می توان استفاده کرد واکشی می کنیم. دقیق به کدها نگاه کنید:

FOR
SELECT a.name,--table
b.name --col
FROM sysobjects a,
syscolumns b
WHERE a.id = b.id
AND a.xtype ='U'--User table
AND(
b.xtype = 99 --ntext
OR b.xtype = 35 -- text
OR b.xtype = 231 --nvarchar
OR b.xtype = 167 --varchar
OR b.xtype = 175 --char
OR b.xtype = 239 --nchar
)

این دستور 'a.xtype ='U روی جداولی که کاربر در بانک اطلاعاتی ایجاد کرده است، مانور می دهد. به اعدادی که برای نوع داده های کاراکتری استفاده شده است دقت کنید ممکن است این نوع داده در ورژن ها مختلف از Sql متفاوت باشد می تونید برای مطمئن شده از درستی کدها یک Select از جدول سیستمی SysTypes بگیرید.
متغییر کرسری را باز می کنید. و روی تک تک سطرها تا پایان رکوردها FETCH می کنید. با این دستورات :

OPEN Table_Cursor FETCHNEXTFROM Table_Cursor INTO @Table,@Col
WHILE(@@FETCH_STATUS= 0)
BEGIN

حالا با استفاده از آن تکه کدی که نوشتم اقدام به Update جداولتون می کنید.
و در نهایت متغیر را می بندید و حافظه اشغال شده توسط کرسر را آزاد می کنید. با این دستورات:

FETCHNEXTFROM Table_Cursor INTO @Table,@Col
ENDCLOSE Table_Cursor DEALLOCATE Table_Cursor

خیلی سعی کردم با یک روش غیر از کرسر پیاده کنم جواب نداد.

یوسف زالی
یک شنبه 02 مرداد 1390, 10:50 صبح
سلام مجدد.
کرسر ها اشیایی هستند مثل اشاره گر موقعیت در فایل که به ردیف خاصی از یک سلکت اشاره می کنند.
اگر با فایل کار کرده باشید می دونید که پس از هر read اگر بار دیگه read کنید کاراکتر بعدی خونده میشه.
اما کی گفت که کاراکتر بعدی خونده شه؟ فقط گفتیم خونده شه.
قضیه اینه که در حافظه مربوط به کار با فایل اشاره گری موقعیت کاراکتری که باید خوانده شه رو نگه میداره و با هربار خوندن خودش اتوماتیک می ره جلو.
تو فایل های غیر متنی (باینری) هم میشد با دستور Seek بگیم این اشاره گر بره به کدوم کاراکتر اشاره کنه.

دقیقا اتفاقی که در کرسر می افته هم همین جوریه.
حالا با تفاوتهایی و پیشرفته شدن هایی..

اینجا می شه روی "ردیف" های یک "Select" اشاره گر گذاشت.

به چه دردی می خوره خب؟
گاهی کار ما به گونه ای هست که مجبوریم به ازای هر ردیف از یک سلکت خاص کاری انجام بدیم که نمی شه اون کار رو یکهو انجام داد.
مثال خیلی ساده اش اینه که ردیفی داریم برای جمع مانده های ردیف های بالایی. نمیشه با یک دستور آپدیت این کارو کرد. پس میایم و روی سلکتی از جدول مورد نظر که می خواهیم روش کاری کنیم(در این مثال همه ردیف ها) کرسر می گذاریم و در یک حلقه یکی یکی می ریم روی ردیف بعدی و کارمون رو روی ردیفی که هستیم انجام می دیم...

این مفهوم ساده کرسر هست.
ایشالا همین روزا یک توضیح جامع درست درمون براتون می گذارم ..

یوسف زالی
یک شنبه 02 مرداد 1390, 12:19 عصر
معمولا میشه هر کرسری رو به While تبدیل کرد.
اول در یک جدول موقتی میریزیم . سپس top 1 یکی یکی از آن بر می داریم.
توضیجات در پستهای بعدی... (الان سر کارم!)

takavar_dez
شنبه 09 مهر 1390, 12:16 عصر
ایشالا همین روزا یک توضیح جامع درست درمون براتون می گذارم ..

سلام
ممنونم حتما این کار رو بکنید لطفا