Just nu i M3-nätverket
Jump to content

Behöver loopa DataReader flera gånger


Anders Mejner

Recommended Posts

Anders Mejner

Hej,

 

jag håller på att lära mig ASP.NET och portar en ganska stor applikation från ASP 3.0 till ASP.NET 2.0. Tabeller med rader i miljoner, tabellen som det rör sig om nedan har cirka 300 000 rader, växer med några tusen per dygn.

 

Jag _måste_ loopa igenom ett record set två gånger, det finns tyvärr ingen annan lösning.

 

Hur gör jag det bäst i ASP.NET? Jag kan ju köra SQL:en två gånger (dåligt) och jag kan ju göra en DataAdapter som jag kan börja om från position 0 med, typ movefirst (mindre dåligt).

 

Finns det några andra lösningar jag bör beakta?

 

Link to comment
Share on other sites

Förklara gärna varför du måste loopa igenom den två gånger så kanske man kan se en annan lösning på problemet som du missat.

 

Link to comment
Share on other sites

Anders Mejner

Bristande datamodell som jag inte är ansvarig för och som _inte går_ att ändra.

 

Just den här funktionen avänds inte speciellt ofta och hela systemet har ganska låg användning (inga publika användare). Viktigast är att det går snabbt på en gång, skalbarhet är inte lika viktigt. Systemet har bara ca 150 inloggningar per dag.

 

Men pga av bristande datamodell kan vi faktiskt inte ändra i datamodellen hur gärna vi än vill. I framtiden kommer dock detta problem att fasas ut. Så om tio år slipper vi loopa två gånger... :-/

 

Link to comment
Share on other sites

Anders Mejner

Vi måste använda summor från första loopningen. Tyvärr kan vi inte summera i SQL-satsen eftersom det står i SQL:en vad vi ska summera, och det på ett icke "join-bart" sätt.

 

Om jag nu inte har missat att man kan manipulera tabellnamn beroende på värden i annan kolumn i annan tabell i SQL:en.

 

Link to comment
Share on other sites

Ok, ni får inte ändra i datamodellen, men finns det ingen möjlighet att lägga till stored procedures, så du kan lösa detta på den sidan?

Ett annat alternativ är förstås att lagra datan från första loopen i en lista av någon väl vald typ och använda denna vid senare behov av dataåtkomsten från queryn. Effektiviteten, minnesvis, av detta beror förstås på hur mycket data det handlar om.

 

Link to comment
Share on other sites

Anders Mejner

Vi får men kan inte... Data kan inte kopplas på rätt sätt.

 

Lista känns bra, jag får läsa på lite om olika list-typer i asp.net.

 

SP kör vi med överallt, kan man loopa ett RS i SP? Vore suveränt.

 

 

Link to comment
Share on other sites

SP kör vi med överallt, kan man loopa ett RS i SP?

Japp, du använder cursors till detta. Här får du ett kort exempel, men behöver du ett mer specifikt exempel så säg till.

 

/* Deklarera variablerna som representerar fälten du tänker hämta */
DECLARE @Data1 int
DECLARE @Data2 int

/* Skapa din cursor efter önskad query */
DECLARE cur CURSOR FOR SELECT data1,data2 FROM Tabell

/* Öppna cursorn för läsning */
OPEN cur

/* Hämta data från första raden och lägg in i dina variabler */
FETCH NEXT FROM cur INTO @Data1,@Data2

/* Påbörja loopen */
WHILE @@FETCH_STATUS = 0
BEGIN
/* Här gör du sedan saker med @Data1 och @Data2, ex. skapar en ny
    query, eller summerar en tredje variabel, or whatever */

/* Hämta nästa rad */
FETCH NEXT FROM cur INTO @Data1,@Data2
END

/* Stäng och frigör minne för cursorn */
CLOSE cur
DEALLOCATE cur

 

I loopen skulle du alltså kunna konkatenera ihop en query-sträng som du sedan efter loopen exekverar med sp_executesql

 

Link to comment
Share on other sites

Anders Mejner

Ja det gick ju bra. Problemet är bara att jag skickar in XML i SP:n för att göra en SELECT * FROM Tabell WHERE id IN(id, id, id).

 

BEGIN

SET NOCOUNT ON
DECLARE @DocHandle int
EXEC sp_xml_preparedocument @DocHandle OUTPUT, @matpunkter

SELECT 
Data1
...
FROM Tabell
...
JOIN OPENXML (@DocHandle, '/ROOT/tabell',1) WITH (id int) AS x ON Tabell.id = x.id
WHERE
...
ORDER BY id DESC
EXEC sp_xml_removedocument @DocHandle 

 

Jag vet inte vad jag ska stoppa in den "extra XML"-koden i cursorn...

 

Kanske enklare med en lista, förslag på lista? Eller möjligtvis lösning på XML-problemet? Det går ju iofs att lösa genom en temporär-tabell också.

 

Link to comment
Share on other sites

Jag har dessvärre inte börjat nyttja XML-möjligheterna i SQL Server 2005 så inget förslag på lager där tyvärr.

 

Förslag på lista, tja det beror på hur många fält du skall hämta i första queryn samt vilken typ av sökningar, sorteringar osv. du kommer behöva göra. Net 2.0 har ju en enastående ny uppsättning listor i System.Collections.Generic

 

En vanligt använd generisk lista är List<T> där du skulle kunna lägga in element av en egen struct som representerar en post i tabellen.

 

Först en struct som representerar datan ur en rad i tabellen

public struct DBData 
{
	public int ID;
	public string Field1, Field2;
}

 

Sedan skapar du en generisk lista med denna typ som element

List<DBData> lista=new List<DBData>();

och i din första loop lägger du till elementen med

DBData data=new DBData();
data.ID=dr.GetInt32(0);
data.Field1=dr.GetString(1);
data.Field2=dr.GetString(2);
lista.Add(data);

 

I övrigt kan du se i dokumentationen vilka metoder du har tillgång till för List<T>

 

[inlägget ändrat 2008-01-22 11:14:42 av Anjuna Moon]

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...