我创建了一个存储过程,以从SQL Server数据库中将数据作为JSON对象提取。我所有的数据都是关系数据,我正在尝试将其作为JSON字符串发送出去。
目前,我可以从SQL Server中获取一个JSON字符串,但是该对象始终包含转义字符(例如“ {\” field \“:\” value \“})。拉取相同的JSON但不使用转义字符。要测试这一点,我使用了一些简单的查询,并使用存储过程以SqlDataAdapter
将它们插入.NET。
令我感到困惑的是,当我在SSMS中运行查询时,我从未看到任何转义字符,但是一旦将其拉到.NET应用程序中,就会出现转义字符。我想防止这种情况发生,并让我的应用程序仅获取未转义的JSON字符串。
我尝试了一些在研究过程中发现的建议,但没有任何结果产生我想要的结果。我所看到的更改(记录在MSDN和其他SO帖子中)已解决了无法逃脱的结果,但仅在SSMS内,而在其他应用程序内则没有。
我尝试过的事情:
将简单的Json查询设置为param,然后使用JSON_QUERY选择参数:
DECLARE @JSON varchar(max)
SET @JSON = (SELECT '{"Field":"Value"}' AS myJson FOR JSON PATH)
SELECT JSON_QUERY(@JSON) AS 'JsonResponse' FOR JSON PATH
这将在.NET应用程序中产生以下内容:
"[{\"JsonResponse\":{\"Field\":\"Value\"}}]"
这会在SSMS中产生以下内容:
[{"JsonResponse":[{"myJson":"{\"Field\":\"Value\"}"}]}]
使用JSON_QUERY的不带参数的简单Json查询:
SELECT JSON_QUERY('{"Field":"Value"}') AS 'JsonResponse' FOR JSON PATH
这将在.NET应用程序中产生以下内容
"[{\"JsonResponse\":{\"Field\":\"Value\"}}]"
这会在SSMS中产生以下内容
[{"JsonResponse":{"Field":"Value"}}]
使用JSON_QUERY的带有临时表的简单Json查询:
CREATE TABLE #temp(
jsoncol varchar(255)
)
INSERT INTO #temp VALUES ('{"Field":"Value"}')
SELECT JSON_QUERY(jsoncol) AS 'JsonResponse' FROM #temp FOR JSON PATH
DROP TABLE #temp
这将在.NET应用程序中产生以下内容:
"[{\"JsonResponse\":{\"Field\":\"Value\"}}]"
这会在SSMS中产生以下内容:
[{"JsonResponse":{"Field":"Value"}}]
我相信,如果没有转义字符,就无法从SQL Server中获取JSON字符串。如果上面的示例不够用,我将存储过程包括在这里。希望有人可以指出正确的方向。
这是我的存储过程:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_GetRoles]
@USER_ID int
AS
BEGIN
DECLARE @JSON varchar(max)
SET @JSON = (SELECT DISTINCT src.SOURCE_ID AS [source_id]
,RTRIM(src.SOURCE_CODE) AS [source_code]
,src.SOURCE_LABEL AS [source_label]
,(
SELECT srcapp.SOURCE_APPLICATION_ID AS [source_application_id]
,srcapp.APPLICATION_ID AS [application_id]
,app.APPLICATION_CODE AS [application_code]
,CASE WHEN srcappusr.ADMINISTRATOR_FLAG = 'Y' THEN 'true' ELSE 'false' END AS [is_administrator]
FROM dbo.SOURCE_APPLICATION AS srcapp
JOIN(SELECT APPLICATION_ID, APPLICATION_CODE FROM dbo.APPLICATION AS app WHERE RECORD_STATUS = 'A') app ON srcapp.APPLICATION_ID = app.APPLICATION_ID
JOIN(SELECT SOURCE_APPLICATION_ID, USER_ID, ADMINISTRATOR_FLAG FROM dbo.SOURCE_APPLICATION_USER AS srcappusr WHERE RECORD_STATUS = 'A') srcappusr ON srcapp.SOURCE_APPLICATION_ID = srcappusr.SOURCE_APPLICATION_ID
WHERE src.SOURCE_ID = srcapp.SOURCE_ID
AND srcappusr.USER_ID = @USER_ID
AND srcapp.RECORD_STATUS = 'A'
FOR JSON PATH
) AS [source.applications]
,(
SELECT env.ENVIRONMENT_ID AS [environment_id]
,RTRIM(env.ENVIRONMENT_CODE) AS [environment_code]
,CASE WHEN envusr.ADMINISTRATOR_FLAG = 'Y' THEN 'true' ELSE 'false' END AS [is_administrator]
FROM dbo.ENVIRONMENT AS env
JOIN(SELECT ENVIRONMENT_ID, USER_ID, ADMINISTRATOR_FLAG FROM dbo.ENVIRONMENT_USER AS envusr WHERE RECORD_STATUS = 'A') envusr ON env.ENVIRONMENT_ID = envusr.ENVIRONMENT_ID
WHERE src.SOURCE_ID = env.SOURCE_ID
AND envusr.USER_ID = @USER_ID
AND env.RECORD_STATUS = 'A'
FOR JSON PATH
) AS [source.environments]
FROM dbo.SOURCE AS src
LEFT JOIN(SELECT SOURCE_ID, SOURCE_APPlICATION_ID FROM dbo.SOURCE_APPLICATION AS srcapp WHERE RECORD_STATUS = 'A') srcapp ON src.SOURCE_ID = srcapp.SOURCE_ID
LEFT JOIN(SELECT SOURCE_APPLICATION_ID, USER_ID FROM dbo.SOURCE_APPLICATION_USER AS srcappusr WHERE RECORD_STATUS = 'A') srcappusr ON srcapp.SOURCE_APPLICATION_ID = srcappusr.SOURCE_APPLICATION_ID
LEFT JOIN(SELECT SOURCE_ID, ENVIRONMENT_ID FROM dbo.ENVIRONMENT AS env WHERE RECORD_STATUS = 'A') env ON src.SOURCE_ID = env.SOURCE_ID
LEFT JOIN(SELECT ENVIRONMENT_ID, USER_ID FROM dbo.ENVIRONMENT_USER envusr WHERE RECORD_STATUS = 'A') envusr ON env.ENVIRONMENT_ID = envusr.ENVIRONMENT_ID
WHERE
(srcappusr.USER_ID = @USER_ID OR envusr.USER_ID = @USER_ID)
AND src.RECORD_STATUS = 'A'
FOR JSON PATH)
SELECT JSON_QUERY(@JSON) as 'JsonResponse'
END
这将在.NET应用程序中产生以下内容
"[{\"source_id\":1,\"source_code\":\"1\",\"source_label\":\"SOURCE1\",\"source\":{\"applications\":[{\"source_application_id\":1,\"application_id\":1,\"application_code\":\"APP1\",\"is_administrator\":\"true\"}],\"environments\":[{\"environment_id\":1,\"environment_code\":\"1\",\"is_administrator\":\"true\"}]}}]"
但是在SSMS中产生以下内容
[{"source_id":1,"source_code":"1","source_label":"SOURCE1","source":{"applications":[{"source_application_id":1,"application_id":1,"application_code":"APP1","is_administrator":"true"}],"environments":[{"environment_id":1,"environment_code":"1","is_administrator":"true"}]}}]
答案 0 :(得分:1)
这取决于您在哪里查看字符串...
在SSMS中,字符串用单引号标记。双引号可以存在于字符串中而不会出现问题:
DECLARE @SomeString = 'This can include "double quotes" but you have to double ''single quote''';
在C#应用程序中,双引号是字符串标记。因此,上面的示例如下所示:
string SomeString = "This must escape \"double quotes\" but you can use 'single quote' without problems";
在您的IDE中(是VS?),您可以按原样查看字符串 或,因为您需要在代码中使用该字符串。您的示例在字符串的开头和结尾显示"
。明确表明,这是如代码中的选项。您可以使用此字符串并将其放入代码中。使用和处理的真实字符串将不包含转义字符。
提示:仅在人类可读的格式中需要转义字符,其中存在具有特殊含义的字符(CSV中的;
,HTML中的<
等)... < / p>
需要使用转义字符将字符串放置在字符串中。您必须以某种方式标记字符串的开头和结尾,但是您只能使用一些魔术字符来标记其他内容。
要在嵌入的字符串中使用这些字符,必须采取以下一种方式:
&
替换为&
,而JSON将"
替换为\"
,因为JSON使用"
来标记其标签)或CDATA
部分,它允许按原样放置未转义的字符 :<![CDATA[forbidden characters &<> allowed here]]>
)无论您做什么,都必须在编辑器或XML或JSON之类的基于文本的容器中的可见字符串和值之间进行区分 strong>应用程序将从中选择。
一个例子:
<root><a>this & that</a></root>
visible string: "this & that"
real value: "this & that"