草庐IT

c# - 使用SQL返回JSON字符串

coder 2024-06-02 原文

这是一个“最佳实践”问题。我们正在就此主题进行内部讨论,并希望获得更广泛受众的意见。

我需要将数据存储在具有常规列和行的传统MS SQL Server表中。有时我需要将DataTable返回到我的Web应用程序,而其他时候,我需要返回JSON字符串。

当前,我将表返回到中间层并将其解析为JSON字符串。这似乎在大多数情况下都能很好地工作,但偶尔会在大型数据集上花费一些时间(解析数据,而不返回表)。

我正在考虑修改存储过程,以有选择地返回DataTableJSON字符串。我只需将@isJson bit参数添加到SP。

如果用户希望使用字符串而不是表,则SP将执行以下查询:

DECLARE @result varchar(MAX)
SELECT @result = COALESCE(@results ',', '') + '{id:"' + colId + '",name:"' + colName + '"}'
    FROM MyTable
SELECT @result

这将产生如下内容:
{id:"1342",name:"row1"},{id:"3424",name:"row2"}

当然,用户也可以通过将false传递给@isJson参数来获取表。

我想明确地说,数据存储不会受到影响,任何现有 View 和其他过程也不会受到影响。这只是对某些存储过程的结果的更改。

我的问题是:
  • 有人在大型应用程序中尝试过吗?如果是这样,结果是什么?
  • 您看到/希望使用此方法有什么问题?
  • 除了以这种方式修改存储过程或解析中间层中的字符串之外,SQL Server中是否存在更好的从表到JSON的更快方法?
  • 最佳答案

    我个人认为,这种字符串处理的最佳位置是使用具有功能且可以编译的完全表达性语言编写的程序代码。在T-SQL中这样做是不好的。程序代码可以具有快速执行适当转义的功能。
    让我们考虑一下事情:

  • 在部署应用程序各部分的新版本时,此功能的最佳位置是哪里?
  • 如果您必须还原数据库(及其所有存储过程),将会对任何事情产生负面影响吗?如果要部署Web前端的新版本,将JSON转换绑定(bind)到数据库中是否会引起问题?
  • 您将如何正确地转义字符?您要发送任何日期吗?日期字符串将采用哪种格式,以及如何将其转换为另一端的实际Date对象(如果需要)?
  • 您将如何对其进行单元测试(以及自动测试!),以证明其正常工作?您将如何对其进行回归测试?
  • SQL Server UDF可能非常慢。您是否愿意使用慢速功能,或为了快速入侵SQL代码(例如Replace(Replace(Replace(Replace(Value, '\', '\\'), '"', '\"'), '''', '\'''), Char(13), '\n'))而感到满意? Unicode,\u\x转义怎么办?将'</script>'拆分为'<' + '/script>'怎么样? (也许不适用,但也许适用,具体取决于您使用JSON的方式。)您的T-SQL过程是否要执行所有这些操作,并且可用于不同的记录集,或者您是否会每次将其重写为每个记录集?您需要返回JSON的SP吗?
  • 您可能只有一个需要返回JSON的SP。目前。有一天,您可能还会有更多。然后,如果您发现错误,则必须在两个地方修复它。或五个。或者更多。

  • 似乎您需要通过中间层进行翻译来使事情变得更复杂,但是从长远来看,我保证您会变得更好。如果您的产品可以扩展并开始大规模并行化,该怎么办—您总是可以廉价地投入更多的Web服务器,但是却无法如此轻松地解决数据库服务器资源饱和的问题!因此,不要让数据库做更多的工作。它是数据访问层,而不是表示层。使它尽可能少地工作。编写其他代码。您会很高兴的。
    Web应用程序中字符串处理的速度提示
  • 确保您的Web字符串连接代码不受Schlemiel the Painter's Algorithm的影响。在生成JSON时直接将其写入输出缓冲区(Response.Write),或者使用适当的StringBuilder对象,或者将JSON的各部分写入数组,然后稍后将其Join()。不要将普通的 Vanilla 级联连接到一遍又一遍的字符串越来越长。
  • 尽可能少地引用对象。我不知道您的服务器端语言,但是如果它恰好是ASP Classic,则不要使用字段名称-获取对变量中每个字段的引用,或者至少使用整数字段索引。在循环内基于其名称取消引用字段的性能会(很差)。
  • 使用预构建的库。当您可以使用经过尝试和真实的库时,请不要自己动手。性能应该与您自己的性能相同或更好,并且(最重要的是)它将经过测试和纠正。
  • 如果您要花时间进行此操作,请将其抽象化以足以转换任何记录集,而不仅仅是现在的记录集。
  • 使用编译后的代码。您始终可以在编译时获得最快的代码,而不是对其进行解释。如果您确定JSON转换例程确实是瓶颈(并且必须真实地证明这一点,请不要猜测),然后将代码放入已编译的内容中。
  • 减少字符串长度。这不是很大,但是如果可能的话,请使用一个字母的json名称而不是多个字母的名称。对于一个巨大的记录集,这将在两端节省总计。
  • 确保已将其压缩。这并不是服务器端的改进,但是我不能不完整地提到JSON性能。

  • JSON中的传递日期
    我建议使用单独的JSON模式(在JSON中本身,定义要遵循的虚拟记录集的结构)。该模式可以作为 header 发送到“recordset”以进行跟踪,也可以已经加载到页面中(包含在基本javascript文件中),因此不必每次都发送。然后,在JSON解析回调(或最终结果对象的后回调)中,查找当前列的架构,并根据需要进行转换。您可能会考虑使用ISO格式,因为在ECMAScript 5 strict mode中应该提供更好的日期支持,并且无需更改数据格式即可简化代码(并且简单的对象检测可以让您在支持它的任何浏览器中使用此代码):

    Date

    Dates are now capable of both parsing and outputting ISO-formatted dates.

    The Date constructor now attempts to parse the date as if it was ISO-formatted, first, then moves on to the other inputs that it accepts.

    Additionally, date objects now have a new .toISOString() method that outputs the date in an ISO format. var date = new Date("2009-05-21T16:06:05.000Z");

    print( date.toISOString() ); // 2009-05-21T16:06:05.000Z

    关于c# - 使用SQL返回JSON字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11512335/

    有关c# - 使用SQL返回JSON字符串的更多相关文章

    1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

      我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

    2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    3. Ruby 解析字符串 - 2

      我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

    4. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

      我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

    5. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    6. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

      很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

    7. ruby - 在 Ruby 中使用匿名模块 - 2

      假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

    8. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

      我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

    9. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

      我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

    10. ruby-on-rails - unicode 字符串的长度 - 2

      在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

    随机推荐