適用於:✅ Microsoft Fabric 中的 SQL 分析端點和倉儲
在本文中,您將學習如何使用 Fabric SQL 查詢 JSON 檔案,包括 Fabric Data Warehouse 及 SQL 分析端點。
JSON(JavaScript 物件符號)是一種輕量級的半結構化資料格式,廣泛用於感測器串流、物聯網配置、日誌及地理空間資料(例如 GeoJSON)。
使用 OPENROWSET 直接查詢 JSON 檔案
在 Fabric Data Warehouse 和 Lakehouse (SQL 分析端點) 中,你可以直接使用 OPENROWSET 函式查詢湖中 JSON 檔案。
OPENROWSET( BULK '{{filepath}}', [ , <options> ... ])
[ WITH ( <column schema and mappings> ) ];
當你用 OPENROWSET 查詢 JSON 檔案時,首先要指定檔案路徑,這可以是直接的 URL 或針對一個或多個檔案的通配符模式。 預設情況下,Fabric 會將 JSON 文件中的每個頂層屬性投影為結果集中的獨立欄位。 對於 JSON Lines 檔案,每行都被視為獨立的列,非常適合串流場景。
如果你需要更多控制:
- 使用選用
WITH子句明確定義結構,並將欄位映射到特定的 JSON 屬性,包括巢狀路徑。 - 使用
DATA_SOURCE作為相對路徑的根位置參考。 - 設定錯誤處理參數,例如使用
MAXERRORS來流暢地管理解析問題。
常見的 JSON 檔案使用案例
你可以在 Microsoft Fabric 中處理的常見 JSON 檔案類型與使用案例:
- 行分隔的 JSON(「JSON Lines」)檔案,每一行都是獨立且有效的 JSON 文件(例如事件、讀數或日誌條目)。
- 整個檔案不一定是單一有效的 JSON 文件——而是一連串 JSON 物件,中間以換行字元分隔。
- 此格式的檔案通常有副檔名
.jsonl、.ldjson、 或.ndjson。 非常適合串流和追加操作的情境——用戶可以在不重寫檔案或破壞結構的情況下,將新事件作為新行附加。
- 單文件 JSON(「經典 JSON」)
.json檔案,整個檔案是一個有效的 JSON 文件,可以是單一物件或一個物件陣列(這些物件可能為巢狀結構)。- 它常用於設定、快照以及匯出成一個完整的資料集。
- 例如,GeoJSON 檔案通常會儲存一個描述特徵及其幾何形狀的單一 JSON 物件。
使用 OPENROWSET 查詢 JSONL 檔案
Fabric Data Warehouse 與 Lakehouse 的 SQL 分析端點,讓 SQL 開發者能透過函 OPENROWSET 式直接從資料湖查詢 JSON Lines(.jsonl、.ldjson、.ndjson)檔案。
這些檔案每行包含一個有效的 JSON 物件,非常適合串流與僅附加的情境。
要讀取 JSON Lines 檔案,請在參數中 BULK 提供其 URL:
SELECT TOP 10 *
FROM OPENROWSET(
BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.jsonl'
);
預設情況下,會 OPENROWSET 使用 schema 推論,自動發現每個 JSON 物件中的所有頂層屬性,並將其以欄位形式回傳。
不過,你可以明確定義該架構來控制回傳哪些屬性及覆蓋推斷的資料型別。
SELECT TOP 10 *
FROM OPENROWSET(
BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.jsonl'
) WITH (
country_region VARCHAR(100),
confirmed INT,
date_reported DATE '$.updated'
);
在以下情況下,明確定義結構非常有用:
- 你想要覆蓋預設推斷型別(例如強制使用 日期 資料型別而非 varchar)。
- 你需要穩定的欄位名稱和選擇性投影。
- 你要將欄位映射到特定的 JSON 屬性,包括巢狀路徑。
使用 OPENROWSET 讀取複雜(巢狀)JSON 結構
Fabric Data Warehouse 以及 Lakehouse 的 SQL 分析端點讓 SQL 開發者能使用 OPENROWSET 直接從湖中讀取含有巢狀物件或子陣列的 JSON 檔案。
{
"type": "Feature",
"properties": {
"shapeName": "Serbia",
"shapeISO": "SRB",
"shapeID": "94879208B25563984444888",
"shapeGroup": "SRB",
"shapeType": "ADM0"
}
}
在以下範例中,查詢包含範例資料的檔案,並使用子 WITH 句明確投影其葉層屬性:
SELECT
*
FROM
OPENROWSET(
BULK '/Files/parquet/nested/geojson.jsonl'
)
WITH (
-- Top-level field
[type] VARCHAR(50),
-- Leaf properties from the nested "properties" object
shapeName VARCHAR(200) '$.properties.shapeName',
shapeISO VARCHAR(50) '$.properties.shapeISO',
shapeID VARCHAR(200) '$.properties.shapeID',
shapeGroup VARCHAR(50) '$.properties.shapeGroup',
shapeType VARCHAR(50) '$.properties.shapeType'
);
備註
這個例子使用沒有資料來源的相對路徑,在透過其 SQL 分析端點查詢 Lakehouse 檔案時有效。 在 Fabric Data Warehouse 中,您必須以下其中一項:
- 使用檔案的 絕對路徑 ,或
- 在外部資料來源中指定根網址,並使用
DATA_SOURCE選項在語句中引用OPENROWSET其。
使用 OPENROWSET 展開巢狀陣列(JSON 轉為列)
Fabric Data Warehouse 和 Lakehouse 的 SQL 分析端點讓你可以透過 . 來讀取帶有巢狀陣列 OPENROWSET的 JSON 檔案。 接著,你可以使用CROSS APPLY OPENJSON來展開(unnest)這些陣列。 當頂層文件包含你想以每個元素一列為一列的子陣列時,此方法非常有用。
以下簡化的範例輸入中,類似 GeoJSON 的文件有一個特徵陣列:
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{
"type": "Feature",
"properties": {
"shapeName": "Serbia",
"shapeISO": "SRB",
"shapeID": "94879208B25563984444888",
"shapeGroup": "SRB",
"shapeType": "ADM0"
},
"geometry": {
"type": "Line",
"coordinates": [[[19.6679328, 46.1848744], [19.6649294, 46.1870428], [19.6638492, 46.1890231]]]
}
}
]
}
下列查詢:
- 透過使用
OPENROWSET,從湖中讀取 JSON 文件,投影頂層類型屬性及原始特徵陣列。 - 應用
CROSS APPLY OPENJSON於展開特徵陣列,使每個元素成為結果集中的獨立列。 在此擴充中,查詢透過 JSON 路徑表達式擷取巢狀值。shapeName、shapeISO、geometry以geometry.type和coordinates為細節的數值,現在已成為平面欄位,方便分析。
SELECT
r.crs_name,
f.[type] AS feature_type,
f.shapeName,
f.shapeISO,
f.shapeID,
f.shapeGroup,
f.shapeType,
f.geometry_type,
f.coordinates
FROM
OPENROWSET(
BULK '/Files/parquet/nested/geojson.jsonl'
)
WITH (
crs_name VARCHAR(100) '$.crs.properties.name', -- top-level nested property
features VARCHAR(MAX) '$.features' -- raw JSON array
) AS r
CROSS APPLY OPENJSON(r.features)
WITH (
[type] VARCHAR(50),
shapeName VARCHAR(200) '$.properties.shapeName',
shapeISO VARCHAR(50) '$.properties.shapeISO',
shapeID VARCHAR(200) '$.properties.shapeID',
shapeGroup VARCHAR(50) '$.properties.shapeGroup',
shapeType VARCHAR(50) '$.properties.shapeType',
geometry_type VARCHAR(50) '$.geometry.type',
coordinates VARCHAR(MAX) '$.geometry.coordinates'
) AS f;