13 Replies - 1546 Views - Last Post: 13 January 2011 - 11:31 PM Rate Topic: ***-- 2 Votes

#1 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Sql Pattern with C#

Posted 04 January 2011 - 05:41 AM

I want a query that can search for books in which their title contains the search text.

Here is the whole function
which searches books by ID, by book title, by year, by place and in addition by category
so I don't have problems with all except searching by book title. Since book titles are long it is not advisable to make the search with the whole title. So I wanted to be any book that contains the search text. For Instance if I search like this "tif" then Artificial Intelligence, Tiffany Days,...should come out.
 public static DataTable GetBooks(int ID,string bt, int yr, string place,string cat)
        {
            try
            {
                DBConnector.Connect();
                string query,query1;
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = DBConnector.conn;
                query = "";

                if (ID != 0)
                {
                    query = "SELECT * FROM Book WHERE Book_ID='"+ID+"'";
                }
                else if (bt != "")
                {
                    query = "SELECT * FROM Book WHERE Book_Title LIKE '" + bt + "'"; 
                }
                else if (place != "")
                {
                    query = "SELECT * FROM Book WHERE Place LIKE '" + place + "'";
                }
                else if (yr != 0)
                {
                    query = "SELECT * FROM Book WHERE Year_Published='" + yr + "'";
                }

                query1 = query + "AND Category_ID='" + Category.GetID(cat) + "'"; //inculdes category search

                
                if (cat == "All")
                {
                    cmd.CommandText = query;
                }
                else
                {
                    cmd.CommandText = query1;
                }

                SqlDataAdapter adp = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                adp.Fill(dt);
                return dt;
            }
            catch
            {
                return null;
            }

        
        }



As you can see in the above code I used LIKE operator first, I tried the following too...
 query = "SELECT * FROM Book WHERE Book_Title LIKE '" + "*"+bt+"*" + "'"; 



It didn't work....
So my question is how should the query should look like.....?????????????????


If needed here is code for the function that is activated when search button is clicked on the search form, it calls GetBooks(...)....
lbl a prefix for the name of labels
cmb a prefix for the name of combo boxes
gv a prefix for the data grid view controls
txt a prefix for the name of textbox controls
 private void btnSearch_Click(object sender, EventArgs e)
        {
           
           try
           {
               lblStatus.Text = "";
               if (gvResults.Rows.Count == 0)
               {
                   gvResults.DataSource = null;
               }
            switch (cmbSearchBy.Text)
            {
                    
                case "ID":
                    int result;
                    int.TryParse(txtSearchText.Text,out result);

                    if (result == 0)
                    {
                        lblStatus.Text = "Please Enter a Number on the Search Text!";
                        gvResults.DataSource = null;

                    }
                    else
                    {

                        gvResults.DataSource = Book.GetBooks(int.Parse(txtSearchText.Text), "", 0, "", "All");
                        txtSearchText.Text = "";
                        
                    }
                    break;
                    
                case "BookTitle":
                      if (txtSearchText.Text.Length < 3)
                      {
                          lblStatus.Text = "Search Text should contain atleast 3 characters";
                      }
                      else
                      {
                          gvResults.DataSource = Book.GetBooks(0, txtSearchText.Text, 0, "", cmbSearchFrom.Text);
                          txtSearchText.Text = "";
                      } 
                      break;
                case "Year":
                      gvResults.DataSource = Book.GetBooks(0,"",int.Parse(txtSearchText.Text),"", cmbSearchFrom.Text);
                      txtSearchText.Text = "";
                      break;
                case "Place":
                    gvResults.DataSource = Book.GetBooks(0,"",0,txtSearchText.Text, cmbSearchFrom.Text);
                    txtSearchText.Text = "";
                    break;
                
                   
            }
            lblStatus.Text = lblStatus.Text+"\n"+gvResults.Rows.Count.ToString() + " Result/s Found";
            lblStatus.ForeColor = Color.Blue;
           }
            catch
           {
            lblStatus.Text="Some Error Occurred";
           }
        
       
    
    }





Again if needed here is the script for the table Book, note this not the full database script.

USE [BookCirculation]
GO

/****** Object:  Table [dbo].[Book]    Script Date: 01/04/2011 15:37:00 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Book](
	[Book_ID] [int] NOT NULL,
	[Book_Title] [varchar](50) NOT NULL,
	[Category_ID] [int] NOT NULL,
	[Author_Name] [varchar](50) NOT NULL,
	[Quantity_Available] [int] NOT NULL,
	[Total_Quantity] [int] NOT NULL,
	[Price] [float] NOT NULL,
	[Year_Published] [bigint] NOT NULL,
	[Publisher_Name] [varchar](50) NOT NULL,
	[Place] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Book] PRIMARY KEY CLUSTERED 
(
	[Book_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Book]  WITH CHECK ADD  CONSTRAINT [FK_Book_Category] FOREIGN KEY([Category_ID])
REFERENCES [dbo].[Category] ([Category_ID])
GO

ALTER TABLE [dbo].[Book] CHECK CONSTRAINT [FK_Book_Category]
GO






Is This A Good Question/Topic? 0
  • +

Replies To: Sql Pattern with C#

#2 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1210
  • View blog
  • Posts: 4,124
  • Joined: 27-January 10

Re: Sql Pattern with C#

Posted 04 January 2011 - 05:52 AM

Not tested, but I think your SQL command should be something like:

select * from Book where Book_Title like %parameterhere%


Edit: That's what your command has to look like ultimately. Format the string to your liking.

This post has been edited by Sergio Tapia: 04 January 2011 - 06:17 AM

Was This Post Helpful? 0
  • +
  • -

#3 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1511
  • View blog
  • Posts: 5,916
  • Joined: 21-March 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 05:54 AM

For SQL Server, the LIKE command uses "%" as wildcards...NOT "*".

So the correct way to use LIKE would be like this...

query = "SELECT * FROM Book WHERE Book_Title LIKE '%" + bt + "%";



or a little better formatted..

query = string.Format("SELECT * FROM Book WHERE Book_Title LIKE '%{0}%'", bt);



Also, you shouldn't be selecting everything from the table. Only return the columns that you are going to use.
Was This Post Helpful? 1
  • +
  • -

#4 Vishu Sukhdev  Icon User is offline

  • D.I.C Head

Reputation: 38
  • View blog
  • Posts: 150
  • Joined: 19-February 10

Re: Sql Pattern with C#

Posted 04 January 2011 - 05:59 AM

Hi Sergio,
you can use query like:-
query = "SELECT * FROM Book WHERE Book_Title LIKE '%"+ bt +"%'"; 


Was This Post Helpful? 1
  • +
  • -

#5 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1210
  • View blog
  • Posts: 4,124
  • Joined: 27-January 10

Re: Sql Pattern with C#

Posted 04 January 2011 - 06:17 AM

Ah yeah, I was right! :P It's been a while since I wrote raw tsql commands.
Was This Post Helpful? 0
  • +
  • -

#6 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 06:52 AM

I tried all by commenting turn by turn

according to Sergio Tapia I replaced the "*" with the "%"
query = "SELECT * FROM Book WHERE Book_Title LIKE '" + "%"+bt+"%" + "'"; 



according to eclipsed4utoo and Vishu Sukhdev
query = "SELECT * FROM Book WHERE Book_Title LIKE '%" + bt + "%'"; //



according to eclipsed4utoo again
query = string.Format("SELECT * FROM Book WHERE Book_Title LIKE '%{0}%'", bt);





Thank you all
All the above queries work
Everybody I can't believe how fast I got the answer after trying to fix it for about 2 hours

One More Question
I used this query using VB and ASP.NET with SQL Server as a BackEnd (as u can see by Inheriting the Membership Provider) when I was doing my graduation project last year.
In the Search Form on the search text box I wrote something like this "A*" and all the user names that start with the letter "A" come out as a result.

So eclipsed4utoo you said sql server does not use "*"
Partial Public NotInheritable Class UserAccount
    Inherits MembershipProvider
'....
'....
Public Overloads Shared Function FindUsersByName(ByVal userNameToMatch As String) As IQueryable(Of UserAccount)

        Dim dc As New BusinessClassesDataContext
        Dim query = (From u In dc.UserAccounts Select u Where u.userName Like userNameToMatch)
        Return query

    End Function
'...
'....
End Class



Thank you for helping.
Was This Post Helpful? 0
  • +
  • -

#7 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1210
  • View blog
  • Posts: 4,124
  • Joined: 27-January 10

Re: Sql Pattern with C#

Posted 04 January 2011 - 07:05 AM

You're going to have to create yourself a helper method.

Something like:

public string FindSimilar(string searchParameter, string type)
{
    switch type
    {
        case "pre":
            return "select * from Book where Book_Title like " + searchParameter + "%";
     
        case "post":
            return "select * from Book where Book_Title like %" + searchParameter;

        default:
            break;
    }
}


If your textbox has "A*" as text, you know you want to do a "post" search, so call that. Maybe create an enumerable?

Just a proof of concept, but you get the point.
Was This Post Helpful? 0
  • +
  • -

#8 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 07:18 AM

You have answered the question I didn't Intend to ask
But I will use this function for my previous question.

But I am not asking about the book search now this is an another question

I am asking about this query that helped me to search all user names that start with the letter "A", when i input A* on a textbox and click on search button(the search button calls the function)

I am arguing "*" can also be used against SQL Server

Here is the previous code again(look @ the query I used)
Note this is not C#, this is VB.NET
I shouldn't have posted a VB.NET code on a C# forum but I posted it just because there are similar. I can convert it to C#, but there is no point of doing that.
Partial Public NotInheritable Class UserAccount
    Inherits MembershipProvider

'....
'....
'....
Public Overloads Shared Function FindUsersByName(ByVal userNameToMatch As String) As IQueryable(Of UserAccount)
 
        Dim dc As New BusinessClassesDataContext

        Dim query = (From u In dc.UserAccounts Select u Where u.userName Like userNameToMatch)
        Return query
    End Function

'...
'....
'....
End Class





Sorry for taking your precious time
Thanks
Was This Post Helpful? 0
  • +
  • -

#9 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1511
  • View blog
  • Posts: 5,916
  • Joined: 21-March 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 07:23 AM

While you might be passing "A*" to the method, if you look at the generated SQL that Linq-To-SQL/EF created, you would have seen that it used "%", so your LIKE operator would have probably looked like this...

SELECT * FROM UserAccounts WHERE UserName LIKE '%A*%'



Which could possibly work.
Was This Post Helpful? 1
  • +
  • -

#10 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 07:56 AM

I think may be absolutely right. Can you tell me where to set a breakpoint and look at the LINQ To SQL generated query.

Plus I want to ask you and everybody whether using such tools like LINQ to SQL is advisable for students doing projects or not. Because LINQ to SQL will do everything for you.
What do you think????

I personally did my final year project with VB,ASP.NET and LINQ to SQL
Was This Post Helpful? 0
  • +
  • -

#11 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1511
  • View blog
  • Posts: 5,916
  • Joined: 21-March 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 08:04 AM

For viewing the query, try this.

As for using LINQ-To-SQL, I would say for beginners to use ADO.Net(DataSet/DataAdapter or SqlConnection/SqlCommand/SqlDataReader) for the simple reason to learn how to do database access(and writing queries) in .Net. Once students get into the workplace, they can't be guaranteed to be able to use the tools they want to use. For example, I am a huge fan of LINQ-To-SQL, and have been using it at home since it was originally released. However, at work, it was only recently(about 2 weeks ago) that we were allowed to LINQ-To-SQL in projects.

Now, if you already know how to do ADO.Net, I would recommend using LINQ-To-SQL or EF for the simple fact that it helps with the speed of development.
Was This Post Helpful? 1
  • +
  • -

#12 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Re: Sql Pattern with C#

Posted 04 January 2011 - 09:33 AM

View Posteclipsed4utoo, on 04 January 2011 - 07:04 AM, said:

For viewing the query, try this.

As for using LINQ-To-SQL, I would say for beginners to use ADO.Net(DataSet/DataAdapter or SqlConnection/SqlCommand/SqlDataReader) for the simple reason to learn how to do database access(and writing queries) in .Net. Once students get into the workplace, they can't be guaranteed to be able to use the tools they want to use. For example, I am a huge fan of LINQ-To-SQL, and have been using it at home since it was originally released. However, at work, it was only recently(about 2 weeks ago) that we were allowed to LINQ-To-SQL in projects.

Now, if you already know how to do ADO.Net, I would recommend using LINQ-To-SQL or EF for the simple fact that it helps with the speed of development.


thanks again and again
Was This Post Helpful? 0
  • +
  • -

#13 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 3793
  • View blog
  • Posts: 6,390
  • Joined: 08-June 10

Re: Sql Pattern with C#

Posted 05 January 2011 - 08:10 AM

I can't believe nobody told him to use Sql Parameters. I'm about ready to start suggesting LINQ to SQL or Entity Framework to everyone just so I don't have to say anything about SQL Injection anymore.

Seriously, don't use string concatenation to build a query. First of all, it's difficult to read, and the difference between this:

string sql = "select * from table where column='"+var+"' and ...";


and this

string sql = "select * from table where column = "+var+" and ...";


isn't readily apparent.

But this:

string sql = "select * from table where column=@column and ...";
...
sqlCommand.Parameters.AddWithValue("@column", var);


That's obvious. You don't have to remember to use quotes or not, and it's obvious what's going on.

What's more, any input in the parameter is escaped, meaning that people can't do a SQL Injection attack against you. Imagine using that SQL above, someone passed in this as the value for "var":

false; delete from table; --


Or something like that. That code would be executed if you just use a string. If you use parameters, that would be escaped and would not be executed.

Please, please start using parameters. It'll make your life easier and your code safer.
Was This Post Helpful? 2
  • +
  • -

#14 tinase  Icon User is offline

  • New D.I.C Head

Reputation: -16
  • View blog
  • Posts: 33
  • Joined: 19-June 08

Re: Sql Pattern with C#

Posted 13 January 2011 - 11:31 PM

View PostinsertAlias, on 05 January 2011 - 07:10 AM, said:

I can't believe nobody told him to use Sql Parameters. I'm about ready to start suggesting LINQ to SQL or Entity Framework to everyone just so I don't have to say anything about SQL Injection anymore.
....

I always use sql parameters for long series of fields but for the smaller ones like this, using parameters will just increase the number of lines of code. I don't have security concerns like sql injection because this is a simple project. But thanks for you advice.

you can see the following query with a long series of fields
 public Boolean Add()
        {
            try
            {
                DBConnector.Connect();
                string iquery = "INSERT INTO Book VALUES(@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9,@p10)";
                SqlCommand icmd = new SqlCommand(iquery, DBConnector.conn);
                string squery = "SELECT Book_ID FROM Book";
                SqlDataAdapter adp = new SqlDataAdapter(squery, DBConnector.conn);
                DataTable dt = new DataTable();
                adp.Fill(dt);
                int max = 1; 
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    int temp = int.Parse(dt.Rows[i].ItemArray[0].ToString());
                    if (temp > max)
                    {
                        max = temp;
                    }
                }
                max++; 
                icmd.Parameters.AddWithValue("@p1", max);
                icmd.Parameters.AddWithValue("@p2", _Book_Title);
                icmd.Parameters.AddWithValue("@p3", _Category_ID);
                icmd.Parameters.AddWithValue("@p4", _Author_Name);
                icmd.Parameters.AddWithValue("@p5", _Quantity_Available);
                icmd.Parameters.AddWithValue("@p6", _Total_Quantity);
                icmd.Parameters.AddWithValue("@p7", _Price);
                icmd.Parameters.AddWithValue("@p8", _Year_Published);
                icmd.Parameters.AddWithValue("@p9", _Publisher_Name);
                icmd.Parameters.AddWithValue("@p10", _Place);
                icmd.ExecuteNonQuery();
                return true; 
            }
            catch
            {
                return false;
            }
        }


This post has been edited by tinase: 13 January 2011 - 11:35 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1