跳至主要內容

Microsoft SQL Server

Microsoft SQL Server 資料來源連接器可將 Prisma ORM 連接到 Microsoft SQL Server 資料庫伺服器。

範例

若要連接到 Microsoft SQL Server 資料庫,您需要在 Prisma schema 中配置一個 datasource 區塊。

schema.prisma
datasource db {
provider = "sqlserver"
}

資料庫連接 URL 在 prisma.config.ts 中進行配置。

prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config'

export default defineConfig({
schema: 'prisma/schema.prisma',
datasource: {
url: env('DATABASE_URL'),
},
})
資訊

使用 Prisma CLI 命令時,環境變數不會自動載入。您需要使用像 dotenv 這樣的套件從 .env 檔案載入環境變數,或確保您的環境變數已在您的 shell 中設定。

傳遞給 datasource 區塊的欄位有:

  • provider:指定 sqlserver 資料來源連接器。
  • url 欄位是在 prisma.config.ts 中配置,並指定 Microsoft SQL Server 資料庫的連接 URL

使用 node-mssql 驅動程式

v5.4.0 起,您可以將 Prisma ORM 與來自 JavaScript 生態系統的資料庫驅動程式搭配使用(而不是使用 Prisma ORM 內建的驅動程式)。您可以透過使用 驅動程式轉接器 (driver adapter) 來達成此目的。

對於 SQLite 以外的場景,node-mssql 是 JavaScript 生態系統中最受歡迎的驅動程式之一。

本節說明如何將其與 Prisma ORM 及 @prisma/adapter-mssql 驅動程式適配器結合使用。

1. 安裝相依套件

首先,安裝 Prisma ORM 用於 node-mssql 的驅動程式適配器。

npm install @prisma/adapter-mssql

2. 使用驅動程式轉接器實例化 Prisma Client

現在,當您實例化 Prisma Client 時,您需要將 Prisma ORM 驅動程式轉接器的實例傳遞給 PrismaClient 建構函式。

import 'dotenv/config'
import { PrismaMssql } from '@prisma/adapter-mssql'
import { PrismaClient } from '../prisma/generated/client'

const config = {
server: 'localhost',
port: 1433,
database: 'mydb',
user: 'sa',
password: 'mypassword',
options: {
encrypt: true, // Use this if you're on Windows Azure
trustServerCertificate: true, // Use this if you're using self-signed certificates
},
}

const adapter = new PrismaMssql(config)
const prisma = new PrismaClient({ adapter })

連接詳情

用於連接 Microsoft SQL Server 資料庫的連接 URL 遵循 JDBC 標準

以下範例使用 SQL 身分驗證(使用者名稱與密碼)並啟用 TLS 加密連接。

sqlserver://HOST[:PORT];database=DATABASE;user=USER;password=PASSWORD;encrypt=true
警告

注意:如果您在連接字串中使用以下任何字元,您需要對它們進行跳脫處理

:\=;/[]{}  # these are characters that will need to be escaped

要跳脫這些字元,請在包含特殊字元的數值周圍使用大括號 {}。例如:

sqlserver://HOST[:PORT];database=DATABASE;user={MyServer/MyUser};password={ThisIsA:SecurePassword;};encrypt=true

引數

參數名稱必填預設值註解
  • 資料庫
  • initial catalog
master要連接的資料庫名稱。
  • username
  • user
  • uid
  • userid
無 - 請參閱註解SQL Server 登入帳號(例如 sa),或者若 integratedSecurity 設為 true,則為有效的 Windows (Active Directory) 使用者名稱(僅限 Windows)。
  • password
  • pwd
無 - 請參閱註解SQL Server 登入密碼,或者若 integratedSecurity 設為 true,則為 Windows (Active Directory) 使用者密碼(僅限 Windows)。
encrypttrue配置是否始終使用 TLS,或僅在登入過程中配置。可選值:true(始終使用)、false(僅用於登入憑證)。
integratedSecurity啟用 Windows 身分驗證(整合安全性)。可選值:true, false, yes, no。若設為 trueyes 且提供了 usernamepassword,則透過 Windows Active Directory 進行登入。若未透過個別參數提供登入資訊,則使用目前已登入的 Windows 使用者登入伺服器。
connectionLimitnum_cpus * 2 + 1連線池 (connection pool) 的最大大小(Prisma ORM v6 及更早版本)
connectTimeout5等待新連接的最長秒數。
schemadbo若架構 (schema) 名稱非預設值,則作為所有查詢的前綴。
  • loginTimeout
  • connectTimeout
  • connectionTimeout
等待登入成功的秒數。
socketTimeout等待每個查詢成功的秒數。
isolationLevel設定 交易隔離層級
poolTimeout10從連接池等待新連接的最長秒數。如果所有連接都在使用中,資料庫會在等待指定時間後返回 PoolTimeout 錯誤。
  • ApplicationName
  • 應用程式名稱
(不區分大小寫)
設定連接的應用程式名稱。自 2.28.0 版本起可用。
trustServerCertificatefalse配置是否信任伺服器憑證。
trustServerCertificateCA用於驗證伺服器憑證的憑證授權檔案路徑,用以取代系統憑證。必須為 pemcrtder 格式。不能與 trustServerCertificate 參數同時使用。
Prisma ORM v7 連線池

在 Prisma ORM v7 中,驅動程式適配器是關聯式資料庫的預設選項。連接池由您提供的 Node.js 驅動程式(例如 mssql)處理,而非 Prisma 的連接 URL 參數。請參閱 連接池指南以了解 v7 的預設值與配置。

使用 整合安全性 (僅限 Windows)

以下範例使用目前已登入的 Windows 使用者來登入 Microsoft SQL Server。

sqlserver://:1433;database=sample;integratedSecurity=true;trustServerCertificate=true;

以下範例使用特定的 Active Directory 使用者來登入 Microsoft SQL Server。

sqlserver://:1433;database=sample;integratedSecurity=true;username=prisma;password=aBcD1234;trustServerCertificate=true;

連接到具名執行個體 (Named Instance)

以下範例使用整合安全性連接到 Microsoft SQL Server 的具名執行個體 (mycomputer\sql2019)。

sqlserver://mycomputer\sql2019;database=sample;integratedSecurity=true;trustServerCertificate=true;

Microsoft SQL Server 與 Prisma schema 之間的型別對應

若要查看按 Prisma ORM 型別組織的型別對應,請參閱 Prisma schema 參考文件。

支援的版本

請參閱支援的資料庫

限制與已知問題

Prisma Migrate 的注意事項

Prisma Migrate 在 2.13.0 及後續版本中受支援,並具有以下注意事項:

資料庫架構 (Schema) 名稱

SQL Server 沒有類似 PostgreSQL 中常見的 SET search_path 指令。這意味著在建立遷移時,您必須在連接 URL 中定義與生產資料庫所使用的相同架構名稱。對於大多數使用者來說,這是 dbo(預設值)。然而,如果生產資料庫使用其他架構名稱,則必須手動編輯所有遷移 SQL 以反映生產環境,或者在建立遷移前更改連接 URL(例如:schema=name)。

循環引用

當模型相互引用時,可能會出現循環引用,從而建立一個封閉迴路。使用 Microsoft SQL Server 資料庫時,如果關聯的參照動作 (referential action) 設定為 NoAction 以外的值,Prisma ORM 將會顯示驗證錯誤。

更多資訊請參閱SQL Server 中參照動作的特殊規則

破壞性變更

某些遷移會導致比預期更多的變更。例如:

  • 新增或移除 autoincrement()。這無法透過修改欄位達成,而是需要重建資料表(包括所有限制、索引和外鍵)並在資料表之間移動所有資料。
  • 此外,無法刪除資料表中的所有欄位(PostgreSQL 或 MySQL 則可以)。如果遷移需要重建所有資料表欄位,它也會重建整個資料表。

不支援共享預設值

在某些情況下,使用者可能希望將預設值定義為共享物件。

default_objects.sql
CREATE DEFAULT catcat AS 'musti';

CREATE TABLE cats (
id INT IDENTITY PRIMARY KEY,
name NVARCHAR(1000)
);

sp_bindefault 'catcat', 'dbo.cats.name';

使用預存程序 sp_bindefault,預設值 catcat 可以用於多個資料表。Prisma ORM 管理預設值的方式是每個資料表獨立。

default_per_table.sql
CREATE TABLE cats (
id INT IDENTITY PRIMARY KEY,
name NVARCHAR(1000) CONSTRAINT DF_cat_name DEFAULT 'musti'
);

當對最後一個範例進行內省 (introspection) 時,會產生以下模型:

schema.prisma
model cats {
id Int @id @default(autoincrement())
name String? @default("musti")
}

而第一個範例則不會內省出預設值。

schema.prisma
model cats {
id Int @id @default(autoincrement())
name String?
}

如果將 Prisma Migrate 與共享預設物件一起使用,則必須手動對 SQL 進行變更。

資料模型限制

無法將帶有 UNIQUE 約束和篩選索引的欄位用作外鍵

Microsoft SQL Server 僅允許在具有 UNIQUE 約束的欄位中有一個 NULL。例如:

  • 使用者資料表有一個名為 license_number 的欄位。
  • license_number 欄位具有 UNIQUE 約束。
  • license_number 欄位僅允許**一個** NULL 值。

解決此問題的標準方法是建立一個排除 NULL 值的篩選唯一索引。這允許您插入多個 NULL 值。如果您未在資料庫中建立索引,嘗試透過 Prisma Client 將多於一個 null 值插入欄位時將會收到錯誤。

*然而*,建立索引後,將無法在資料庫中使用 license_number 作為外鍵(或對應 Prisma Schema 中的關聯純量欄位)。

原始查詢 (Raw Query) 注意事項

帶有 String @db.VarChar(n) 欄位 / VARCHAR(N) 資料表的原始查詢

原始查詢中的 String 查詢參數總是被編碼為 NVARCHAR(4000)(如果您的 String 長度 <= 4000)或 NVARCHAR(MAX) 傳送給 SQL Server。如果您將 String 查詢參數與 String @db.VarChar(N) / VARCHAR(N) 型別的欄位進行比較,可能會導致 SQL Server 進行隱式轉換,進而影響索引效能並導致 CPU 使用率偏高。

以下是一個範例:

model user {
id Int @id
name String @db.VarChar(40)
}

此查詢會受到影響:

await prisma.$queryRaw`SELECT * FROM user WHERE name = ${"John"}`

為了避免此問題,我們建議您在原始查詢中始終手動將 String 查詢參數轉型 (cast) 為 VARCHAR(N)

await prisma.$queryRaw`SELECT * FROM user WHERE name = CAST(${"John"} AS VARCHAR(40))`

這使得 SQL Server 能夠執行叢集索引搜尋 (Clustered Index Seek),而非叢集索引掃描 (Clustered Index Scan)。

© . This site is unofficial and not affiliated with Prisma Data, Inc.