You need to enable JavaScript to run this app. 将JSON数据导入SQL Server时指定列返回Null如何解决
优惠活动
大模型
产品
解决方案
定价
更多

将JSON数据导入SQL Server时指定列返回Null如何解决

问题原因

你出现空值的核心原因有两点:

  • 你的JSON字段为嵌套结构,OPENJSON的WITH子句默认仅读取根级字段,你没有指定嵌套层级的访问路径
  • 你原有WITH子句里出现了重复的date字段名,没有对应映射_id.$oid、createdDate.$date、lastLogin.$date这几个嵌套字段,同时$date存储的是Unix毫秒级时间戳,需要额外做类型转换才能得到标准 datetime 格式
修复后的代码

你可以直接调整OPENJSON的WITH子句,给嵌套字段指定JSON路径,同时处理时间戳转换即可:

SELECT 
    users.oid,
    users.state,
    users.role,
    users.signUpSource,
    users.active,
    -- 转换Unix毫秒时间戳为SQL Server标准datetime类型
    DATEADD(MILLISECOND, createdDateTimestamp % 1000, DATEADD(SECOND, createdDateTimestamp / 1000, '19700101')) AS createdDate,
    DATEADD(MILLISECOND, lastLoginTimestamp % 1000, DATEADD(SECOND, lastLoginTimestamp / 1000, '19700101')) AS lastLogin
FROM OPENROWSET (
    BULK 'C:\Users\shahk\OneDrive\Desktop\FetchAssgn\users.json', 
    FORMATFILE= 'C:\Users\shahk\OneDrive\Desktop\FetchAssgn\csv.fmt',
    CODEPAGE = '65001' -- 如果你的JSON文件为UTF-8编码,添加该参数避免乱码
) AS [Json]
CROSS APPLY OPENJSON (json)
WITH  (
    oid varchar(50) '$."_id"."$oid"', -- 明确指定嵌套路径获取oid值
    state varchar(5) '$.state',
    createdDateTimestamp BIGINT '$.createdDate."$date"', -- 先读取数字类型的创建时间戳
    lastLoginTimestamp BIGINT '$.lastLogin."$date"', -- 先读取数字类型的最后登录时间戳
    role varchar(10) '$.role',
    signUpSource varchar(10) '$.signUpSource',
    active bit '$.active' -- 布尔类型直接映射为bit类型更合理
) AS users
额外注意事项
  • 如果你的JSON文件是每行一个独立JSON对象(即你提供的扩展样例格式),需要确保你的fmt格式文件配置为按行读取,也可以给OPENROWSET添加SINGLE_CLOB参数一次性读取整个文件再拆分处理
  • 以上时间戳转换逻辑兼容SQL Server 2016及以上所有版本,无需额外自定义函数
  • 字段名包含$这类特殊符号时,JSON路径中需要用双引号包裹避免解析错误

内容的提问来源于stack exchange,提问作者user16669095

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 21:57:03