views:

159

answers:

5

I have this little method that i use to get stuff from SQL. I either call it with varSearch = "" or varSearch = "something". I would like to know if having method written this way is best or would it be better to split it into two methods (by overloading), or maybe i could somehow parametrize whole WHERE clausule?

private void sqlPobierzKontrahentDaneKlienta(ListView varListView, string varSearch) {
        varListView.BeginUpdate();
        varListView.Items.Clear();
        string preparedCommand;
        if (varSearch == "") {
            preparedCommand = @"
                SELECT t1.[KlienciID],
                CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                          t2.[PodmiotFirmaNazwa] ELSE 
                          t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                ON t1.[PodmiotID] = t2.[PodmiotID]
                ORDER BY t1.[KlienciID]";
        } else {
            preparedCommand = @"
                SELECT t1.[KlienciID],
                CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                          t2.[PodmiotFirmaNazwa] ELSE 
                          t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                ON t1.[PodmiotID] = t2.[PodmiotID]
                WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue
                ORDER BY t1.[KlienciID]";
        }
        using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (SqlCommand sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
            sqlQuery.Parameters.AddWithValue("@searchValue", "%" + varSearch + "%");
            using (SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader())
                if (sqlQueryResult != null) {
                    while (sqlQueryResult.Read()) {
                        string varKontrahenciID = sqlQueryResult["KlienciID"].ToString();
                        string varKontrahent = sqlQueryResult["Nazwa"].ToString();
                        ListViewItem item = new ListViewItem(varKontrahenciID, 0);
                        item.SubItems.Add(varKontrahent);
                        varListView.Items.AddRange(new[] {item});
                    }
                }
        }
        varListView.EndUpdate();
    }
+6  A: 

The better approach would actually be to use a stored procedure instead of hardcoding SQL into your application. You can pass the where clause parameter to your stored procedure and handle the logic on the database side.

This approach also offers the advantage that if you need this logic in another application (like a JAVA app, for example) the logic is centralized in the database, so you don't have to rewrite it again.

dcp
TomTom
A: 

I am sure there are better approaches to this, like using a Stored procedure, But if you really need to do this You need:

     string preparedCommandTemplate = @"
                        SELECT t1.[KlienciID],
                        CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                                  t2.[PodmiotFirmaNazwa] ELSE 
                                  t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                        FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                        INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                        ON t1.[PodmiotID] = t2.[PodmiotID] {0}
                        ORDER BY t1.[KlienciID]";
string whereClause="WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue"

 if (string.Emtpy.Equals(varSearch )) {
            preparedCommand = string.Format(preparedCommandTemplate,string.Empty)
        } else {
            preparedCommand = string.Format(preparedCommandTemplate,whereCaluse)

        }
Midhat
the syntax might be a little off.
Midhat
I thought that using string merging is not "allowed" or even discouraged due to sql injection!
MadBoy
Besides ORDER BY needs to be after WHERE so you would actually need additional string whereClausue, string orderBy and have it merged together. But like i said earlier it's being downvoted on SO all over :)
MadBoy
order by will be after where clause. the {0} marker will be replaced with the where c lause
Midhat
A: 

If you don't want to use a stored procedure, at least parameterize the where clause. This kind of code can quickly get out of hand. I would also consider using a free text index or something like Lucene.NET to implement this kind of "like" search across multiple fields.

Tom Cabanski
+3  A: 

Sucks on MULTIPLE levels:

  • NO DAL at all - this means your SQL code is plastered over all the forms. Terrible maintenance - put at least all the SQL handling into one class.

  • It is a lot of manually writen code, as such it is bad performance wise (as in: programmer performance). Look at BLToolkit on how you can have all the code GENERATED at RUNTIME (from an attribuite with the SQL and an abstract method - the subclass with the real method is bytecode generated).

That said, unless I can convince you to use a real data access layer / ORM like NHibernate.

FOr 1 I would fire you as programmer (welcome back as trainee). Having SQL in forms just is not my idea of spending time when reworking a database - as such, it is not testable and a pain to maintain. THis is btw. ,not ".net specific" - isolating SQL is something I did 20 years ago (nearly) in smalltalk and C++ already ;)

For 2 I would - well - it would not happen due to guidelines ;)

TomTom
Harse, but fair.
Tim
Considering i am not programmer but administrator which was given a task to do I'm still being a trainee :-)
MadBoy
A: 

Given that you want to continue using hard-coded SQL statements in your code (and not switch to LINQ2SQL or Entity Framework or another ORM tool), the one thing you definitely do not want to do is add the where clause as a parameter to your method (if that's what you mean by 'parameterize the where clause'). This makes the clients that use this method dependent on your data access technology (in this case, a SQL database).

Compare the following two calls:

sqlPobierzKontrahentDaneKlienta(lv, "something");

and

sqlPobierzKontrahentDaneKlienta(lv,
    "WHERE t2.[PodmiotOsobaNazwisko] LIKE '%something%' OR " +
    "      t2.[PodmiotFirmaNazwa] LIKE '%something%' OR " +
    "      t2.[PodmiotOsobaImie] LIKE '%something%'")

Which one looks better?

Ronald Wildenberg
BY parameter i meant `sqlQuery.Parameters.AddWithValue("@whereClausule", whereClausulule);` and not additional parameter to method. but having that is not allowed I think.
MadBoy
Ah, ok. That is indeed not allowed.
Ronald Wildenberg