如何将SQL Server查询结果的数据转换为JSON格式?

10

我正在学习Ajax和JSON格式。我正在构建一个非常简单的通讯录。假设我有一张表格,为了简单起见,它只有三列:

姓名、电子邮件和电话

我的javascript/jquery并不是很好,我正在学习。但我想将从SQL Server返回的数据放到JSON格式中。我应该创建一个存储过程来创建一个JSON文件,并将其放入一个文件夹中,在js代码中使用吗?

还是这是像客户端的C# / VB.NET应用程序应该做的事情,每5分钟生成一次文件呢?基本上假设我得到一些数据返回:

George g@yahoo.com 123-3333
Mike m@gmail.com 123-4433
Steve s@gmail.com 144-3333
Jill r@gmail.com 333-3333

我从简单的选择语句中获取了这个:

SELECT name, email, phone from myTable

我该如何将其转换为 JSON 文件,以便可以将数据存储在 .json 文件中,并在我的 JavaScript 代码中使用该文件?有人能解释一下如何生成 JSON 文件吗?


1
你可能想在这里投票:http://connect.microsoft.com/SQLServer/feedback/details/673824/add-native-support-for-json-to-sql-server-a-la-xml-as-in-for-json-or-from-openjson - Tom Hunter
你需要使用服务器端脚本来完成这个任务。每次数据库更新时更新.json文件是否经济实惠?将数据序列化并放在一个SQL字段中会更好吧? - shennan
重复的问题?https://dev59.com/YEnSa4cB1Zd3GeqPQ8hz - Tom Hunter
我最终采用了这个想法:https://dev59.com/Rm445IYBdhLWcg3wAFq0#16166658 - Rafael Emshoff
2个回答

10

通常更好的做法是通过一些Web API提供JSON。

以下是在ASP.NET MVC中执行此操作的示例:

http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

public class Contact
{
  public string Name {get;set;}
  public string Email {get;set;}
  public string Phone {get;set;}
}

public class ContactsController : ApiController
    {
        // instead of having the contacts in memory, you can load them from the database using Entity Framework, Dapper.NET - or you other favorite ORM.
        Contact[] contacts = new Contact[] 
        { 
            new Contact{ Name = "George", Email = "g@yahoo.com", Phone = "123-3333" }, 
            new Contact{ Name = "Mike", Email = "m@yahoo.com", Phone = "123-3333" }, 
            new Contact{ Name = "Steve", Email = "s@yahoo.com", Phone = "123-3333" } 
        };

        public IEnumerable<Contact> GetAllContacts()
        {
            return contacts;
        }
    }

您可以访问以下地址: http://localhost:xxxx/api/contacts/ 来查看数据。您可以使用JavaScript以JSON格式检索数据。Web API会负责将其转换为JSON。

背后的ASP.NET MVC使用NewtonSoft的JSON.NET将类转换为JSON。它是开源的,可在任何.NET应用程序中使用。

http://james.newtonking.com/pages/json-net.aspx

使用jQuery检索数据:

<script type="text/javascript">
    $(document).ready(function () {
        // Send an AJAX request
        $.getJSON("api/contacts/",
        function (data) {
            // On success, 'data' contains a list of contacts.
            $.each(data, function (key, val) {

                console.log(val.Name, val.Phone, val.Email);  
            });
        });
    });
</script>

如果您的项目正在使用ASP.NET Web Forms,则可以执行以下操作:

asp.net web forms json return result

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
public List<Contact> GetAllContacts()
{
  return contacts;
}

@JoeMcBride - 我尝试了这个,但出现了问题 https://dev59.com/iGrXa4cB1Zd3GeqPD-dI 也许你可以再次帮忙? - oJM86o
这需要你为从数据库返回的每个可能的查询创建一个类(所有表和视图)。最好的方式是以一种通用的方式,将SELECT * FROM view直接转换为JSON格式。以某种方式直接将SQLDataReader的结果转换为JSON响应。 - Rafael Emshoff

1
你也许可以利用我过去使用的一些基本 SQL 转换成 JSON 的逻辑……但这可能相当特定于我的数据集。我试图将其泛化一些。
SET NOCOUNT ON;

--sample table
CREATE TABLE #Temp(
    Id INT Identity(1,1),
    Column1 INT,
    Column2 VARCHAR(10),
    Column3 VARCHAR(10)
    )
;

INSERT INTO #Temp(Column1, Column2, Column3) VALUES (10,'Test', 'Test2'), (20, 'Test3', 'Test4'), (30, 'Test5', 'Test6');

WITH 
    cte AS(
        SELECT  Id AS RowId,
                CAST(Id AS VARCHAR(100)) AS Id,
                CAST(Column1 AS VARCHAR(100)) AS Column1,
                CAST(Column2 AS VARCHAR(100)) AS Column2,
                CAST(Column3 AS VARCHAR(100)) AS Column3
        FROM #Temp
        ),
    cte2 AS (
        SELECT  RowId,
                '"' + PropertyName + '"' + ':' + CASE WHEN ISNUMERIC(Value) = 1 THEN Value ELSE '"' + Value + '"' END AS Value,
                ROW_NUMBER() OVER(PARTITION BY RowId ORDER BY CASE WHEN PropertyName = 'Id' THEN '' ELSE PropertyName END) AS RowNum,
                ROW_NUMBER() OVER(ORDER BY RowId) AS RowNum2
        FROM cte
            UNPIVOT(
                Value
                FOR PropertyName IN (
                    Id,
                    Column1,
                    Column2,
                    Column3
                    )
                ) upvt
        )
        SELECT  CASE WHEN cte2.RowNum2 = y.MinRowNum THEN '[' ELSE '' END,
                CASE WHEN cte2.RowNum = x.MinRowNum THEN '{' ELSE '' END,
                cte2.value,
                CASE WHEN cte2.RowNum <> x.MaxRowNum THEN ',' ELSE '' END,
                CASE 
                    WHEN cte2.RowNum = x.MaxRowNum THEN '}' + 
                        CASE WHEN cte2.RowNum2 = y.MaxRowNum THEN '' ELSE ',' END 
                    ELSE '' 
                END,
                CASE WHEN cte2.RowNum2 = y.MaxRowNum THEN ']' ELSE '' END
        FROM cte2
            INNER JOIN (
                SELECT  RowId, 
                        MIN(RowNum) AS MinRowNum, 
                        MAX(RowNum) AS MaxRowNum
                FROM cte2
                GROUP BY RowId
                ) x
                    ON cte2.RowId = x.RowId
            CROSS JOIN (
                SELECT  MIN(RowNum2) AS MinRowNum, 
                        MAX(RowNum2) AS MaxRowNum
                FROM cte2
                ) y
;

/* --输出如下:

[ { "Id":1 ,
"Column1":10 ,
"Column2":"测试" ,
"Column3":"测试2" },
{ "Id":2 ,
"Column1":20 ,
"Column2":"测试3" ,
"Column3":"测试4" },
{ "Id":3 ,
"Column1":30 ,
"Column2":"测试5" ,
"Column3":"测试6" } ] */


基本上,我对一个基于列的通用数据集进行了解压操作,然后使用窗口函数来识别“文档”、“实体”和“属性/值”的开始和结束。显然,这可以在代码中更好地完成,但对于最基本的目的,它也能起到一定作用。 - Jeremy Giaco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接