PDA

View Full Version : سوال: مشکل در کد جستجو و ارتباط بین دو جدول



fa_karoon
جمعه 21 خرداد 1389, 00:53 صبح
سلام دوستان در عملیات جستجو دچار مشکل شده ام شرح کارم را می نویسم لطفا کدها را بردارید و در پروژه ای اجرا کنید و اگر متوجه شدید عیب کد من چیست که با مشکل مواجه می شود مرا راهنمایی کنید
سیستم جستجوی من به این صورت است فرد در یک TextBox کلمه ی مورد نظر خود را می نویسد و کلید جستجو را فشار می دهد سپس این کلمه یا کلمات در فیلد KeyWords در جدول Content جستجو می شوند و اگر رکوردی وجود داشت که این کلمه در آن وجود داشت برگردانده می شود در این جدول User_ID اشخاص نیز که در جدول Users کلید اصلی است به عنوان کلید خارجی قرار داده شده و هر رکوردی که در نتیجه جستجو برگردانده می شود براساس فیلد User_ID آن نام کاربری اش از جدول Users نیز برگردانده می شود.
مشکلی که اکنون با آن مواجه شده ام این است که هنگامی که دو کلمه یا بیشتر را جستجو می کنم به ازای هر کاربری که در جدول Users وجود دارد رکورد یافت شده در جدول Content تکرار می شود (البته گاهی اینجوری تکرار می شوند و گاهی چندتا در میون لطفا کد را امتحان کنید و نتیجه را ببینید و اگر کشف کردید مشکل از کجاست کمک کنید)


PublicFunction GetDatasource() As DataSet
'------Create String Where---------------
Dim strWhere AsString
Dim arySearch() AsString = Request.QueryString("m").Split(" ")
If arySearch.GetLength(0) = 1 Then
strWhere = "Content_KeyWords LIKE '%" & Request.QueryString("m") & "%'"
Else
strWhere = "Content_KeyWords LIKE '%" & Request.QueryString("m") & "%'"
Dim n AsInteger, i AsInteger, j AsInteger, p AsInteger, t AsInteger, k, h AsInteger
n = arySearch.Length
Dim ary() AsString = Request.QueryString("m").Split(" ")
h = (n * n) - n
Dim mul(n - 2, h) AsString
k = 0
For i = 0 To n - 1
For j = 0 To n - 1
If arySearch(i) <> ary(j) Then
mul(0, k) = arySearch(i) + " " + ary(j)
k = k + 1
EndIf
Next
Next

t = 0
For p = 2 To n
k = 0
For i = 0 To n - 1
For j = 0 To h - 1
If mul(t, j).IndexOf(arySearch(i)) = -1 Then
mul(t + 1, k) = arySearch(i) + " " + mul(t, j)
k = k + 1
EndIf
Next
Next
t = t + 1
'd = (n * n) - n
Next
For i = 0 To n - 2
For j = 0 To h - 1
strWhere += " OR Content_KeyWords LIKE '%" & mul(i, j) & "%'"
Next
Next
For i = 0 To n - 1
strWhere += " OR Content_KeyWords LIKE '%" & arySearch(i) & "%'"
Next
EndIf
'------ End Create String Where---------------
'------ Begin Recognition Role ---------------
Dim strRole AsString = "Anonymous"
Dim Comm AsNew SqlCommand("Select * from Login_Table where User_ID='" & _
Session("UserID") & "'", Application("con"))
Dim myread As SqlDataReader
Application("con").open()
myread = Comm.ExecuteReader

DoWhile myread.Read
strRole = myread(3).ToString.Trim
Loop
myread.Close()
Comm.Dispose()
'------ End Recognition Role ---------------

Dim ds AsNew DataSet()
Dim tb AsNew DataTable("tb")
Dim col AsNew DataColumn("Title", GetType(String))
tb.Columns.Add(col)
col = New DataColumn("Path", GetType(String))
tb.Columns.Add(col)
col = New DataColumn("Date", GetType(String))
tb.Columns.Add(col)
Dim row As DataRow = Nothing
Dim strcommand AsString = " "
If Request.QueryString("n") = "4"Then
strcommand = "SELECT Content_Table.Content_ID, Content_Table.Content_Name, Content_Table.Content_Size, Content_Table.Content_Date, Content_Table.Content_Path, Content_Table.Content_Level, Content_Table.ContentType_ID, Users_Table.User_Name, Content_Table.Content_Indexing,Users_Table.User_ID FROM Content_Table, Users_Table WHERE " & strWhere & " AND" & _
" Content_Deleted ='False' AND Content_upHold ='True' AND Content_Table.User_ID=Users_Table.User_ID"
Else
strcommand = "SELECT Content_Table.Content_ID, Content_Table.Content_Name, Content_Table.Content_Size, Content_Table.Content_Date, Content_Table.Content_Path, Content_Table.Content_Level, Content_Table.ContentType_ID, Users_Table.User_Name, Content_Table.Content_Indexing FROM Content_Table, Users_Table WHERE " & strWhere & " AND ContentType_ID='" & _
Request.QueryString("n") & "' AND Content_Deleted ='False' AND Content_upHold ='True' AND Content_Table.User_ID=Users_Table.User_ID"
EndIf
Dim com AsNew SqlCommand(strcommand, Application("con"))
Dim myreader As SqlDataReader
myreader = com.ExecuteReader

DoWhile myreader.Read

If myreader(5).ToString.Trim = "Private"Then
If (strRole = "Admin") Or (strRole = "User") Then
If (Session("UserID") <> 0) And (myreader(8).ToString.IndexOf(Session("UserID").ToString) <> -1) Then
row = tb.NewRow()
row("Title") = "<tr><td><table><tr><td><a href=Download.aspx?file=" & myreader(4).ToString & ">" & myreader(1).ToString & "</a></td><td> , " & myreader(2).ToString & "</td></tr></table></td></tr>"
If myreader(6).ToString <> "3"Then
row("Path") = "<tr><td><table><tr><td><a href=ShowAbstract.aspx?id=" & myreader(0).ToString & " style=text-decoration:none>چکیده , </a></td><td> ارسال شده توسط " & myreader(7).ToString & "</td></tr></table></td></tr>"
Else
row("Path") = "<tr><td> ارسال شده توسط " & myreader(7).ToString & "</td></tr>"
EndIf
row("Date") = "<tr><td> ارسال شده در تاریخ " & myreader(3).ToString & "</td></tr><tr><td><hr></td></tr>"
tb.Rows.Add(row)
Else
row = tb.NewRow()
row("Title") = "<tr><td><table><tr><td style=height:33px;width:33px;background-image:url('Images/LockArticle.gif');background-repeat:no-repeat;background-position:center center;></td><td>" & myreader(1).ToString & "</td><td> , " & myreader(2).ToString & "</td></tr></table></td></tr>"

If myreader(6).ToString <> "3"Then
row("Path") = "<tr><td style=padding-right:30px><table><tr><td><a href=ShowAbstract.aspx?id=" & myreader(0).ToString & " style=text-decoration:none>چکیده , </a></td><td> ارسال شده توسط " & myreader(7).ToString & "</td></tr></table></td></tr>"
Else
row("Path") = "<tr><td style=padding-right:30px> ارسال شده توسط " & myreader(7).ToString & "</td></tr>"
EndIf
row("Date") = "<tr><td style=padding-right:30px> ارسال شده در تاریخ " & myreader(3).ToString & "</td></tr><tr><td><hr></td></tr>"
tb.Rows.Add(row)
EndIf
ElseIf strRole = "Anonymous"Then
row = tb.NewRow()
row("Title") = "<tr><td><table><tr><td style=height:33px;width:33px;background-image:url('Images/LockArticle.gif');background-repeat:no-repeat;background-position:center center;></td><td>" & myreader(1).ToString & "</td><td> , " & myreader(2).ToString & "</td></tr></table></td></tr>"

If myreader(6).ToString <> "3"Then
row("Path") = "<tr><td style=padding-right:30px><table><tr><td><a href=ShowAbstract.aspx?id=" & myreader(0).ToString & " style=text-decoration:none>چکیده , </a></td><td> ارسال شده توسط " & myreader(7).ToString & "</td></tr></table></td></tr>"
Else
row("Path") = "<tr><td style=padding-right:30px> ارسال شده توسط " & myreader(7).ToString & "</td></tr>"
EndIf
row("Date") = "<tr><td style=padding-right:30px> ارسال شده در تاریخ" & myreader(3).ToString & "</td></tr><tr><td><hr></td></tr>"
tb.Rows.Add(row)
EndIf
Else
row = tb.NewRow()
row("Title") = "<tr><td style=padding-right:30px><table><tr><td><a href=Download.aspx?file=" & myreader(4).ToString & ">" & myreader(1).ToString & "</a></td><td> , " & myreader(2).ToString & "</td></tr></table></td></tr>"
If myreader(6).ToString <> "3"Then
row("Path") = "<tr><td style=padding-right:30px><table><tr><td><a href=ShowAbstract.aspx?id=" & myreader(0).ToString & " style=text-decoration:none>چکیده , </a></td><td> ارسال شده توسط " & myreader(7).ToString & "</td></tr></table></td></tr>"
Else
row("Path") = "<tr><td style=padding-right:30px> ارسال شده توسط " & myreader(7).ToString & "</td></tr>"
EndIf
row("Date") = "<tr><td style=padding-right:30px> ارسال شده در تاریخ " & myreader(3).ToString & "</td></tr><tr><td><hr></td></tr>"
tb.Rows.Add(row)
EndIf
Loop

Application("con").close()
ds.Tables.Add(tb)
Return ds
EndFunction

PublicSub BindListView()
'bind to list view
ListView1.DataSource = GetDatasource()
ListView1.DataBind()
EndSub

ProtectedSub Page_Load(ByVal sender AsObject, ByVal e As System.EventArgs) HandlesMe.Load

If (Request.QueryString("n") <> Nothing) And (Request.QueryString("m") <> Nothing) Then

IfNot IsPostBack Then
BindListView()
EndIf
EndIf
EndSub

ProtectedSub DataPager1_PreRender(ByVal sender AsObject, ByVal e As System.EventArgs) Handles DataPager1.PreRender
If Request.QueryString("n") <> NothingAnd Request.QueryString("m") <> NothingThen
BindListView()
EndIf
EndSub
EndClass

hamedsabzian
جمعه 21 خرداد 1389, 22:21 عصر
دوست عزیز! مطالعه ی کدت یه کم سخته!
ببین مشکلت با گذاشتن DISTINCT توی دستور SELECT حل میشه یا نه؟

سری هم به تاپیک زیر بزن:
گفتگوی فنی شماره یک - اصول و قواعد کد نویسی (http://www.barnamenevis.org/forum/showthread.php?t=224704)

fa_karoon
شنبه 22 خرداد 1389, 01:36 صبح
دوست عزیز! مطالعه ی کدت یه کم سخته!
ببین مشکلت با گذاشتن DISTINCT توی دستور SELECT حل میشه یا نه؟

سری هم به تاپیک زیر بزن:
گفتگوی فنی شماره یک - اصول و قواعد کد نویسی (http://www.barnamenevis.org/forum/showthread.php?t=224704)

من کدم رو یه مقدار اصلاح کردم باور کنید امتحانش خیلی سخت نیست فقط کافیه یه لیست ویو و یه دیتا پیجر روی صفحه بذارید و کد رو نیز کپی کنید دو تا جدول هم می خواد با نام Content_Table و Users_Table
بعدش هم هیچ ربطی به Distinct نداره!

Alireza_Salehi
شنبه 22 خرداد 1389, 02:10 صبح
این مشکل زمانی پیش می آید که شما به جای استفاده از عملگر Join نام جدول ها را با کاما بعد از FROM از هم جدا کرده اید
در این حالت دو جدول در هم ضرب دکارتی می شوند، و به هر ردیف از جدول اول به ازای هر ردیف از جدول دوم تکرار می شود.

از عملگر join استفاده کنید مشکل حل می شود.


در ضمن کدتان خیلی کثیف و درهم وبرهم است.

hamedsabzian
شنبه 22 خرداد 1389, 02:12 صبح
سلام!
قصد جسارت نداشتم!:لبخند:

1. یه مثال از ورودی ها بزنید. (یه URL بدید، چیزی که توی QueryString میاد)
2. اون حلقه های For تو در تو برای چیه؟

3. امتحان کنید:
قسمت Join جداول تون مستقل از قسمت WHERE بنویسید. به این شکل:

... FROM Content_Table INNER JOIN Users_Table ON Content_Table.User_ID=User_Table.User_ID WHERE ...

در ضمن کدتان به شدت مستعد SQL Injection است. پیشنهاد می کنم بعد از رفع مشکل اصلی برای برطرف کردن این مشکل هم اقدام کنید.
موفق باشید!

fa_karoon
شنبه 22 خرداد 1389, 20:56 عصر
از همه ی دوستانی که جواب دادند واقعا ممنون با راهنمایی هاتون مشکلم حل شد فقط گفته بودید که کدم کثیف است و مستعد SQL Injection . نمی دونم ممکنه اینجا جاش نباشه ولی اگه امکان داره می شه بگید چطور می تونم کدم رو مرتب تر کنم. در مورد SQL Injection هم مطالعاتی داشتم اما بلد نیستم تویه کدنویسی هام ازش استفاده کنم می شه تویه این کد بگید کجا باید چه چیزهایی رو رعایت کنم(البته اگه برای دوستان مشکلی نیست و امکانش هست که تویه این تاپیک گفته بشه)
باز هم ممنونم:تشویق:

fa_karoon
دوشنبه 24 خرداد 1389, 19:35 عصر
دوستان لطفا اگه امکان داره تو این تاپیک یا یه تاپیک جدید با مثال(مثلا همین کد من) توضیح بدید که برای بهتر شدن این کد و جلوگیری از SQL Injection چه کار باید کرد؟ لطفا
ممنونم

hamedsabzian
سه شنبه 25 خرداد 1389, 02:17 صبح
به نظر بنده سخته که آدم از همون اول خوب کد بنویسه. وقتی ضرورت خوب کد نوشتن براتون آشکار میشه خودبه خود اصول رو رعایت می کنید. که این با تجربه به دست میاد.( البته این حرفا چیزی رو راجع به خودم ثابت نمی کنه. بنده کدهای بسیاری نوشته ام که مصداق بارز WTF بوده اند).
به آدرس زیر مراجعه گردد:
http://www.barnamenevis.org/forum/showthread.php?t=224704

اما در مورد SQL Injection ...
هیچ وقت نباید ورودی را که کاربر وارد می کنه، به صورت مستقیم با رشته هایی که به عنوان کد SQL در نظر گرفته اید جمع کنید (Concat).
یک راه خوب اینه که ورودی هارو به صورت پارامتر بدید. مثال:
به جای:
SqlCommand com = new SqlCommand("SELECT * FROM Order as o WHERE o.Name='" + Request.QueryString["Name"] + "'");
بنویسید:
SqlCommand com = new SqlCommand("SELECT * FROM Order as o WHERE o.Name=@Name");
com.Parameters.AddWithValue("@Name", Request.QueryString["Name"]);

موفق باشید.