Power BI RDL 連接 Dataverse,為什麼 Shared Connection 卻要選 SQL Server?
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/1387
在 Power BI Service 中為 Paginated Report(RDL)設定共用資料連線時,我遇到了一個乍看非常矛盾的問題:
資料明明存放在 Dataverse,Power BI 的「新しい接続」中也明明存在
Dataverse這個連線類型,為什麼實際上卻需要選擇SQL Server?
進一步分析實際使用中的 RDL 後,原因終於明確了。
一、先說結論
如果現有 RDL 內部採用的是:
<DataProvider>SQLAZURE</DataProvider>
並且 Connection String 類似:
Data Source=[環境].crm.dynamics.com,5558;
Initial Catalog=[Database ID];
Encrypt=True;
Authentication=Active Directory Interactive;
同時 Dataset 中直接使用:
SELECT ...
FROM ...
INNER JOIN ...
WHERE ...
GROUP BY ...
UNION ALL ...
那麼這份 RDL 實際採用的架構就是:
RDL
↓
SQL / SQLAZURE Provider
↓
T-SQL
↓
Dataverse TDS Endpoint
↓
Dataverse
因此在 Power BI Service 中建立 Shareable Cloud Connection 時,應該匹配這個 RDL 的資料來源 Provider:
接続の種類
→ SQL Server
而不是因為最終資料存在 Dataverse,就直接選:
接続の種類
→ Dataverse
二、Dataverse 為什麼可以用 SQL 查?
Dataverse 本身提供了 TDS Endpoint。
TDS 是 Tabular Data Stream,也就是 SQL Server 所使用的通訊協議之一。
Dataverse 透過 TDS Endpoint 對外提供一個類似 SQL Server 的唯讀查詢介面,因此可以使用 SQL:
SELECT
A.Column1,
B.Column2,
COUNT(*)
FROM TableA AS A
INNER JOIN TableB AS B
ON A.Id = B.Id
WHERE ...
GROUP BY ...
所以從帳票製作者的角度,可以把 Dataverse 理解成:
「一個可以用 SQL 查詢的資料來源。」
這對 RDL 特別方便。
三、這不是 RDL 的固定預設
有一點需要特別注意:
並不是只要使用 RDL + Dataverse,就一定會自動變成 SQL Server 連線。
RDL 本身可以支援不同的 Data Source。
真正決定連線方式的是 RDL 裡面的設定,例如:
<DataProvider>SQLAZURE</DataProvider>
本次實際分析的 RDL 使用的就是 SQLAZURE。
而它的 Data Source 名字雖然叫:
DataverseTDS
但這個名字本身沒有決定性。
例如:
<DataSource Name="DataverseTDS">
這只是開發者取的一個名稱。
就算改成:
<DataSource Name="ABC">
實際連線方式也不會因此改變。
真正重要的是:
<DataProvider>SQLAZURE</DataProvider>
四、為什麼當初會選擇 SQL/TDS?
主要原因是:
製作複雜 RDL 帳票時,SQL 非常方便。
例如一張帳票可能需要:
Table A
↓ JOIN
Table B
↓ JOIN
Master C
↓
日期條件
↓
組織條件
↓
GROUP BY
↓
COUNT
使用 SQL 可以很自然地寫成:
SELECT ...
FROM A
INNER JOIN B ...
INNER JOIN C ...
WHERE ...
GROUP BY ...
甚至還可以使用:
DISTINCT
TOP
COUNT
DATEADD
NOT EXISTS
UNION ALL
本次分析的實際 RDL 中,就存在大量這類 SQL。
因此對這類「統計帳票」而言:
Dataverse
↓
TDS Endpoint
↓
SQL
↓
RDL
是一種非常自然的設計。
換句話說,並不是 Dataverse 強迫 RDL 使用 SQL。
而是:
為了方便使用 SQL 製作 RDL Dataset,因此選擇了 Dataverse TDS Endpoint。
五、那 Power BI 裡的「Dataverse」Connection 又是什麼?
Power BI Service 建立新 Connection 時,可以看到:
接続の種類
├─ Dataverse
├─ SQL Server
├─ ...
這裡的 Dataverse 是另一種資料來源 Connector。
例如它要求填寫:
環境のドメイン
xxxx.crm.dynamics.com
它代表的是:
RDL / Power BI
↓
Dataverse Connector
↓
Dataverse
而目前這批 RDL 使用的是:
RDL
↓
SQL Provider
↓
Dataverse TDS
↓
Dataverse
兩者最終都到 Dataverse,但中間的 Provider 完全不同。
可以理解為:
| 項目 | SQL/TDS 方式 | Dataverse Connector |
|---|---|---|
| 最終資料來源 | Dataverse | Dataverse |
| RDL Provider | SQL / SQLAZURE | Dataverse 對應 Provider |
| 查詢方式 | SQL | Dataverse Connector 對應方式 |
| TDS Endpoint | 使用 | 不以現有 SQL DataSource 形式使用 |
| 現有 SQL Dataset | 可直接使用 | 不能直接沿用 |
六、為什麼不能直接把 Connection Type 改成 Dataverse?
因為 Power BI Service 的 Shared Connection 並不會幫忙「翻譯 Dataset」。
目前 RDL 裡已經寫的是:
SELECT ...
FROM ...
INNER JOIN ...
GROUP BY ...
Power BI 不會因為把:
SQL Server
改成:
Dataverse
就自動把這些 SQL:
SQL
↓
自動轉換
↓
Dataverse Query
不存在這樣的自動轉換。
Shared Connection 主要負責的是:
這個已經定義好的 Data Source,要使用哪條實際連線以及哪套 Credential。
它不是 Dataset Query Converter。
七、所以現有 RDL 不修改的話,目前應該怎麼設定?
以這次實際分析的 RDL 為例:
<DataProvider>SQLAZURE</DataProvider>
Connection String 又是:
Data Source=[Dataverse Environment],5558;
Initial Catalog=[Database];
因此 Power BI Service 裡應建立類似:
接続名:
開発環境_DataverseTDS
接続の種類:
SQL Server
Server:
[環境].crm.dynamics.com,5558
Database:
[Database ID]
認証:
OAuth 2.0
然後:
RDL
↓
ゲートウェイとクラウド接続
↓
Map to
↓
這條 Shared Cloud Connection
這樣就可以讓多份 RDL 共用同一套 Connection / Credential。
八、SQLAZURE 和 Power BI 裡的 SQL Server 為什麼名字又不一樣?
這也是很容易搞混的一點。
RDL XML 中可能看到:
<DataProvider>SQLAZURE</DataProvider>
而 Power BI Service 建立 Connection 時看到的卻是:
SQL Server
這兩個畫面的命名層次不同。
可以簡單理解成:
RDL XML
SQLAZURE
↓
SQL 系 Data Provider
Power BI Service
SQL Server
↓
可供這類 SQL Data Source 映射的 Cloud Connection
所以不能要求兩邊的顯示名稱必須完全一致。
真正應該確認的是:
-
RDL 的 DataProvider
-
Connection String
-
Server
-
Database
-
Dataset 使用的 Query Language
九、如果真的想改成「Dataverse」Connection 呢?
可以,但那就不是單純修改一個下拉框了。
需要重新設計 RDL 的資料取得層。
也就是從現在的:
RDL
↓
SQLAZURE
↓
SQL
↓
Dataverse TDS
改成另一種 Data Source,例如:
RDL
↓
Dataverse / Power Query
↓
Dataverse
這時原有的 SQL:
SELECT
JOIN
GROUP BY
UNION
...
通常也需要重新實作。
例如使用 Power Query 時,對應的是 M 語言。
這裡需要特別注意:
不是 Power Fx。
Power Fx 主要是 Canvas App 等 Power Platform 場景使用的公式語言。
Paginated Report 如果改成 Power Query 型 Dataset,主要涉及的是:
Power Query
→ M
而不是:
Power Fx
十、是否值得把現有 RDL 全部改成 Dataverse Connector?
如果現有 RDL 已經大量使用:
JOIN
GROUP BY
COUNT
UNION
DATEADD
DISTINCT
NOT EXISTS
那通常沒有必要僅僅因為:
「資料本來就是 Dataverse」
就把 Data Source 全部重做。
因為 Dataverse TDS Endpoint 本來就是 Dataverse 官方提供的資料存取方式。
對大量既存 SQL 帳票而言:
保留 SQL/TDS
+
統一使用 Shared Cloud Connection
通常比重新改寫所有 Dataset 要簡單得多。
最容易搞混的四個概念
最後可以把整件事濃縮成這張表:
| 層級 | 本次實際情況 |
|---|---|
| 資料真正存在哪裡 | Dataverse |
| 怎麼讓外部查詢 | Dataverse TDS Endpoint |
| RDL 使用什麼 Provider | SQLAZURE |
| Power BI Shared Connection | SQL Server |
因此這四句話可以同時成立:
資料是 Dataverse。
使用 Dataverse TDS Endpoint。
RDL 使用 SQLAZURE。
Power BI Connection 選 SQL Server。
它們並不矛盾。
最終結論
判斷 Power BI Paginated Report 應該使用哪一種 Shared Connection,不要只看資料最終存在哪裡。
應該優先查看 RDL 本身:
DataProvider 是什麼?
Connection String 是什麼?
Dataset 寫的是什麼查詢?
如果現有 RDL 是:
SQLAZURE
+
Dataverse :5558
+
T-SQL Dataset
那麼它本質上就是:
透過 SQL/TDS 查詢 Dataverse 的 RDL。
在不修改 RDL 的前提下,Power BI Service 裡應該繼續使用 SQL Server 類型的 Shared Cloud Connection。
而 Dataverse Connection 雖然存在,卻是另一條資料存取路徑,不能靠修改 Connection Type 就直接替換現有 SQL/TDS RDL。
This article was last edited at