SQL游标性能,拆分多个字符串时内存异常

SQL Cursor performance, memory exception while splitting multiple strings

我已经完成游标查询以在文章描述 (varchar(max)) 中拆分 html table 以将其实现为属性 (#test) table。并将其添加到另一个游标中以循环整个文章 table 约 5000 篇文章。

到目前为止,查询工作正常(预期的插入结果),但是...

错误描述: 大约 2 分钟后,我收到以下消息。

Error executing batch. Error Message: Exception of type 'System.OutOfMemoryException

系统信息

问题:
你能给我一个避免内存问题的方法吗?

我知道游标通常只用作最后一个选项,但我还是新手SQL,不知道如何以更好的方式写这个。

也没有要求查询非常高效的值,因此可以慢慢来。

谢谢

查询:

Create TABLE #test
(
    [cArtNr] varchar(100),
    kArtikel int,
    attribute varchar(100),
    Value varchar(100)
)  

DECLARE @S varchar(max),
  @Split char(1),
  @Split2 char(1),
  @Split3 char(1),
  @y varchar(max),
  @X xml,
  @1 varchar(100),
  @2 varchar(100),
  @3 varchar(100),
  @4 int;

DECLARE loop_cursor CURSOR
    FOR SELECT 
            cArtNr, kArtikel, [cBeschreibung]
        FROM 
            [mydb].[dbo].[tartikel]

OPEN loop_cursor
FETCH NEXT FROM loop_cursor;

WHILE @@FETCH_STATUS = 0
BEGIN
    FETCH NEXT FROM loop_cursor into @3,@4,@S;

 /*  ### Select Description string and cut everything outside from table tags ###*/
  Select @S
  Select @S = RIGHT(@S,LEN(@S)-CHARINDEX('<table>',@S)-6)
  Select @S = LEFT(@S,CHARINDEX('</table>',@S)-1)
  Select @S = Replace(@S,'<tr><td>','')
  Select @S = Replace(@S,'</td><td>',';')
  Select @S = Replace(@S,'</td></tr>','#')
  SELECT @S

  /* ### Split Variables ### */
Select @Split = ';',
  @Split2 = '#'

Select @S = Replace(@S,@Split2,'</s><s>')
SELECT @x = CONVERT(xml,'<root><s>' + REPLACE(@S,@Split,'</s><s>') + '</s></root>')
Select @x

DECLARE calc3 SCROLL Cursor FOR
SELECT [Value] = T.c.value('.','varchar(100)')
FROM @X.nodes('/root/s') T(c)

OPEN calc3;
FETCH NEXT FROM calc3;
    WHILE @@FETCH_STATUS = 0
        BEGIN
            FETCH NEXT FROM calc3;
            FETCH PRIOR FROM calc3
            INTO @1

            FETCH NEXT FROM calc3
            INTO @2

            Insert into #test ([cArtNr],kArtikel,attribute,Value)
            Values (@3, @4, @1, @2);
            FETCH NEXT FROM calc3;
        END
DEALLOCATE calc3;
FETCH NEXT FROM loop_cursor;
END
DEALLOCATE loop_cursor;
Select * from #test

示例字符串:

<b>Thermal Armor mit Strömungsventil Gezielter Luftstrom für optimale Wärmeableitung</b><br \><br \>TUF Thermal Armor ist mehr als eine coole Abdeckung im Camouflage-Stil: Zwei Lüfter liefern einen kräftigen Luftstrom für schnelle Kühlung. Der umkehrbare Luftstrom bläst Staub vom Kühlkörper der VRM, das Strömungsventil steuert die Luftzufuhr der Heatpipe – ideal für Systeme mit Flüssigkühlung!<br \><br \><b>Thermal Radar 2Individuelle Lüftersteuerung, Kühlung des ganzen Systems</b><br \><br \>Mit Z97 Thermal Radar 2 können Sie die Lüfter von ASUS-Grafikkarten sowie Gehäuselüfter steuern. Mehrere Sensoren auf dem Board und das mitgelieferte Thermistorkabel überwachen die Temperatur von Grafikkarten und anderen Komponenten in Echtzeit. Sie können die Lüfterdrehzahlen manuell anpassen oder mit einem Klick automatisch optimieren.<br \><br \><b>TUF ICe Die Schaltzentrale der Systemkühlung</b><br \><br \>Das TUF-Entwicklungsteam von ASUS hat einen vollkommen neuen Chip für eine unglaublich präzise Temperaturüberwachung und Lüftersteuerung geschaffen.<br \><br \>Mit dem TUF ICe können Sie sich auf die Überwachung der Temperatursensoren und Lüfterdrehzahlen verlassen – bei manuellen Einstellungen ebenso wie im Ein-Klick-Automatikmodus.<br \><br \><b>TUF-Komponenten Garantiert hart im Nehmen</b><br \><br \>- TUF 10K-Ti-Kondensatoren20 % temperaturbeständiger, 5 × längere Lebensdauer<br \>- TUF-Drosseln aus Speziallegierung: 13,6 % kühler = maximale Haltbarkeit<br \>- TUF-MOSFETs Widerstandsarme MOSFETs gemäß Militärstandard<br \>- Niedriger RDS-Durchlasswiderstand = höhere Energieeffizienz = geringere Wärmeabgabe durch die MOSFETs<br \><br \><b>Dust Defender</b><br \><b>Weniger Staub für längere Lebensdauer</b><br \><b>DRAM</b><br \><br \>Das TUF-Design schützt die rückwärtigen Anschlüsse, die Erweiterungs- und Speichersteckplätze sowie wichtige Buchsen vor Staub, der die Systemleistung beeinträchtigen kann. Ein Filter verhindert, dass der rückwärtige Lüfter Staub ansaugt. Die Dust Defender schützen vor Ablagerungen, damit Ihr PC länger leistungsfähig und stabil bleibt.<br \><br \><b>Tests auf ServerniveauSystematische Stabilitätstests</b><br \><br \>TUF bietet umfassende Lösungen an – darauf sind wir stolz. Wir testen unsere Produkte nicht isoliert, sondern betrachten die Stabilität und Haltbarkeit des Gesamtsystems. Wir unterziehen unsere Mainboards extremen Temperaturschwankungen (Thermoschockprüfung), ausgiebigen Dauertests (MTBF-Prüfung) und vielen Stabilitätstests auf Serverniveau, damit Sie sich unter allen Umständen auf Ihr TUF-Mainboard verlassen können.<br \><br \><b>5 Jahre Garantie Garantierte Zuverlässigkeit</b><br \><br \>Jedes TUF-Motherboard beruht auf Komponenten, die militärischen Anforderungen gerecht werden, und durchläuft einen Dauertest auf Serverniveau mit mehr als 7.000 Stunden an Kompatibilitätsprüfungen mit mehr als 1.000 Geräten. Auf TUF können Sie sich verlassen. Deshalb gewähren wir auf jedes Board 5 Jahre Garantie.<br \><br \><b>TUF ESD Guards Leistungsstarker ESD-Schutz für längere Lebensdauer</b><br \><br \>Elektrostatische Entladungen kommen unerwartet und können erhebliche Schäden verursachen. Der TUF-Entladungsschutz übertrifft die Anforderungen von Industriestandards um 30 % und sorgt dafür, dass alle elektrostatischen Entladungen geerdet werden – für eine längere Lebensdauer der Komponenten.<br \><br \>- Tastatur- und Mausanschlüsse: Zusätzliche Leiter auf TVS-Dioden<br \>- USB-3/2.0-Anschlüsse Suppressordioden (TVS) auf der Platine und Kondensatorschutz für Oberflächen- und DIP-Bauteile<br \>- Audioanschlüsse: Kondensatorschutz für die vorderen und hinteren Audioanschlüsse<br \>- LAN-Anschluss TVS-Dioden- und Überspannungsschutz am LAN-Anschluss gegen extreme Spannungsspitzen wie im Fall von Blitzeinschlag<br \><br \><b>Laut Medienberichten das intuitivste UEFI-BIOS</b><br \><br \>Das eleganteste grafische BIOS mit Maussteuerung ist jetzt noch ansprechender. Unerfahrene Anwender und routinierte Overclocker finden sich mit dem einfachen EZ-Modus und dem erweiterten Modus gleichermaßen zurecht.<br \><br \>MyFavorite-Liste: Tuning-Optionen und Tools schneller finden – mit MyFavorites<br \>EZ Tuning Wizard – Übertakten und RAID: Wählen Sie Ihre Hardware, und optimieren Sie die Systemleistung mithilfe leicht verständlicher Szenarien. Oder richten Sie Ihre RAID-Konfiguration auf schnellere Datentransfers aus.<br \>EZ XMP: DRAM-Leistung mit einem Klick verbessern<br \>Intuitive grafische Lüftersteuerung: Feintuning einzelner Lüfter durch Anpassung der Kurve mit der Maus<br \>Echtzeit-Hardwareüberwachung: Der aktuelle Status der wichtigsten Systemkomponenten auf einen Blick<br \><br \><b>EZ-Modus</b><br \><br \>- Lüfterprofil: Detaillierte CPU- und Gehäuselüfterwerte für sofortige Kühlung<br \>- SATA-Informationen: SATA-Informationen, um Speichergeräte einfacher zu finden<br \>- Schnelle Uhreinstellung: Uhrzeit und Datum bequem mit der Maus einstellen<br \>- EZ XMP: DRAM-Leistung mit einem Klick verbessern<br \><br \><b>Erweiterter Modus</b><br \><br \>- Shortcuts: Mit der Eingabetaste Shortcuts für häufig verwendete Einstellungen anlegen oder mit F4 einen Shortcut direkt anwählen<br \>- Notizen: Schnell und bequem Notizen rund um das BIOS machen<br \>- Änderungsprotokoll: Letzte Änderung verfolgen und Profile auf USB-Stick speichern<br \>- SATA-Anschlüsse umbenennen: SATA-Anschlüsse zur besseren Orientierung umbenennen<br \><br \><b>Der Turbo für Kreative</b><br \><br \>Wenn Sie Design im Blut haben, führt kein Weg am TUF Z97-Motherboard vorbei! USB 3.0 Boost steigert die Übertragungsgeschwindigkeit von USB auf 170 %, die SATA Express-Anschlüsse ermöglichen eine Datenübertragung mit bis zu 10 Gbit/s. Für Sie bedeutet das jederzeit zügiges Arbeiten ohne Zwangspausen, während Bilder übertragen und Dateien gespeichert oder geladen werden. Und unsere exklusive Turbo-LAN-Technologie optimiert automatisch Ihre Internetverbindung – für schnelle und reibungslose Dateitransfers. Das TUF Z97 eignet sich auch für Multi-Head-Arbeitsplätze und sorgt für absolute Stabilität – selbst bei einer Auflösung von 4K/UHD!<br \><br \><b>TUF Audio Design</b><br \><br \>TUF Audio Design optimiert nach Ihren Vorstellungen im Handumdrehen die Audioeinstellungen für Töne, Gespräche, Filme und Ihre Lieblingsmusik. Die Abschirmung, der professionelle Leitungsaufbau und die hochwertigen Komponenten sorgen für außergewöhnliche Klarheit und Klangtreue.<br \><br \>- Audio-Abschirmung Präzise Analog-digital-Trennung und stark reduzierte Interferenzen<br \>- Audioverstärker Exzellenter Klang für Kopfhörer und Lautsprecher<br \>- Schaltung gegen Knackgeräusche Vermindertes Knackgeräusch beim Start an allen Audioeingängen<br \>- Spezielle Leitungsanordnung Getrennte Schichten für den linken und rechten Kanal wahren die Qualität empfindlicher Audiosignale<br \><br \><b>Ihr PC, Ihre Welt</b><br \><br \>Die ASUS HomeCloud überwindet Grenzen. Sie können aus der Ferne auf Ihren PC zugreifen, Multimedia-Dateien streamen und alle Ihre Daten verwalten – von jedem Ort aus, unabhängig vom Speicherort. Nutzen Sie die integrierte Wake-on-WAN-Funktion, um Ihren PC mit einem Mobilgerät zu aktivieren und zu steuern – und zwar jederzeit und überall. Sie können sogar Ihre Festplatte in eine private Cloud verwandeln und sich damit von den Speicherbeschränkungen der Cloud-Dienste unabhängig machen. Mit der HomeCloud wird Ihr PC das Tor zur Ihrer Welt.<br \><br \><b>Der PC-Eigenbau war noch nie so einfach</b><br \><br \>Wir wissen, wie Sie Ihren PC montieren und nutzen. Deshalb machen wir Ihnen das Leben leichter – von der Montage über Systemeinrichtung und Monitoring bis hin zu Firmware- und Hardware-Updates. Und deshalb suchen wir stets nach neuen und interessanten Lösungen, damit der PC-Eigenbau einfach und unkompliziert ist und Spaß macht.<br \><br \><b>Montage</b><br \>Mit ASUS Q-Design geht die PC-Montage schnell und einfach vonstatten<br \><br \><b>Einstellungen</b><br \>Die ASUS AI Suite 3 ist die Schaltzentrale für alle Systemeinstellungen<br \><br \><b>Monitoring</b><br \>ASUS Push Notice überwacht den PC-Status, wenn Sie unterwegs sind<br \><br \><b>BIOS-Updates</b><br \>ASUS USB BIOS Flashback aktualisiert Ihr BIOS auch ohne montierte CPU<br \><br \><table><tr><td>ACPI-Version:</td><td>5.0a</td></tr>
<tr><td>Anzahl DisplayPort Anschlüsse:</td><td>1</td></tr>
<tr><td>Anzahl Ethernet LAN (RJ-45) Anschlüsse:</td><td>2</td></tr>
<tr><td>Anzahl HDMI Anschlüsse:</td><td>1</td></tr>
<tr><td>Anzahl USB 2.0 Anschlüsse:</td><td>4</td></tr>
<tr><td>Anzahl USB 2.0 Schnittstellen:</td><td>2</td></tr>
<tr><td>Anzahl USB 3.0 Anschlüsse:</td><td>4</td></tr>
<tr><td>Arbeitsspeicher Typ:</td><td>DIMM</td></tr>
<tr><td>Audio Kanäle:</td><td>7.1</td></tr>
<tr><td>BIOS-Speichergröße:</td><td>64 MB</td></tr>
<tr><td>BIOS-Typ:</td><td>UEFI AMI</td></tr>
<tr><td>Breite:</td><td>30,5 cm</td></tr>
<tr><td>Clear CMOS-Jumper:</td><td>Ja</td></tr>
<tr><td>CPU Ventilatorstecker:</td><td>Ja</td></tr>
<tr><td>Eingebauter Ethernet-Anschluss:</td><td>Ja</td></tr>
<tr><td>Ethernet Schnittstellen Typ:</td><td>Gigabit</td></tr>
<tr><td>Front Panel Audiostecker:</td><td>Ja</td></tr>
<tr><td>HDD Schnittstellen:</td><td>Serial ATA III</td></tr>
<tr><td>Kompatible Prozessoren:</td><td>Celeron, Core i3, Core i5, Core i7, Pentium</td></tr>
<tr><td>Komponente für:</td><td>PC</td></tr>
<tr><td>Motherboard Chipsatz:</td><td>Intel Z97</td></tr>
<tr><td>Motherboard Chipsatz Familie:</td><td>Intel</td></tr>
<tr><td>Motherboardformfaktor:</td><td>ATX</td></tr>
<tr><td>Parallele Verarbeitungstechnologie:</td><td>Quad-GPU CrossFireX, Quad-GPU SLI</td></tr>
<tr><td>PCI-Express x16 (Gen 2.x)-Anschlüsse:</td><td>1</td></tr>
<tr><td>PCI-Express x16 (Gen 3.x)-Anschlüsse:</td><td>2</td></tr>
<tr><td>PCI-Express x16-Slots:</td><td>3</td></tr>
<tr><td>PCI-Express x1-Slots:</td><td>3</td></tr>
<tr><td>Prozessorfamilie:</td><td>Intel</td></tr>
<tr><td>Prozessorsockel:</td><td>Socket H3 (LGA 1150)</td></tr>
<tr><td>RAID Level:</td><td>0, 1, 5, 10</td></tr>
<tr><td>RAM-Speicher maximal:</td><td>32 GB</td></tr>
<tr><td>S/PDIF aus Stecker:</td><td>Ja</td></tr>
<tr><td>S/PDIF-out Anschluss:</td><td>Ja</td></tr>
<tr><td>SATA Anschlüsse:</td><td>6</td></tr>
<tr><td>SATA III Anschlüsse:</td><td>6</td></tr>
<tr><td>Tiefe:</td><td>24,4 cm</td></tr>
<tr><td>TPM-Verbinder:</td><td>Ja</td></tr>
<tr><td>Unterstützte Arbeitsspeicher:</td><td>DDR3-SDRAM</td></tr>
<tr><td>Unterstützte Arbeitsspeichergeschwindigkeit:</td><td>1333, 1600, 1866 MHz</td></tr>
<tr><td>USB 3.0-Anschlüsse:</td><td>2</td></tr>
<tr><td>Zahl der Chassisventilatorstecker:</td><td>4</td></tr>
<tr><td>Zahl der EATX Energie Stecker:</td><td>1</td></tr>
</table>

正如@James 所建议的那样,它在客户端会更快。

但是,如果您想在 SQL 中处理,您可以使用临时 table 避免游标,并直接在结果 table.

中插入批量数据
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results

Create TABLE #Results(
     cArtNr varchar(100)
    ,kArtikel int
    ,attribute varchar(100)
    ,Value varchar(100)
)  

declare @tb table 
(
    id int identity(1,1)
   ,cArtNr varchar(100)
   ,kArtikel int
)

Declare  @MaxRec int
        ,@CurrentRec int = 1
        ,@val varchar(max)
        ,@xmlData xml
        ,@cArtNr varchar(100)
        ,@kArtikel int

Insert into  @tb(cArtNr, kArtikel)
SELECT cArtNr, kArtikel FROM tartikel

SET @MaxRec = @@ROWCOUNT

WHILE @MaxRec >= @CurrentRec 
BEGIN 

    /* Assuming tartikel has kArtikel as unique key else join both keys i.e. kArtikel & cArtNr */
    SELECT  @val = tar.cBeschreibung
           ,@cArtNr = tmp.cArtNr
           ,@kArtikel = tmp.kArtikel
    FROM tartikel tar
    JOIN @tb tmp
    ON tar.kArtikel = tmp.kArtikel
    WHERE tmp.id = @CurrentRec

    /* Assuming this parsing will cover all scenarios   */
    Select @val = RIGHT(@val,LEN(@val)-CHARINDEX('<table>',@val)-6)
    Select @val = LEFT(@val,CHARINDEX('</table>',@val)-1)
    Select @val = Replace(@val,'<tr><td>','')
    Select @val = Replace(@val,'</td><td>',';')
    Select @val = Replace(@val,'</td></tr>','#')

    SELECT @xmlData = CONVERT(xml,'<root><s>' + REPLACE(@val,'#','</s><s>') + '</s></root>')

    Insert into #Results (cArtNr,kArtikel,attribute,Value) 
    SELECT   @cArtNr
            ,@kArtikel
            ,SUBSTRING(T.c.value('.','varchar(100)'), 1, CASE CHARINDEX(';', T.c.value('.','varchar(100)')) WHEN 0 THEN LEN(T.c.value('.','varchar(100)')) ELSE CHARINDEX(';', T.c.value('.','varchar(100)'))-1 END) attribute
            ,SUBSTRING(T.c.value('.','varchar(100)'), CASE CHARINDEX(';', T.c.value('.','varchar(100)')) WHEN 0 THEN 0 ELSE CHARINDEX(';', T.c.value('.','varchar(100)'))+1 END, LEN(T.c.value('.','varchar(100)'))+1 ) Value
    FROM @xmlData.nodes('/root/s') T(c)

    SET @CurrentRec = @CurrentRec + 1

END

SELECT * FROM #Results