【问题标题】:SQL Server table to jsonSQL Server 表转 json
【发布时间】:2019-05-02 13:31:04
【问题描述】:

我希望提取表格的一些列(Col1 和 2)并放入 JSON 格式,并在每个节点中编写一些硬编码的 JSON,就像这样。

{ "col1":"xxxx", "col2":"xxxx", "hardcodedString":"xxxx", “硬编码字符串”:“xxxx”,“硬编码字符串”:“xxxx”, "hardcodedString":"xxxx", "hardcodedString":"xxxx"},

我找到了以下 git 脚本,它创建了一个应该生成 JSON 的 SP,但是当我按要求执行时,我得到“命令已成功完成”

对输出的去向有什么想法,或者是否有更好的方法来实现我的 JSON?

create procedure [dbo].[GetJSON] (
    @schema_name varchar(50),
    @table_name varchar(50),
    @registries_per_request smallint = null
)
as
begin
    if ( ( select count(*) from information_schema.tables where table_schema = @schema_name and table_name = @table_name ) > 0 )
    begin
        declare @json varchar(max),
            @line varchar(max),
            @columns varchar(max),
            @sql nvarchar(max),
            @columnNavigator varchar(50),
            @counter tinyint,
            @size varchar(10)

        if (@registries_per_request is null)
        begin
            set @size = ''
        end
        else
        begin
            set @size = 'top ' + convert(varchar, @registries_per_request)
        end
        set @columns = '{'

        declare schemaCursor cursor for
            select column_name
            from information_schema.columns
            where table_schema = @schema_name
            and table_name = @table_name
        open schemaCursor

        fetch next from schemaCursor into @columnNavigator

        select @counter = count(*)
        from information_schema.columns
        where table_schema = @schema_name
        and table_name = @table_name

        while @@fetch_status = 0
        begin
            set @columns = @columns + '''''' + @columnNavigator + ''''':'''''' + convert(varchar, ' + @columnNavigator + ') + '''''''
            set @counter = @counter - 1
            if ( 0 != @counter )
            begin
                set @columns = @columns + ','
            end

            fetch next from schemaCursor into @columnNavigator
        end 

        set @columns =  @columns + '}'

        close schemaCursor
        deallocate schemaCursor

        set @json = '['

        set @sql = 'select ' + @size + '''' + @columns + ''' as json into tmpJsonTable from [' + @schema_name + '].[' + @table_name + ']'
        exec sp_sqlexec @sql

        select @counter = count(*) from tmpJsonTable

        declare tmpCur cursor for
            select * from tmpJsonTable
        open tmpCur

        fetch next from tmpCur into @line

        while @@fetch_status = 0
        begin
            set @counter = @counter - 1
            set @json = @json + @line
            if ( 0 != @counter )
            begin
                set @json = @json + ','
            end

            fetch next from tmpCur into @line
        end

        set @json = @json + ']'

        close tmpCur
        deallocate tmpCur
        drop table tmpJsonTable

        select @json as json
    end
end

【问题讨论】:

  • 有什么理由必须在 SQL 中执行此操作?
  • 完全没有理由 - 简化的问题陈述是将 SQL Server 表内容转换为问题提供的 JSON 格式

标签: sql json sql-server-2008


【解决方案1】:

我真的不建议这样做,在应用层有更好的方法可以做到这一点,但以下方法避免了循环,并且比您当前的方法更简洁:

CREATE PROCEDURE dbo.GetJSON @ObjectName VARCHAR(255), @registries_per_request smallint = null
AS
BEGIN
    IF OBJECT_ID(@ObjectName) IS NULL
        BEGIN
            SELECT Json = '';
            RETURN
        END;

    DECLARE @Top NVARCHAR(20) = CASE WHEN @registries_per_request IS NOT NULL 
                                    THEN 'TOP (' + CAST(@registries_per_request AS NVARCHAR) + ') ' 
                                    ELSE '' 
                                END;

    DECLARE @SQL NVARCHAR(MAX) = N'SELECT ' + @Top + '* INTO ##T ' + 
                                'FROM ' + @ObjectName;

    EXECUTE SP_EXECUTESQL @SQL;

    DECLARE @X NVARCHAR(MAX) = '[' + (SELECT * FROM ##T FOR XML PATH('')) + ']';


    SELECT  @X = REPLACE(@X, '<' + Name + '>', 
                    CASE WHEN ROW_NUMBER() OVER(ORDER BY Column_ID) = 1 THEN '{'
                         ELSE '' END + Name + ':'),
            @X = REPLACE(@X, '</' + Name + '>', ','),
            @X = REPLACE(@X, ',{', '}, {'),
            @X = REPLACE(@X, ',]', '}]')
    FROM    sys.columns
    WHERE   [Object_ID] = OBJECT_ID(@ObjectName)
    ORDER BY Column_ID;

    DROP TABLE ##T;

    SELECT  Json = @X;

END

注意我已将您的两部分对象名称(@schema 和 @table)更改为只接受完整的对象名称。

Example on SQL Fiddle

这个想法基本上是使用 SQL-Server 中的 XML 扩展将表转换为 XML,然后只需将开始标记替换为 {ColumnName:,将结束标记替换为 ,。然后需要再进行两次替换以停止将右括号添加到每行的最后一列,并从 JSON 字符串中删除最后的 ,

【讨论】:

  • 太棒了,撞上这个,效果很好。如何将结果输出到 .js 文件?
  • 您需要自动将其输出到 .js 文件中,还是一次性输出?
  • 嘿,是的,需要自动输出到 .js 文件,我正在考虑将 sp 包装在 SSIS 包中,但在 SSMS SSIS 向导中出现错误。
【解决方案2】:

使用来自魔术词For JSON

示例:

 SELECT name, surname  
 FROM emp  
 FOR JSON AUTO  

结果:

[{"name": "John"}, {"name": "Jane", "surname": "Doe"}]

更多信息在:

https://docs.microsoft.com/en-us/sql/relational-databases/json/format-query-results-as-json-with-for-json-sql-server?view=sql-server-2017&viewFallbackFrom=sql-server-2014

【讨论】:

  • 这只适用于一张桌子。但尝试转换几个表,你会得到不正确的结果。
【解决方案3】:

在 ruby​​ 中使用 mysql2 gem 和 json

require 'mysql2'
require 'json'

client = Mysql2::Client.new(:host => "localhost", :username => "user", :password => "your_pass", :database => "db_name")
results = client.query("SELECT col1, col2 FROM table LIMIT 3").to_a

results.each do |res|
  res.merge!({:hardcoded => "xxxx", :hardcoded2 => "xxxxy"})
end

puts JSON.generate results

【讨论】:

  • 很好,我该如何运行它?
  • 我建议使用rvm 安装ruby,然后运行'gem install mysql2'(你需要安装libmysqlclient-dev)。将此代码复制到 .rb 文件中并使用 ruby​​ 运行它。
  • 谢谢,这将在我的项目中引入另一种技术,如果可能的话我想避免这种技术。我将坚持使用 SQL cmd 格式化 json,然后尝试输出到平面文件。不过,我将看看 ruby​​,因为它似乎是许多服务器端 mw 工作的灵活解决方案。
  • 还有一个问题,MySQL vs MSSQL?
猜你喜欢
  • 1970-01-01
  • 2019-02-05
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2022-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多