json - 兼容级别 100 SQL SERVER 2016 中的 OPENJSON
问题描述
我需要使用OPENJSON()
兼容级别为 100 的旧数据库中的功能。服务器运行 SQL SERVER 2016。所以我想出了这个想法:在同一服务器中创建另一个数据库“GeneralUTILS”(lvl 130)并从100 级数据库:
CREATE FUNCTION [dbo].[OPENJSON_](@json NVARCHAR(MAX))
RETURNS @Results TABLE ([Key] nVARCHAR (4000) , [Value] NVARCHAR(MAX), [Type] INT)
AS
BEGIN
INSERT INTO @Results
SELECT * from OPENJSON(@json)
RETURN
END
但是我没有 WITH 子句来修改 lvl 100 数据库中的输出表。
解决方案
最重要的可能是你为什么需要这个问题......
我希望我得到了正确的,你需要什么:
(提示:这至少需要 SQL-Server 2016)
--创建两个模型数据库
CREATE DATABASE dbOld;
GO
ALTER DATABASE dbOld SET COMPATIBILITY_LEVEL = 100; --v2008
GO
CREATE DATABASE dbForJsonIssues;
GO
ALTER DATABASE dbForJsonIssues SET COMPATIBILITY_LEVEL = 130; --v2016
GO
--现在我们将在“higher”数据库中创建一个存储过程
USE dbForJsonIssues;
GO
--Attention: replacing FROM is a very hacky way... Read the hints at the end...
--You might use parameters for the JSON-string and the JSON-path, but then you must use sp_executesql
CREATE PROCEDURE EXEC_Json_Command @Statement NVARCHAR(MAX), @TargetTable NVARCHAR(MAX)
AS
BEGIN
DECLARE @statementWithTarget NVARCHAR(MAX)=REPLACE(@Statement,'FROM',CONCAT(' INTO ',@TargetTable,' FROM'));
PRINT @statementWithTarget; --you can out-comment this line...
EXEC(@statementWithTarget);
END
GO
--现在我们进入“下层”数据库
USE dbOld;
GO
--A synonym is not necessary, but allows for easier code
CREATE SYNONYM dbo.ExecJson FOR dbForJsonIssues.dbo.EXEC_Json_Command;
GO
--这是如何使用它
DECLARE @json NVARCHAR(MAX)=N'[{"someObject":[{"attr1":"11", "attr2":"12"},{"attr1":"21", "attr2":"22"}]}]';
DECLARE @Statement NVARCHAR(MAX)=CONCAT(N'SELECT * FROM OPENJSON(N''',@json,N''',''$[0].someObject'') WITH(attr1 INT,attr2 INT)');
--the target table will be created "on the fly"
--You can use ##SomeTarget too, but be careful with concurrencies in both approaches...
EXEC ExecJson @Statement=@Statement,@TargetTable='dbOld.dbo.SomeTarget';
SELECT * FROM SomeTarget;
--We can drop this table after dealing with the result
DROP TABLE SomeTarget;
GO
--清理(注意真实数据!)
USE master;
GO
DROP DATABASE dbOld;
DROP DATABASE dbForJsonIssues;
最重要的概念:
我们不能直接在数据库中使用 JSON 语句,但我们可以基于字符串创建语句,将其传递给存储过程并EXEC()
用于执行。
使用SELECT * INTO SomeDb.SomeSchema.SomeTargetTable FROM ...
将创建一个具有拟合结构的表。确保使用数据库中不存在的表。
实际上并不需要将目标表作为参数传递,您可以自己将其放在语句中。替换存储过程中的 是一种非常精明的方法,如果在其他地方发现FROM
可能会导致麻烦。from
您可能会针对各种需求使用类似的程序...
推荐阅读
- php - 终端命令删除多个文件-CPanel,共享主机感染病毒
- redirect - 将 Strapi 管理员索引重定向到管理员登录
- javascript - 查找 HTML 文档中任意位置的两个元素在 DOM 中的相对位置
- c# - Winform C# 应用程序,如何在按钮内对齐文本?
- signalr - 运行长处理器的 SignalR 客户端
- sql-server - SQL Server:尝试使用 sp_send_dbmail 发送电子邮件
- resteasy - 在@BeanParam 中使用枚举
- r - bind_rows(..., .id) 和 yearqtr 的问题
- mongodb - 在 MongoDB 中组合组 - 聚合
- java - 如何在我的 Java 代码中进行更流畅的移动