webForumDet fria alternativet

göra en select på ett eller flera nummer som finns i ett fält

Databaser & SQL

10 svar · 1 013 visningar · startad av Sanji

Medlem sedan juli 2009355 inlägg
Frågan#1

hej! jag bygger en sql select där jag sorterar resultaten med hjälp av tecken som skrivs in i sex olika textboxar. jag använder substring metoden i sql för att jämföra om en siffra på en viss position i fältet är samma som den man skrivit in. jag har fått sökningen på första och sista tecknet att fungera, både då man bara söker på antingen första eller sista och då man söker på båda samtidigt. problemet är att jag inte får till sökningen på de fyra tecken som ligger mellan första och sista.

jag kodar i asp.net och c#, och databasen är mssql.

så här ser koden ut som skapar villkor för select-satsen:

int numberofconditions = 0;
            string condition = " WHERE";
            string and = "";
            if (searchtbox1.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference) - 5),(len(offerdata.objectreference) - 5)) =" + searchtbox1.Text; numberofconditions++; }
            
            if (searchtbox2.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference) - 4),(len(offerdata.objectreference) - 4)) =" + searchtbox2.Text; numberofconditions++; }
           
            if (searchtbox3.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference) - 3),(len(offerdata.objectreference) - 3)) =" + searchtbox3.Text; numberofconditions++; }
            
            if (searchtbox4.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference) - 2),(len(offerdata.objectreference) - 2)) =" + searchtbox4.Text; numberofconditions++; }
           
            if (searchtbox5.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference) - 1),(len(offerdata.objectreference) - 1)) =" + searchtbox5.Text; numberofconditions++; }
            
            if (searchtbox6.Text != "")
            { if (numberofconditions > 0) { and = " AND "; } condition += and + " substring(offerdata.objectreference, (len(offerdata.objectreference)) ,(len(offerdata.objectreference))) =" + searchtbox6.Text; numberofconditions++; }
            
            if (numberofconditions > 0)
            {
                RefreshTable(condition);
            }

jag använder dessa villkor i metoden RefreshTable, där jag hämtar värden med en sql datareader:

SqlDataReader reader = this.CustomQuery("SELECT calculation.costcarrier AS [description], calculation.supplierID AS [calcsupplierID], calculation.pieces AS [calcpieces], calculationbase.costcarrier AS [costcarrier], article.articlenr AS [articlenumber], offerdata.number AS [offernumber], offerdata.objectreference AS [reference], offerdata.responsibleID AS [offerresponsibleID], offerdata.responsibleproductionID AS [responsibleproduction], offerdata.deliverydate, suppliers.suppliername AS [customername]  FROM Sanji_Database.Sanji_admin.calculation LEFT OUTER JOIN Sanji_Database.Sanji_admin.calculationbase ON (calculation.calculationbaseID = calculationbase.ID) LEFT OUTER JOIN Sanji_Database.Sanji_admin.offerarticles ON (calculation.offerarticleID = offerarticles.offerartID) LEFT OUTER JOIN Sanji_Database.dbo.article ON (offerarticles.articleID = article.ID) LEFT OUTER JOIN Sanji_Database.Sanji_admin.offerdata ON (offerarticles.offerID = offerdata.ID) LEFT OUTER JOIN Sanji_Database.dbo.suppliers ON (offerdata.customerID = suppliers.ID)"+condition

condition innehåller resultatet från koden ovanför denna kodbit.

ett exempel som fungerar är då jag söker efter numret 123456, anger jag 1 i första rutan och 6 i sista så får jag fram resultatet, men anger jag ett nummer i någon av de 4 mellersta textboxarna så hittar den ingenting.

går det inte att plocka ut andra tecken än första och sista kanske?

Mvh

Medlem sedan juli 2009355 inlägg
#2

behövs förtydligande eller tillsnyggande av koden jag lagt upp så fixar jag det!

Medlem sedan juni 200032 967 inlägg
#3

Då kan du ju börja med det. Vi kan inte läsa din SELECT-fråga.

Medlem sedan juni 200032 967 inlägg
#4

Och så kan du ju berätta hur den färdiga condition ser ut - ännu hellre den helt färdiga sql-frågan.

Medlem sedan juli 2009355 inlägg
#5

hela sql-frågan ser ut så här:


SELECT calculation.costcarrier AS [description],
 calculation.supplierID AS [calcsupplierID],
 calculation.pieces AS [calcpieces],
 calculationbase.costcarrier AS [costcarrier],
 article.articlenr AS [articlenumber],
 offerdata.number AS [offernumber],
 offerdata.objectreference AS [reference],
 offerdata.responsibleID AS [offerresponsibleID],
 offerdata.responsibleproductionID AS [responsibleproduction],
 offerdata.deliverydate,
 suppliers.suppliername AS [customername]
  FROM Sanji_Database.Sanji_admin.calculation
 LEFT OUTER JOIN Sanji_Database.Sanji_admin.calculationbase ON (calculation.calculationbaseID = calculationbase.ID)
 LEFT OUTER JOIN Sanji_Database.Sanji_admin.offerarticles ON (calculation.offerarticleID = offerarticles.offerartID)
 LEFT OUTER JOIN Sanji_Database.dbo.article ON (offerarticles.articleID = article.ID)
 LEFT OUTER JOIN Sanji_Database.Sanji_admin.offerdata ON (offerarticles.offerID = offerdata.ID)
 LEFT OUTER JOIN Sanji_Database.dbo.suppliers ON (offerdata.customerID = suppliers.ID)
 WHERE substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 5),(len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 5)) =1 
AND  substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 4),(len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 4)) =2 
AND  substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 3),(len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 3)) =3 
AND  substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 2),(len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 2)) =4 
AND  substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 1),(len(Sanji_Database.Sanji_admin.offerdata.objectreference) - 1)) =5 
AND  substring(Sanji_Database.Sanji_admin.offerdata.objectreference, (len(Sanji_Database.Sanji_admin.offerdata.objectreference)) ,(len(Sanji_Database.Sanji_admin.offerdata.objectreference))) =6

taget från en sqlquery jag gjorde direkt i sqlserver management studio.

om man tar bort alla villkor förutom det första och sista så fungerar det.

Medlem sedan mars 20034 471 inlägg
#6

Sanji skrev:

ett exempel som fungerar är då jag söker efter numret 123456, anger jag 1 i första rutan och 6 i sista så får jag fram resultatet, men anger jag ett nummer i någon av de 4 mellersta textboxarna så hittar den ingenting.

Om jag förstår det rätt så vet du att du har en sträng som är 6 lång och du vill kunna söka på specifik position i den?

Då borde din villkorsbyggare skrivas något liknande (med reservation för att asp.net och C# inte är mitt område...):

int numberofconditions = 0;
string matchStr = "";
if (searchtbox1.Text != "") {
   matchStr += searchtbox1.Text;
}
Else {
   matchStr += "_";
}
if (searchtbox2.Text != "") {
   matchStr += searchtbox2.Text;
}
Else {
   matchStr += "_";
}
if (searchtbox3.Text != "") {
   matchStr += searchtbox3.Text;
}
Else {
   matchStr += "_";
}
if (searchtbox4.Text != "") {
   matchStr += searchtbox4.Text;
}
Else {
   matchStr += "_";
}
if (searchtbox5.Text != "") {
   matchStr += searchtbox5.Text;
}
Else {
   matchStr += "_";
}
if (searchtbox6.Text != "") {
   matchStr += searchtbox6.Text;
}
Else {
   matchStr += "_";
}
string condition = " WHERE Sanji_Database.Sanji_admin.offerdata.objectreference LIKE ''" + matchStr + "''''";

Det här genererar en SQL-fråga vars WHERE-del innehåller:

--- Om inga textboxar fylldes i: 
WHERE
   Sanji_Database.Sanji_admin.offerdata.objectreference LIKE '______';  

--- Om textbox2 och 4 fylldes i (med 5 och 6 resp): 
WHERE
   Sanji_Database.Sanji_admin.offerdata.objectreference LIKE '_5_6__';

Varje '_' (underscore) matchar ETT godtyckligt tecken.

Medlem sedan juli 2009355 inlägg
#7

vad skönt om man kan göra så där! jag ska testa lite senare idag när jag har tid!

Medlem sedan juli 2009355 inlägg
#8

härligt, det fungerar! men jag har dock ett problem, om jag nu vill kunna spara värden i det fältet som ibland är mindre än 6 tecken långt, hur kommer jag runt det? går det att spara in "mellanslag" framför tecken så att värdet blir 6 tecken långt, eller finns det något annat sätt? problemet blir ju att det inte går att söka bland alla poster om det finns poster med färre tecken än 6.

Mvh

Medlem sedan juli 2009355 inlägg
#9

kan jag kanske använda mig av substring om jag gör så här:

[][2][][3][][2]

säg att jag vill ha ut värden baserat på vilken position det första tecknet kommer på. sitter det en tvåa i andra textboxen som ovan, så söker den på de 5 sista tecknen. är det tomt fram till 4:e textboxen, så söker den på de tre sista tecknen.

om jag använder en substring för att hämta ut antalet tecken, kan jag då köra LIKE på det värdet jag fått ut?

Medlem sedan mars 20034 471 inlägg
#10

Sanji skrev:

härligt, det fungerar! men jag har dock ett problem, om jag nu vill kunna spara värden i det fältet som ibland är mindre än 6 tecken långt, hur kommer jag runt det? går det att spara in "mellanslag" framför tecken så att värdet blir 6 tecken långt, eller finns det något annat sätt? problemet blir ju att det inte går att söka bland alla poster om det finns poster med färre tecken än 6.

Om ditt värde inte alltid är sex tecken kan du använda ett annat wildcard i SQL '%', betyder 'vilket/vilka tecken som helst, 0-N stycken'. Beroende på hur du vill matcha dina sex textboxar om värdet kan vara längre eller kortare än sex tecken får du omformulera din villkorssats därefter.

Om villkoren ska matcha de sista tecknen i strängen kan du t.ex ändra till:

int numberofconditions = 0;
string matchStr = "";
if (searchtbox1.Text != "") {
   matchStr += searchtbox1.Text;
}
if (searchtbox2.Text != "") {
   matchStr += searchtbox2.Text;
}
Else if (matchStr != "") {
   matchStr += "_";    -- Får wildcard "ett tecken" bara om tidigare box fyllts i.
}
if (searchtbox3.Text != "") {
   matchStr += searchtbox3.Text;
}
Else if (matchStr != "") {
   matchStr += "_";
}
if (searchtbox4.Text != "") {
   matchStr += searchtbox4.Text;
}
Else if (matchStr != "") {
   matchStr += "_";
}
if (searchtbox5.Text != "") {
   matchStr += searchtbox5.Text;
}
Else if (matchStr != "") {
   matchStr += "_";
}
if (searchtbox6.Text != "") {
   matchStr += searchtbox6.Text;
}
string condition
if (matchStr != "") {
    condition = " WHERE Sanji_Database.Sanji_admin.offerdata.objectreference LIKE ''%" + matchStr + "''";
}

Det här genererar en SQL-fråga vars WHERE-del innehåller:

--- Om inga textboxar fylldes i: 
WHERE  -- inget mer eftersom inget villkor då satts
  

--- Om textbox2 och 4 fylldes i (med 5 och 6 resp): 
WHERE
   Sanji_Database.Sanji_admin.offerdata.objectreference LIKE '%5_6__';

På motsvarande sätt kan du lätt matcha de första tecknen istället genom att ha % sist, eller - genom att ha % både före och efter söksträngen - matcha mot sifferserie någonstans i strängen.

Medlem sedan juli 2009355 inlägg
#11

tack så mycket för all hjälp! jag börjar förstå hur detta fungerar nu :) nu funkar allt prima!

Mvh

266 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
121 ms — deklarationer (db)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)