删除或阻碍 SQL 中的"Line Continuation"



目前,我们正在对所有SQL事务使用查询聚合。我们现在希望在服务器中添加BLOB支持,这意味着我们必须将字节数组转换为字符串,这样它才能与查询一起发送。我们希望将BLOB数据作为字节数组放在服务器上,但服务器似乎漏掉了一些字符。特别是"one_answers"[newline]"。

我认为,这是因为SQL Server";换行符";。我尝试过不同的方法,但似乎都无济于事。我想知道是否有一种方法可以告诉我的存储过程不要这样做或在服务器上停止此功能,或者是否有其他方法可以绕过此功能,而不需要对数据进行任何更改。

我们在客户端上使用c#中的ASCII转换

Encoding.ASCII.GetString(Blob, 0, Blob.Length).Replace("'", "''")

以尽可能少地进行转换。

在服务器上,我们使用将字符串转换为varbinary

CONVERT(VARBINARY(MAX), (@BLOB))

我知道使用

Convert.ToBase64String(BLOB)

将停止此问题。然而,这也需要我们(在客户端上将字节转换为字符串)->(在SQL中将字符串转换为字节)->(在服务器或客户端上将字节转换为字符串)->(在客户端上将字符串转换为字节),以便将一个blob上载到服务器并从服务器下载。

我们不能放弃聚合,因为它需要保持服务器更平稳地运行,并且保存字符串将占用比必要的更多空间。

任何关于这方面的知识都欢迎

编辑

评论中的许多人对这个问题感到困惑,我能理解。我会努力回答为什么,即使是你,它也与我的OG问题无关。会有很多拼写错误,因为我半夜在床上穿着内衣这样做。

我们有测试软件解决方案,到处都是。他们大多在工厂里使用糟糕的电脑,互联网接入非常有限。每个工作站都可以运行一定数量的DUT(被测设备),这些DUT都有一个测试。每个测试都有一定数量的步骤要执行。因此,可以有一个有1个dut的站,它有13个测试步骤,也可以有一种有50个dut,它有40个tet步骤。这些公司可以位于中国、波兰、加拿大等地(这些公司通常在欧洲和其他大陆拥有最多)。

我们没有任何服务器端软件,所以所有的插入都直接变成了注入(我们知道,这很糟糕,但这是10年前的遗留代码,一切都很混乱,因为我是这个项目中唯一的全职人员,而我只工作了6个月,由于自然原因,永远无法与以前的全职人员交谈)。正因为如此,而且这个项目的资金很低,我不会尝试做任何剧烈的改变。

因此,我听说的问题是,当有50个线程试图插入13个单独的步骤对象时,不仅占用了服务器连接,还停止了生产。解决方案是";查询聚合";(我认为这是一些SQL标准的废话,因为我想记住,我在代码中读到了关于is的注释,但我没有找到它),它将所有内容捆绑到一个字符串中,然后在服务器上进行处理。然后,服务器将对其进行切片,并将变量发送到所有存储过程(我只是信使,而不是SQL向导)。在这样做的时候,我们也需要将Blob转换为字符串,因为它是测试中的一个步骤,流程的管道就像一个迷宫,所以几乎不可能通过更改调用来获取id。

现在,我想用ascii更改c#中的blob字节数组,因为当我将其从varchar(max)转换为varbinary(max)时,MSSQL使用普通的ascii转换。问题是,在这样做的时候,有些字符会神秘地消失,因为当从服务器下载字节数组时,我无法将其转换回zip。我发现,通过逐个比较ascii字符,已经从服务器上的字节数组中删除了三个字符(或六个字节)。在ASCII中,这三个字符是"、"one_answers"\r",它们都出现在行的末尾。

通过将这一发现与Microsoft自己关于Line Continuation的文档(可以在此处查看)进行比较,我认为这些案例似乎有关联,这就是为什么我想禁用它,因为我不使用此功能。

我也可以使用

Convert.ToBase64String(BLOB)

因为它从未处理过这个问题,即使在发送50MB文件时也是如此。这可能是巧合,但我相信它确实阻止了这种情况的发生(我想记住,我是从一些出于同样原因或类似原因使用这种方法的智囊那里得到的)。问题是1。字符串变得非常大(我相信是ascii的2.6倍)和2。服务器不会以这种方式进行转换。因此,当我进行强制转换时,它将显示我有一个ascii字符串,这意味着服务器上的字节将表示Base64String的ascii字符串,Base64String表示字节数组,这将创建大量转换。

我们正在决定是否应该跳过将其转换为服务器上的字节数组并将其保存为varchar(max),或者是否应该继续使用fogging来找到将其保留为字节数组的解决方案,以便用户可以直接下载而不进行任何转换。我所说的我们是指我的导师,他参与了这个项目

如前所述,任何关于这方面的知识都欢迎

好吧,我不打算深入讨论整个老鼠窝,但很明显,除此之外,您还有其他问题,您应该强烈考虑清除您已经拥有的任何garabage SQL,转而使用一些正确编写的代码。几乎可以肯定的是;合计";当您可以只使用单独的参数和/或表值参数时,可以对数据进行分解,然后再次对其进行分解。

尽管如此,理想情况下您应该正确地参数化查询。例如,在C#中,您可以执行以下

command.Parameters.Add("@myBlob", SqlDbType.VarBinary, -1).Value = someByteArray;

然后SQL可以直接引用那个@myBLOB变量这是将字节数组传输到SQL Server的最安全、性能最高的方法,我建议您始终使用此方法


如果由于任何原因无法参数化查询,则需要安全的注入方法,以避免任何编码或误解问题。你可以传递这样的十六进制字符串(再次使用C#)

var blobString = Convert.ToHexString(someByteArray);
var query = $"
DECLARE @myBlob varbinary(max) = 0x{blobString};
INSERT ...

相关内容

最新更新