it-swarm.com.de

Die NVARCHAR-Zeichenfolge (MAX) scheint 6326 Zeichen zu haben, druckt jedoch nicht alle

Ich schreibe eine gespeicherte Prozedur, um die gespeicherte Prozedur des Systems sp_send_dbmail Zum Senden einer HTML-E-Mail zu verwenden. Ich habe dieses Verfahren bereits verwendet, bin jedoch noch nicht auf dieses Problem gestoßen. Ich verwende die erstellte Erstellungsmethode hier

Aus dem Internet glaube ich, dass NVARCHAR(MAX) maximal 2 147 483 647 Zeichen enthalten sollte ( ref )

Wenn ich jedoch meine Ausgabe erstelle, wenn ich die Ausgabe PRINT, wird nicht die vollständige Zeichenfolge zurückgegeben.

Ich habe mein SQL separat getestet und dies kehrt wie erwartet zurück.

Natürlich habe ich einen Fehler, aber kann jemand zeigen, was es ist, bitte!

Das Skript lautet:

Declare @RawPart varchar(30);
Declare @PO varchar(30);
Declare @NL varchar(12)='<br/>';
DECLARE @BodyHTML  NVARCHAR(MAX) ;
Declare @SubjectText varchar(200);
Declare @StaffEmail varchar(50);
Declare @MrpDate varchar(12);


Set @MrpDate=(Select convert (varchar(12),[SnapshotDate],103) from [dbo].[MrpReqCtl] )

set @StaffEmail='[email protected]';
set @SubjectText ='Schedule Update from MRP Email';
Set @PO='106277';
Set @RawPart=(Select Distinct  MStockCode From dbo.PorMasterDetail Where [email protected] and LineType=1)


--N'<p>Attention From the Mrp run '[email protected]+N'</p><p>Has Detected Changed to the following Schedules</>'
----Define Customer Schedule Table
--         +
Set @BodyHTML=      N'<H1>Customer Schedules</H1>' +
                    N'<table border="1">' +
                    N'<tr><th>Sales Order</th><th>Line</th><th>Ship Date</th><th>Customer</th><th>Stockcode</th><th>Os Qty</th><th>Status</th>'

--Stage 2 Customer Order Details Table
                     +cast( (Select SalesOrder, SalesOrderLine, convert(varchar(12),MLineShipDate,103) as DispatchDate
                                , Customer,rtrim(StockCode)+' - '+ rtrim(F.StockCodeDesc) ,cast(OutstandingQty as int) OutstandingQty
                                ,Case When MLineShipDate<datediff(d,0,getdate())  Then 'Arrs' else '' end as Status 
                                From [dbo].[CHCIW_ForwardOrders] F
                                Where F.StockCode IN (
                                                        Select BC.TopLevel
                                                        FROM         dbo.K3_vwBOMCosting BC
                                                        inner Join dbo.InvMaster I On BC.StockCode=I.StockCode
                                                        Where [TopLevel] like 'MG%' and [email protected] )
                                        and MLineShipDate<dateadd(m,3,datediff(d,0,getdate()) )
                                Order By MLineShipDate
                                For xml Path('tr'), Type) as nvarchar(max))+  N'</table>' ;
Set @BodyHTML=rtrim(@BodyHTML)

Print len(@BodyHTML)
Print @BodyHTML

Die Ausgabe lautet jedoch:

6326

<H1>Customer Schedules</H1><table border="1"><tr><th>Sales Order</th><th>Line</th><th>Ship Date</th><th>Customer</th><th>Stockcode</th><th>Os Qty</th><th>Status</th><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>5</SalesOrderLine><DispatchDate>30/10/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>249</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>177</SalesOrderLine><DispatchDate>10/11/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>846</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>7</SalesOrderLine><DispatchDate>10/11/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>468</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>179</SalesOrderLine><DispatchDate>17/11/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>9</SalesOrderLine><DispatchDate>17/11/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>468</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>181</SalesOrderLine><DispatchDate>24/11/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>11</SalesOrderLine><DispatchDate>30/11/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>720</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>183</SalesOrderLine><DispatchDate>01/12/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>41</SalesOrderLine><DispatchDate>07/12/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>1224</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>185</SalesOrderLine><DispatchDate>08/12/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>43</SalesOrderLine><DispatchDate>14/12/2017</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>252</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>187</SalesOrderLine><DispatchDate>15/12/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status>Arrs</Status></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>189</SalesOrderLine><DispatchDate>22/12/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>7020</OutstandingQty><Status/></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>191</SalesOrderLine><DispatchDate>29/12/2017</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>10920</OutstandingQty><Status/></tr><tr><SalesOrder>010879</SalesOrder><SalesOrderLine>45</SalesOrderLine><DispatchDate>04/01/2018</DispatchDate><Customer>BORG02</Customer>MG16311504501 - VW 1.0L EU6ZD Machined -1565<OutstandingQty>252</OutstandingQty><Status/></tr><tr><SalesOrder>010158</SalesOrder><SalesOrderLine>193</SalesOrderLine><DispatchDate>05/01/2018</DispatchDate><Customer>BORG02</Customer>XXXXXXXXX507 - SOME DECRIPTIVE TEXT XXXXX<OutstandingQty>10920</OutstandingQty><Status/
5
Ian W

Dies ist eine Einschränkung dessen, was auf der Registerkarte "Nachrichten" entweder über PRINT oder RAISERROR angezeigt werden kann. Sie können entweder 4000 Zeichen von NVARCHAR Daten oder 8000 Zeichen von VARCHAR Daten anzeigen.

Es gibt einige Möglichkeiten, dies zu umgehen, z. B. das Aufteilen des Strings in Blöcke, die innerhalb dieser Grenzen über ein CURSOR funktionieren. Doch wenn:

  • sie haben weniger als 8001 Zeichen (was Sie tun), [~ # ~] und [~ # ~]
  • diese Zeichenfolge enthält keine Zeichen, die nicht in die in der Standardkollatierung der Datenbank angegebene Codepage passen

dann könnten Sie einfach den String in VARCHAR(8000) konvertieren:

PRINT CONVERT(VARCHAR(8000), @BodyHTML);

Zum Beispiel:

DECLARE @String NVARCHAR(MAX) = N'A'
    + REPLICATE(CONVERT(NVARCHAR(MAX), N'_'), 7998)
    + N'Z123';

PRINT CONVERT(VARCHAR(MAX), @String);

Wenn Sie dies ausführen und dann die Registerkarte "Nachrichten" aktivieren, sollten Sie eine Zeile haben, die mit "A___" beginnt, dann viele weitere "_" und dann mit "___Z" endet. Sie sollten die "123" nicht sehen (da dies die Zeichen 8001 - 8003 sind). Wenn Sie den Cursor am Ende dieser Zeile platzieren (rechts neben dem "Z"), sollten die Werte "Col" und "Ch" in der blauen Leiste am unteren Rand von SSMS beide 8001) sein.

P.S. Die Verwendung von VARCHAR(8000) oder VARCHAR(MAX) sollte in Ordnung sein. Ich habe keinen Unterschied im Verhalten zwischen ihnen gesehen für dieses spezielle Szenario.


Zur Verdeutlichung des Datentyplimits: 2.147.483.647 ist die maximale Anzahl von Bytes, die in einer NVARCHAR(MAX) - Spalte gespeichert werden kann. Da NVARCHAR UTF-16-Daten sind, werden entweder 2 oder 4 Bytes pro "Zeichen" verwendet, wobei die am häufigsten verwendeten Zeichen in die 2-Byte-Gruppe fallen. Das heißt, Sie können höchstens HÄLFTE dieses Byte-Limits als Zeichen erhalten, wenn alle Zeichen von der 2-Byte-Variante sind. Wenn es sich bei einem Zeichen um eine 4-Byte-Variante handelt, kann die Gesamtzahl der Zeichen verringert werden, da sich die maximale Anzahl der Bytes nicht ändert.

Außerdem ist die Dokumentation insofern falsch, als sie besagt, dass "2.147.483.647 die maximale Anzahl von Zeichen ist". Ich werde dafür eine Korrektur einreichen.

9
Solomon Rutzky