跳到主要內容

Microsoft SQL Server

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

範例

要連線到 Microsoft SQL Server 資料庫,您需要在您的 datasource 區塊中設定 Prisma schema

schema.prisma
datasource db {
provider = "sqlserver"
url = env("DATABASE_URL")
}

傳遞到 datasource 區塊的欄位為

  • provider:指定 sqlserver 資料來源連接器。
  • url:指定 Microsoft SQL Server 資料庫的連線 URL。在此案例中,使用環境變數來提供連線 URL。

連線詳細資訊

用於連線到 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

引數

引數名稱必要預設值註解
  • database
  • initial catalog
master要連線的資料庫。
  • username
  • user
  • uid
  • userid
否 - 請參閱註解SQL Server 登入名稱(例如 sa 有效的 Windows (Active Directory) 使用者名稱,如果 integratedSecurity 設定為 true(僅限 Windows)。
  • password
  • pwd
否 - 請參閱註解SQL Server 登入名稱的密碼 Windows (Active Directory) 使用者名稱,如果 integratedSecurity 設定為 true(僅限 Windows)。
encrypttrue設定是否始終使用 TLS,或僅用於登入程序,可能的值:true(始終使用),false(僅用於登入憑證)。
integratedSecurity啟用 Windows 驗證 (整合安全性),可能的值:truefalseyesno。如果設定為 trueyes 且存在 usernamepassword,則會透過 Windows Active Directory 執行登入。如果未透過個別引數提供登入詳細資訊,則會使用目前登入的 Windows 使用者來登入伺服器。
connectionLimitnum_cpus * 2 + 1連線池的最大大小
connectTimeout5等待新連線的最長秒數
schemadbo如果結構描述名稱不是預設值,則作為所有查詢的前綴添加。
  • loginTimeout
  • connectTimeout
  • connectionTimeout
等待登入成功的秒數。
socketTimeout等待每個查詢成功的秒數。
isolationLevel設定交易隔離等級
poolTimeout10從池中等待新連線的最長秒數。如果所有連線都在使用中,資料庫將在等待給定時間後傳回 PoolTimeout 錯誤。
  • ApplicationName
  • 應用程式名稱
(不區分大小寫)
設定連線的應用程式名稱。自 2.28.0 版本起。
trustServerCertificatefalse設定是否信任伺服器憑證。
trustServerCertificateCA伺服器憑證授權時使用的憑證授權檔案路徑,而不是系統憑證。必須為 pemcrtder 格式。不能與 trustServerCertificate 參數一起使用。

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

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

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

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

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

連線到具名執行個體

以下範例使用整合安全性連線到 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 及更高版本中受支援,但有以下注意事項

資料庫結構描述名稱

SQL Server 沒有相當於 PostgreSQL 的 SET search_path 命令。這表示當您建立遷移時,您必須在生產資料庫使用的連線 URL 中定義相同的結構描述名稱。對於大多數使用者來說,這是 dbo(預設值)。但是,如果生產資料庫使用另一個結構描述名稱,則所有遷移 SQL 必須手動編輯以反映生產環境,在建立遷移之前必須變更連線 URL(例如:schema=name)。

循環參考

當每個模型都參考另一個模型時,可能會在模型之間發生循環參考,從而建立一個閉環。當使用 Microsoft SQL Server 資料庫時,如果關聯的參考動作設定為 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'
);

最後一個範例在內省時,會產生以下模型

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 值。如果您未在資料庫中建立索引,如果您嘗試將多個 null 值插入到具有 Prisma Client 的欄位中,您將收到錯誤。

但是,建立索引使得無法在資料庫中使用 license_number 作為外鍵(或在相應的 Prisma Schema 中的關聯純量欄位)

原始查詢考量

具有 String @db.VarChar(n) 欄位 / VARCHAR(N) 欄位的原始查詢

原始查詢中的 String 查詢參數始終編碼到 SQL Server 為 NVARCHAR(4000)(如果您的 String 長度小於等於 4000)或 NVARCHAR(MAX)。如果您將 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 查詢參數轉換為 VARCHAR(N)

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

這使 SQL Server 能夠執行叢集索引搜尋,而不是叢集索引掃描。