我正在尝试在 T-SQL 中连接字符串,例如
'This is a test ' + CHAR(13) + CHAR(10) + ' string'
当字符串很长时(我不知道限制),我得到一个错误:
您的 SQL 语句的某些部分嵌套得太深。重写查询或将其分解为更小的查询。
我该如何解决这个问题?SQL 语句是如何“嵌套”的?
我应该切换到 0x 吗????如果字符串长度超过某个值,则表示法?
这个问题在 10 年前被问到
没有得到满意的答复。
编辑
要插入的总字符串(带有连接和 ':s)是 369711 个字符长。
有 6301 个
char(13)
和相同的实例char(10)
。有 19050 个实例
+
,不一定都用作连接运算符。
这可能取决于“太长”的含义:
长度:如果您的意思是许多字符的字符串,那么尝试将其中一些转换为一种
MAX
类型(即NVARCHAR(MAX)
或VARCHAR(MAX)
)。例如:连接:如果您的意思是涉及许多连接的操作,那么肯定有一个最大数量可以在单个语句中完成。我前段时间对此进行了测试,并打算在博客上讨论它,但分心了;-)。我刚刚回顾了我的测试,虽然有几种不同的连接方式,但最简单的方式(这就是你正在做的)每个语句的限制约为 3300。我说“大约” 3300 是因为它会根据与内存相关的其他一些因素而有所不同。有时我可以得到 3310,然后我尝试了 3311,它可以工作,再试一次,它会失败,用 3310 再试一次,它会失败,用 3309 再试一次,它就可以了。
如果你有超过这个数量,那么你别无选择,只能将操作分成多个步骤(即多个
SET
/SELECT
语句)。虽然,这里达到最大值的错误是:而且您并没有完全做到这一点,因此在您进行更多测试或至少提供错误号之前还不能完全确定。在任何一种情况下,您都可以通过将“\r”和“\n”组合成单个变量或
VARBINARY
文字来减少串联的数量。以下示例显示两种方法产生相同的输出:该变量的好处是它更短,这有助于使大型脚本更具可读性而不是那么大。但是,您不能突出显示一条或多条随机行并执行,除非您还突出显示
DECLARE
但可能并不总是有效。文字的好处VARBINARY
是您可以轻松执行随机分组的语句,或将语句移动到该脚本的其他脚本/部分,而不必担心忘记DECLARE
. 在任何一种情况下,这可能会减少数百个串联(假设您已经有大约 3300 个串联),但如果您获得需要数百个串联的字符串值,它不会阻止错误。也很可能有一种不同和/或更简单的方法来完成您最终尝试完成的工作,而不依赖于串联。因此,如果您可以更新问题以指定您首先这样做的原因会有所帮助:-)。
给定每组“CR”+“LF”的三个串联(即是一
+ CHAR(13)
、+ CHAR(10)
二和+ '...'
第三),即有 18,903 个串联。是的,这有点超过 3300 ;-)。好的。但为什么?你实际上从中获得了什么?嵌入式 CRLF 非常适合插入。
还:
VARCHAR
还是NVARCHAR
?在问题的示例中,它只是VARCHAR
,但在对该问题的评论中,您给出了将VARBINARY
文字转换为 的示例NVARCHAR
。在任何一种情况下,执行我上面提到的两种方法中的任何一种来减少每个 CRLF 的两个部分之一的连接都无济于事,因为这仍然会给您留下 12,602 个连接。所以,你有两个选择:
使用替换/转义序列在对该问题的评论中,Martin Smith 建议使用
{crlf}
. 我的偏好是以下之一:CHAR(31)
:这是不可打印的“单位分隔符”字符。它只是一个字节,不太可能出现在您的字符串数据中,如果您不小心更改了编码,也不会转换为其他内容。不幸的是,它的可读性不是很好,因为它甚至不会显示为空格,因此它分隔的单词之间似乎没有任何内容。'\n'
:这是几乎通用的“换行符”转义序列。这是两个字节,绝对更具可读性。无论哪种情况,您只需
INSERT INTO Schema.Table (Column) VALUES (REPLACE(....));
将整个字符串转换为
VARBINARY
: 这会产生一个非常便携的单行值。这是不可读的,但也不会有任何意外的字符转换,您可以使用标准的 ANSI/代码页 1252 文件编码,而您需要使用 UTF-8(带签名/BOM)或 Unicode / UTF-16(带签名 / BOM)用于文件编码,如果字符串数据是 Unicode /NVARCHAR
.您在对该问题的评论中提到了有关拥有字节数组的内容。如果数据的来源是 .NET,那么字符串数据已经是 UTF-16 LE(即
NVARCHAR
),所以只要做INSERT INTO Schema.Table (Column) VALUES (0x{hex_from_byte[]});
就可以了。如果目标是一VARCHAR
列,那么您可以:Encoding.GetEncoding(1252).GetBytes(_StringVariable)
INSERT INTO Schema.Table (Column) VALUES (CONVERT(NVARCHAR(MAX), 0x{hex_from_byte[]}));
. 请注意,我们正在转换为,NVARCHAR
因为十六进制表示是 UTF-16 LE。函数的返回值将在插入列时CONVERT
隐式转换为。VARCHAR