Avatar billede torotune Nybegynder
11. maj 2010 - 10:12 Der er 9 kommentarer og
1 løsning

SQL-søgning via flere felter

Hej,

Hvis jeg har en slags udvidet søgning bygget op som en form med flere Controls - Textboxe og DropDowns osv. - som man kan udfylde efter behov, hvordan er det så mest hensigtsmæssigt at behandle søgningen når man trykker på "søg"?

Skal jeg skrive en masse If-sætninger og spørge på hvilke felter der er udfyldt, og så skrive en masse forskellige SQL-sætninger ud fra udfaldet, eller kan man lave noget smartere med en  parametiriseret søgning og én SQL-sætning?

Mvh.
Avatar billede janus_007 Nybegynder
11. maj 2010 - 14:53 #1
Ja du bliver nødt til at skrive den med if. Sådan en if-then kan jo implementeres på mange måder, men i bund og grund handler det om at få sammensat din sql-query korrekt (parameteriseret eller ej, samme fremgangsmåde).
Om du så gør det med Linq eller ej, ændrer heller ingenting :)

og pssst... fald ikke i begynderfælden og tro at stored procedures gør dig lykkeligere *GG*

Det som du ihvertfald bør fokusere lidt på er at holde en grundliggende lagdeling. Eks.vis dine .aspx + code behind og så et ekstra lag (servicelaget og gerne i samme project), men adskilt på et logisk niveau, forstået på den måde at via din codebehind kalder du til andre mere specielle klasser.
Avatar billede torotune Nybegynder
11. maj 2010 - 15:23 #2
Okay -  men det vil sige at bare jeg har 6 søgefelter hvor der frit kan søges i hvert enkelt eller lade det være, så skal jeg faktisk have 36 forskellige SQL-sætninger der tager højde for alle kombinationer søgefelter - udfyldt eller ikke udfyldt?
Avatar billede janus_007 Nybegynder
11. maj 2010 - 16:35 #3
Nej du skal opbygge sql'en, i retning af.

Meget simpelt, uden nogen fancy IFilter osv... se her:

I dit servicelag;
class MyAmazingService
{
...
void GetFromDb(string a, string b).. osv.
{
string sql = null;
if(a != null)
sql += "and field = " + a

if(b != null)
sql += "and field1 = + b
}
}

Til sidst har du en række med and's eller måske or's, helt op til hvordan du bygger sql strengen op. Om du så bygger den med parameters eller.. tjaa... din beslutning.

Og til sidst er det blot at eksekvere imod db'en.

Nu skal ovenstående ikke være et udtryk for at jeg gør sådan, men blot tages som et forslag som der kan bygges videre på.
Personligt bruger jeg Linq og hvis jeg ikke kan komme til det, så ville jeg arbejde med interfaces og et DAL og skrive Sql'en der :) Altså undgå stored procedures, de er og bliver noget hø udenfor db-serveren til selects.
Avatar billede arne_v Ekspert
12. maj 2010 - 03:21 #4
Du kan enten opbygge en SQL streng, som:

using System;
using System.Data;
using System.Data.SqlClient;

namespace E
{
    public class Program
    {
        public static void DynQuery(String f1, String f2)
        {
            using(SqlConnection con = new SqlConnection(@"Server=ARNEPC3\SQLEXPRESS;Database=Test;Integrated Security=SSPI"))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                string sql = "SELECT * FROM t1";
                bool first = true;
                if(f1 != "")
                {
                    sql += (first ? " WHERE" : " AND");
                    sql += " f1 = @f1";
                    cmd.Parameters.Add("@f1", SqlDbType.Int);
                    cmd.Parameters["@f1"].Value = int.Parse(f1);
                    first = false;
                }
                if(f2 != "")
                {
                    sql += (first ? " WHERE" : " AND");
                    sql += " f2 = @f2";
                    cmd.Parameters.Add("@f2", SqlDbType.VarChar, 50);
                    cmd.Parameters["@f2"].Value = f2;
                    first = false;
                }
                cmd.Connection = con;
                cmd.CommandText = sql;
                SqlDataReader rdr = cmd.ExecuteReader();
                while(rdr.Read())
                {
                    Console.WriteLine(rdr[0] + " " + rdr[1]);
                }
                rdr.Close();
            }
        }
        public static void Main(string[] args)
        {
            DynQuery("", "");
            DynQuery("2", "");
            DynQuery("", "BB");
            DynQuery("2", "BB");
            Console.ReadKey();
        }
    }
}

Eller du kan bruge en fast SQL streng og ISNULL:

using System;
using System.Data;
using System.Data.SqlClient;

namespace E
{
    public class Program
    {
        public static void DynQuery(String f1, String f2)
        {
            using(SqlConnection con = new SqlConnection(@"Server=ARNEPC3\SQLEXPRESS;Database=Test;Integrated Security=SSPI"))
            {
                con.Open();
                SqlCommand cmd = new SqlCommand("SELECT * FROM t1 WHERE f1 = ISNULL(@f1,f1) AND f2 = ISNULL(@f2,f2)", con);
                cmd.Parameters.Add("@f1", SqlDbType.Int);
                cmd.Parameters["@f1"].Value = (f1 != "") ? (object)int.Parse(f1) : DBNull.Value;
                cmd.Parameters.Add("@f2", SqlDbType.VarChar, 50);
                cmd.Parameters["@f2"].Value = (f2 != "") ? (object)f2 : DBNull.Value;
                SqlDataReader rdr = cmd.ExecuteReader();
                while(rdr.Read())
                {
                    Console.WriteLine(rdr[0] + " " + rdr[1]);
                }
                rdr.Close();
            }
        }
        public static void Main(string[] args)
        {
            DynQuery("", "");
            DynQuery("2", "");
            DynQuery("", "BB");
            DynQuery("2", "BB");
            Console.ReadKey();
        }
    }
}
Avatar billede janus_007 Nybegynder
12. maj 2010 - 09:10 #5
Arne, har du nogensinde hørt historien om fiskeren der fik en søn?
Avatar billede arne_v Ekspert
12. maj 2010 - 13:19 #6
??
Avatar billede torotune Nybegynder
17. maj 2010 - 14:42 #7
Hej - tak for inspirationen. Jeg kan se at det vil være mere overskueligt med en langsom opbygning af SQL-strengen, som man så fyrer mod databasen til sidst..!

Hvad er det med historien om fiskeren? :-)
Avatar billede arne_v Ekspert
13. juni 2010 - 04:11 #8
Tid at få afsluttet her?
Avatar billede torotune Nybegynder
13. juni 2010 - 13:36 #9
Jeg ventede bare på historien om fiskeren.. :-) Men siger tak for jeres forslag begge to - som gav en løsning på problemet. Lægger I svar?
Avatar billede arne_v Ekspert
13. juni 2010 - 14:48 #10
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester