【问题标题】:how to bypass the 65535 character limit in a select statement using "FOR XML"如何使用“FOR XML”绕过选择语句中的 65535 个字符限制
【发布时间】:2015-09-19 04:18:35
【问题描述】:

我知道文本数据类型(以及 Varchar(MAX))的 65535 截断。我也知道可以设置为无限制的 XML 输出。我有一个将 XML 字符串存储在名为 GEOM 的 varchar(MAX) 列中的表。

我的问题是geom列中的xml sn-p可以超过65535个字符。我想既然它是 XML,而且无论如何我都在我的代码中创建一个 XML 输出,为什么不直接构建 xml 并将其发送出去,因为我可以将 XML 输出设置为“无限制”。

USE [buyerhero]
GO
/****** Object:  StoredProcedure [dbo].[GEOIDKMLCOUNTY]    Script Date: 9/17/2015 11:18:55 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GEOIDKMLCOUNTY] @CountyID nvarchar(30)
AS
DECLARE @kml XML
DECLARE @kmlout NVARCHAR(MAX)

SELECT @kml = CAST('<?xml version="1.0" encoding="utf-16" ?>' + 
'<kml xmlns="http://www.opengis.net/kml/2.2">' + 
'<Document>' + 
'       <Style id="Licensed">
            <LineStyle>
                <color>ff000000</color>
                <width>2</width>
            </LineStyle>
            <PolyStyle>
                <color>1e1400FF</color>
                <fill>1</fill>
                <outline>1</outline>
            </PolyStyle>
        </Style>
        <Style id="NotLicensed">
            <LineStyle>
                <color>ff000000</color>
                <width>2</width>
            </LineStyle>
            <PolyStyle>
                <color>1e14F0FF</color>
                <fill>1</fill>
                <outline>1</outline>
            </PolyStyle>
        </Style>
        <Style id="Other">
            <LineStyle>
                <color>ff000000</color>
                <width>2</width>
            </LineStyle>
            <PolyStyle>
                <color>1e007800</color>
                <fill>1</fill>
                <outline>1</outline>
            </PolyStyle>
        </Style>' +
(
            select 
                '<![CDATA[{"County":"' + r.CountyName + ', ' + r.State + '", "GEOID": "'+t.GEOID+'"}]]>' as Name,
                case t.IsLicensed
                    when 2 then '#Licensed'
                    when 1 then '#NotLicensed'
                    else '#Other'
                end as StyleURL, 
                cast(replace(geom,'"','') as xml) as Geometry
        from Tracts t 
        join census_county_ref c on t.GEOID = c.GEOID
        join FIPSCountyCode r on c.STATEFP = r.StateANSI and c.COUNTYFP = r.CountyANSI
        where r.CountyID = @CountyID
FOR XML PATH(''), ELEMENTS) + '</Document></kml>' AS XML)
--
-- Perform replacement of &lt; and &gt; with < and > respectively
--
SET @kmlout = REPLACE(REPLACE(CAST(@kml AS NVARCHAR(MAX)), '&lt;', '<'), '&gt;', '>')
SET @kmlout = REPLACE(@kmlout, 'utf-16', 'utf-8')
--
-- Return kmlout
--
SELECT @kmlout

尽管 geom 列是 xml 并且我使用的是 varchar(max) cast(replace(geom,'"','') as xml),但该字段仍然会被截断。

如何“取消截断”字段以便输出 XML?

谢谢。

【问题讨论】:

  • 那么文本数据类型不应该用于任何事情。十多年来,它已被弃用,取而代之的是 varchar(max)。不确定您在哪里发现 varchar(max) 的限制为 65,535 个字符。实际限制为 2GB(2^31-1 字节),相当于 80 份《战争与和平》,几乎可以满足您可能通过的任何内容。 msdn.microsoft.com/en-us/library/ms176089.aspx
  • 也就是说,您可以使用 XML 数据类型而不是字符数据类型。它具有验证您的 xml 中没有垃圾的好处。 :)
  • 您没有任何可运行的东西,也没有说您是如何知道有截断的,但是,您是否可能只是在 SQL Server Management Studio 中看到非 XML 数据被截断为 65535 个字符?在 SSMS 工具|选项中有一个设置,但我认为 65535 是最大值。

标签: sql sql-server xml


【解决方案1】:

使用 concat 函数代替 + 运算符。加号运算符限制为 8000 字节。

SELECT @kml =CAST(concat('your xml', the select,'the other xml')

【讨论】:

  • 那是我的问题。谢谢。我很欣赏这个主意。它帮助我获得了所需的输出。
猜你喜欢
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 2018-10-14
  • 2011-05-03
相关资源
最近更新 更多