簡體   English   中英

T-SQL 長動態查詢被中斷

[英]T-SQL long dynamic query gets cut off

我正在處理將生成 html 頁面的查詢。 一開始,該頁面只是一個帶有標簽的簡單 HTML 表格。 標簽稍后將被處理並替換為子查詢(主要是標量函數)。 這種方式將 HTML 與替換標簽組合在一起,將使用 sp_executesql 執行以生成最終的 html。

該 HTML 的摘錄:

...Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Firma:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Companyname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Anrede:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Anrede,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Vorname:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Firstname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Nachname:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Lastname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 1...

現在,我知道如果我使用 nvarchar(max) 以外的任何東西,我的結果將被截斷為 4000,所以我將所有函數結果轉換為 nvarchar(max),我的結果不止於此,但仍然奇怪地從內部截斷。

因此,當我運行一個示例腳本時,我得到了9043個字符作為結果(使用 len 函數),結果被截斷(注意:從內部,接近尾聲但不是尾聲)。 現在我追加一個字母,結果是9044 但如果我在最終結果前 100 個字符添加那個字母,結果仍然是9043 ??

這有什么問題? 為什么我不能構建一個長的 T-SQL 查詢來執行預期的結果?

謝謝

更新 1

因為原始解決方案太長,無法在此處顯示,所以我將嘗試顯示較小的版本,只是為了讓您了解我是如何做到的以及我最終用它做了什么:

declare @BodyTXT nvarchar(max)
set @BodyTXT =  N'select ''some string' + (select cast('result of some function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another AAA string' + (select cast('result of antoher function' as nvarchar(max))) + N''''

execute sp_executesql @BodyTXT

假設這是 LEN = 9043 個字符,現在,請注意 AAA 如果我在那里添加字符,最終結果將保持為 LEN = 9043,但如果我在最開始添加一些字符串,字符串大小將改變並增加我在那里添加的字符串。

結果將以這種方式被切斷:

some stringresult of some function another stringresult of antoher function
 another stringresult of antoher function another stringresult of antoher 
function another stringresult of antoher function another stringresult of antoher
 function another stringresult of antoher function another ...ult of antoher function

你能看到那些......幾乎在結果末尾的點它在那里我缺少應該在輸出中的其余字符串(大約 12000,我有 9043)

更新 2

因為這一切都是自動電子郵件系統的一部分,而且它是實時運行的,所以我必須找到解決方案,而我所做的就是從結果表中刪除一些樣式信息。 因此,在削減 1/3 的 html 之后,我終於得到了預期的結果,但是因為最終字符串的大小取決於客戶購買的產品數量,因為這個問題肯定會再次出現。 而且我還想知道這種行為的原因是什么以及如何克服它。

我曾經遇到過使用 += 運算符連接長字符串的問題,它會減少字符。

所以改為使用@SQL = @SQL + N'a really long text'; 已經解決了。

我知道這是一篇舊文章,但仍然是當前主題。 這只是一個僅供參考,以幫助任何在這個問題上需要幫助的人。

我剛剛遇到一個問題,我的@SqlStr(設置為 NVARCHAR(MAX))在 SP_ExecuteSQL 調用期間不斷切斷導致錯誤。

對這個長腳本所做的唯一串聯是設置為 NVARCHAR(100) 的 @TableName。

經過幾個小時的調試,問題是由@tablename引起的

似乎當使用 nvarchar(###) 而不是 NVarchar(max) 時,SQL 將其視為略有不同的數據類型,並將長字符串剪切為 4000 個字符。

要解決此問題,我必須更改 @Tablename 以匹配 nvarchar(max) 數據類型。

我在生成大型 html 輸出作為字符串時回想起類似的事情。 不記得到底是什么問題,可能是管理工作室的一些限制。 解決方法是將表生成為 xml。 以下是您可以試驗的示例。 首先生成 sql 表,然后用您的表替換“select * from (values..)”。

declare
 @baseTable xml = (select * from ( Values
   (123, 'Firma:', 'Google'),
   (123, 'Anrede:', 'NYC'),
   (123, 'Vorname:', 'John'),
   (123, 'Nachname:', 'Doe')
  ) T(CustID, property, Val)
 for XML PATH('row'), ELEMENTS XSINIL)

,@tblClass VARCHAR(100)
,@thClass VARCHAR(100) 
,@TRstyle VARCHAR(100) = 'font-size: 14px'
,@TDstyle VARCHAR(100) = 'font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold'

 SELECT @tblClass AS [@class]  
    ,@thClass AS [thead/@class]
    ,@baseTable.query(
              N'let $first:=/row[1]
                return 
                <tr> 
                {
                for $th in $first/*
                return <th>{local-name($th)}</th>
                }
                </tr>') AS thead
            ,@baseTable.query(                 
               N'for $tr in /row
                 return 
                 <tr style="{sql:variable("@TRstyle")}">
                  {
                   for $td in $tr/*
                     return <td style="{sql:variable("@TDstyle")}">{string($td)}</td>
                  }
                 </tr>') AS tbody
    FOR XML PATH('table'),TYPE

問題幾乎可以肯定是你的@BodyTXT 可能是 nvarchar(max),但你放入其中的東西不是。 通過執行 set @BodyTxt = a + b + c + d +..... ,所有的串聯都首先完成,然后立即插入您的變量中。 這很好,直到某處 SQL 由於類型強制(或其他原因)決定最新位的結果是 nvarchar(默認長度 4000),而不是 nvarchar(max),並截斷其中的一些。

您可以檢查整個查詢,檢查所有內容並查找問題,但將串聯分解為足夠小的位可能會更簡單,就像這樣。

declare @BodyTXT nvarchar(max)

set @BodyTXT =  N'select ''some string' + (select cast('result of some function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max)))

set @BodyTXT = @BodyTXT +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +

set @BodyTXT = @BodyTXT +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another string' + (select cast('result of antoher function' as nvarchar(max))) + 
N' another AAA string' + (select cast('result of antoher function' as nvarchar(max))) + N''''

LEN將修剪尾隨空格, DATALENGTH不會。 select len('a '), datalength('a ') 因此,如果您將該字母插入 100 個字符,那么最后一個字符就是一個空格。 只需使用DATALENGTH ,您應該會得到預期的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM