跳至主要内容

Microsoft SQL Server

Microsoft SQL Server 数据源连接器将 Prisma ORM 连接到 Microsoft SQL Server 数据库服务器。

示例

要连接到 Microsoft SQL Server 数据库,您需要在您的 datasource 块中配置 Prisma 模式

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

参数

参数名称必需默认值注释
  • 数据库
  • initial catalog
master要连接到的数据库。
  • 用户名
  • 用户
  • uid
  • userid
否 - 请参阅注释SQL Server 登录名(例如 sa如果 integratedSecurity 设置为 true(仅限 Windows),则为有效的 Windows(Active Directory)用户名。
  • 密码
  • pwd
否 - 请参阅注释SQL Server 登录名Windows(Active Directory)用户名的密码,如果 integratedSecurity 设置为 true(仅限 Windows)。
加密true配置是否始终使用 TLS,或者仅用于登录过程,可能的值:true(始终使用),false(仅用于登录凭据)。
integratedSecurity启用 Windows 身份验证(集成安全性),可能的值:truefalseyesno。如果设置为 trueyes 且存在 usernamepassword,则通过 Windows Active Directory 执行登录。如果未通过单独的参数提供登录详细信息,则使用当前登录的 Windows 用户登录到服务器。
connectionLimitnum_cpus * 2 + 1连接池的最大大小
connectTimeout5等待新连接的最长时间(以秒为单位)
模式dbo如果模式名称不是默认值,则作为所有查询的前缀添加。
  • 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 模式的类型映射

有关按 Prisma ORM 类型组织的类型映射,请参阅 Prisma 模式参考 文档。

支持的版本

请参阅 支持的数据库

限制和已知问题

Prisma Migrate 注意事项

Prisma Migrate 在 2.13.0 及更高版本中受支持,并具有以下注意事项

数据库模式名称

SQL Server 没有与 PostgreSQL 中熟悉的 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 能够执行聚簇索引查找而不是聚簇索引扫描。