SQL Server中的OPENJSON动态使用with语句
我需要选择存储为文本的json列并在结果集中解析它。为此,我编写了一个运行良好的存储过程SQL Server中的OPENJSON动态使用with语句,json,sql-server,tsql,Json,Sql Server,Tsql,我需要选择存储为文本的json列并在结果集中解析它。为此,我编写了一个运行良好的存储过程 ALTER PROCEDURE dbo.sp_SerializeJsonFromTable AS Declare @json NVARCHAR(MAX) Declare @Id int Select * Into #Temp From TTAuditLog CREATE TABLE #Temp1 ( Date_Time varchar(50), Exch
ALTER PROCEDURE dbo.sp_SerializeJsonFromTable
AS
Declare @json NVARCHAR(MAX)
Declare @Id int
Select *
Into #Temp
From TTAuditLog
CREATE TABLE #Temp1
(
Date_Time varchar(50),
Exch varchar(100),
Alias varchar(100),
Broker varchar(100),
Company varchar(100),
Trd_Status varchar(50) ,
Trd_Message varchar(max),
Action varchar(20),
B_S varchar(10),
O_C varchar(10),
C_P varchar(10),
Qty Float(50),
Product varchar(50),
Contract varchar(50),
Strike varchar(50),
Price Float(50),
Order_Type varchar(20),
TIF varchar(20),
Modifier varchar(20),
Trigger_Price Float(50),
TPrice_Type varchar(20),
TPrice_Qty Float(50),
Ticks_Away varchar(10),
Advanced varchar(50),
Disc_Qty Float(50),
Variance_pct Float(10),
Duration varchar(20),
Interval varchar(20),
Retries varchar(10),
Leftover_Act varchar(20),
Exec_Qty Float(50),
Work_Qty Float(50),
Cxl_Qty Float(50),
Legged_Qty Float(50),
Pending_Qty Float(50),
Undisclosed_Qty Float(50),
Acc_Number varchar(50),
Risk_Account varchar(50),
Exch_Mbr varchar(20),
Exch_Grp varchar(20),
Exch_Trd varchar(20),
Username varchar(50),
Exch_Cred varchar(50),
Trd_Mbr varchar(20),
Trd_Grp varchar(20),
Trd_ID varchar(20),
Acct varchar(20),
Give_Up varchar(20),
Cntr_Party varchar(50),
Exch_Time Time,
Exch_Date DateTime,
Time_Sent Time,
Src varchar(20),
Time_Proc varchar(20),
P_A varchar(10),
Owner varchar(20),
Order_Num varchar(20),
TT_Order_Key varchar(20),
Rel_Key varchar(20),
Parent_Key varchar(20),
Link_Type varchar(20),
SE_Server varchar(50),
IP_Address varchar(20),
FFT2 varchar(10),
FFT3 varchar(10),
FFT4 varchar(10),
FFT5 varchar(10),
FFT6 varchar(10),
UserTag varchar(20),
OrderTag varchar(20),
Dir_Elec_Access varchar(20),
Trading_Capacity varchar(20),
Liq_Prov varchar(20),
Cmdty_Der_Ind varchar(10),
Inv_Decision varchar(20),
Exec_Decision varchar(20),
Client varchar(20),
Start_Time Time,
Start_Date DateTime,
End_Time Time,
End_Date DateTime,
End_Behavior varchar(20),
TransID varchar(20),
Session_ID varchar(10),
Mon_Username varchar(20),
Callback_Rec varchar(10),
SeriesKey varchar(20),
Exch_Order_ID varchar(20),
Destination varchar(20),
FlowDel_Unit varchar(20),
Time_Rec varchar(20),
Order_Src_Hist varchar(20),
Last_Ord_Src varchar(20)
)
While (Select Count(*) From #Temp) > 0
Begin
Select Top 1 @Id = Id, @json = JsonValue From #Temp
--PRINT @json
--SET @json = 'N' + @json
--Declare @sql varchar(max)
INSERT INTO #Temp1 SELECT * FROM
OPENJSON (@json)
WITH (
Date_Time varchar(50) '$."Time"',
Exch varchar(50) '$."Exch"',
Alias varchar(100) '$."Alias"',
Broker varchar(100) '$."Broker"',
Company varchar(100) '$."Company"',
Trd_Status varchar(50) '$."Status"',
Trd_Message varchar(200) '$."Msg"',
Action varchar(20) '$."Action"',
B_S varchar(10) '$."B_S"',
O_C varchar(10) '$."O_C"',
C_P varchar(10) '$."C_P"',
Qty Float(50) '$."Qty"',
Product varchar(50) '$."Product"',
Contract varchar(50) '$."Contract"',
Strike varchar(50) '$."Strike"',
Price Float(50) '$."Price"',
Order_Type varchar(20) '$."OrderType"',
TIF varchar(20) '$."TIF"',
Modifier varchar(20) '$."Modifier"',
Trigger_Price Float(50) '$."TriggerPrice"',
TPrice_Type varchar(20) '$."TPriceType"',
TPrice_Qty Float(50) '$."TPriceQty"',
Ticks_Away varchar(10) '$."TicksAway"',
Advanced varchar(50) '$."Advanced"',
Disc_Qty Float(50) '$."DiscQty"',
Variance_pct Float(10) '$."Variance"',
Duration varchar(20) '$."Duration"',
Interval varchar(20) '$."Interval"',
Retries varchar(10) '$."Retries"',
Leftover_Act varchar(20) '$."LeftoverAction"',
Exec_Qty Float(50) '$."ExecQty"',
Work_Qty Float(50) '$."WorkQty"',
Cxl_Qty Float(50) '$." CxlQty"',
Legged_Qty Float(50) '$."LeggedQty"',
Pending_Qty Float(50) '$."PendingQty"',
Undisclosed_Qty Float(50) '$."UndisclosedQty"',
Acc_Number varchar(50) '$."AccountNumber"',
Risk_Account varchar(50) '$."RiskAccount"',
Exch_Mbr varchar(20) '$."ExchMbr"',
Exch_Grp varchar(20) '$."ExchGrp"',
Exch_Trd varchar(20) '$."ExchTrd"',
Username varchar(50) '$."Username"',
Exch_Cred varchar(50) '$."ExchCred"',
Trd_Mbr varchar(20) '$."TrdMbr"',
Trd_Grp varchar(20) '$."TrdGrp"',
Trd_ID varchar(20) '$."TrdID"',
Acct varchar(20) '$."Acct"',
Give_Up varchar(20) '$."GiveUp"',
Cntr_Party varchar(50) '$."CntrParty"',
Exch_Time Time '$."ExchTime"',
Exch_Date DateTime '$."ExchDate"',
Time_Sent Time '$."TimeSent"',
Src varchar(20) '$."Source"',
Time_Proc varchar(20) '$."TimeProcessed"',
P_A varchar(10) '$."P_A"',
Owner varchar(20) '$."Owner"',
Order_Num varchar(20) '$."OrderNumber"',
TT_Order_Key varchar(20) '$."TTOrderKey"',
Rel_Key varchar(20) '$."RelatedKey"',
Parent_Key varchar(20) '$."ParentKey"',
Link_Type varchar(20) '$."LinkType"',
SE_Server varchar(50) '$."SEServer"',
IP_Address varchar(20) '$."IPAddress"',
FFT2 varchar(10) '$."FFT2"',
FFT3 varchar(10) '$."FFT3"',
FFT4 varchar(10) '$."FFT4"',
FFT5 varchar(10) '$."FFT5"',
FFT6 varchar(10) '$."FFT6"',
UserTag varchar(20) '$."UserTag"',
OrderTag varchar(20) '$."OrderTag"',
Dir_Elec_Access varchar(20) '$."DirectElectronicAccess"',
Trading_Capacity varchar(20) '$."TradingCapacity"',
Liq_Prov varchar(20) '$."LiquidityProvision"',
Cmdty_Der_Ind varchar(10) '$."CommodityDerivativeIndicator"',
Inv_Decision varchar(20) '$."InvestmentDecision"',
Exec_Decision varchar(20) '$."ExecutionDecision"',
Client varchar(20) '$."Client"',
Start_Time Time '$."StartTime"',
Start_Date DateTime '$."StartDate"',
End_Time Time '$."EndTime"',
End_Date DateTime '$."EndDate"',
End_Behavior varchar(20) '$."EndBehavior"',
TransID varchar(20) '$."TransID"',
Session_ID varchar(10) '$."SessionID"',
Mon_Username varchar(20) '$."MonitoringUsername"',
Callback_Rec varchar(10) '$."CallbackReceived"',
SeriesKey varchar(20) '$."SeriesKey"',
Exch_Order_ID varchar(20) '$."ExchangeOrderID"',
Destination varchar(20) '$."Destination"',
FlowDel_Unit varchar(20) '$."FlowDeliveryUnit"',
Time_Rec varchar(20) '$."TimeReceived"',
Order_Src_Hist varchar(20) '$."OrderSourceHistory"',
Last_Ord_Src varchar(20) '$."LastOrderSource"'
)
Delete #Temp Where Id = @Id
End
SELECT * From #Temp1 order by Date_Time
现在我有了一个需求,我可以在with语句中动态地分配字段名,而不是将它们具体地写在每个字段中
请提供帮助。只要JSON数据只包含具有简单数据类型的类似行、没有对象、没有子数组,就可以构造动态SQL来创建表并在其中插入值,如下所示:
DECLARE @json NVARCHAR(MAX)
SET @json='[
{ "name":"John", "age":31, "city":"New York" },
{ "name":"Mary", "age":29, "city":"New York" }
]'
DECLARE @FirstRow NVARCHAR(MAX)=(SELECT TOP 1 Value FROM OPENJSON(@json))
DECLARE @Columns TABLE (
Position INT IDENTITY PRIMARY KEY,
ColumnName sysname NOT NULL UNIQUE,
JSONDataType INT NOT NULL,
SQLDataType VARCHAR(30) NOT NULL
)
INSERT INTO @Columns (ColumnName, JSONDataType, SQLDataType)
SELECT [Key], Type,
CASE Type
WHEN 1 THEN 'nvarchar(1000)'
WHEN 2 THEN 'float'
WHEN 3 THEN 'bit'
END
FROM OPENJSON(@FirstRow)
DECLARE @SQL NVARCHAR(MAX)
SET @SQL='('+(
SELECT CHAR(13)+CHAR(10)+CHAR(9)+ColumnName+' '+c.SQLDataType
+CASE WHEN c.Position<COUNT(*) OVER () THEN ',' ELSE '' END
FROM @Columns c
ORDER BY c.Position
FOR XML PATH(''), TYPE
).value('.','nvarchar(max)')
+CHAR(13)+CHAR(10)+')'
SET @SQL='CREATE TABLE #Temp '+@SQL+CHAR(13)+CHAR(10)
+'INSERT INTO #Temp SELECT * FROM OPENJSON(@json) WITH'+@SQL
+CHAR(13)+CHAR(10)+'SELECT * FROM #Temp'
PRINT @SQL
EXEC sp_executesql @SQL,N'@json NVARCHAR(MAX)', @json
对于SQL 2017及以上版本:
DECLARE @cols nvarchar(max),
@query nvarchar(max)
SELECT @cols = STRING_AGG([Key], ',')
FROM (
SELECT jc.[Key]
FROM ..YourTableWithAJsonColumn yt
CROSS APPLY OPENJSON(yt.YourJsonColumn) jc
GROUP BY jc.[Key]
) j
SET @query = N'SELECT SomeNonJsonColumn, ' + @cols + N'
FROM
(
SELECT yt.SomeNonJsonColumn,
jc.[Key],
jc.[Value]
FROM ..YourTableWithAJsonColumn yt
CROSS APPLY OPENJSON(yt.YourJsonColumn) jc
) x
PIVOT
(
MAX([Value])
FOR [Key] in (' + @cols + N'
) p'
EXEC sp_executesql @query
感谢Satheesh的格式化。旁注:您不应该在存储过程中使用sp_uuu前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用sp_u,并使用其他东西作为前缀——或者根本不使用前缀@marc_注意到了你的评论。