zplCloud Blog

SQL Server 作为数据源:消除导出循环

连接字符串从不离开你的机器。筛选、排序和分页以参数化 T-SQL 在你的服务器上运行。

2 分钟阅读 zplCloud Team

导出循环,以及它为何会坏

本地 SQL Server 经 zplCloud CLI agent 连接,只有匹配的行用于标签

标签数据存在于 ERP、WMS 或 Azure SQL 数据库中。惯常做法是导出 CSV、修正列名、上传、打印——然后明天重复,因为 CSV 已经过时。

zplCloud data hub 消除了导出。你网络内的 CLI agent 持有 SQL Server 连接字符串,平台向它发送查询描述,只有结果行返回。数据库从不暴露到互联网,凭证从不存储在云中。

这篇文章讲的是精确机制:什么在哪里运行、生成什么 SQL、硬性限制是什么。

架构,一段话

zplcloud proxy 打开一条到 api.zplcloud.com 的出站 TLS 连接(SignalR)。没有入站端口、没有 NAT 规则、没有 VPN。当你在平台中打开数据源时,后端向 agent 发送一个请求对象 - 基础查询、过滤、排序、偏移、限制 - agent 将其转换为 T-SQL,用你的数据库用户对你的 SQL Server 执行,并返回行。连接字符串只存在于 agent 进程内存及其本地配置中。

第 1 步 - 用一个或多个服务器启动 agent

# 允许多个 --sql 标志;NAME 是你在平台中选择的名称。
zplcloud proxy --agent "Lager" \
  --sql PROD="Server=127.0.0.1;Database=erp;User Id=zplcloud;Password=…;Encrypt=True;TrustServerCertificate=True" \
  --sql WAREHOUSE="Server=sql-wh.internal.lan,1433;Database=logistik;User Id=zplcloud;Password=…;Encrypt=True;TrustServerCertificate=True"

等价方式,不把秘密放进命令行(它们会进 shell 历史):

# Windows PowerShell - 每个服务器一个变量,名称在中间
$env:ZPLCLOUD_SQL_PROD_CONNECTION = "Server=127.0.0.1;Database=erp;User Id=zplcloud;Password=…;Encrypt=True;TrustServerCertificate=True"
zplcloud proxy --agent "Lager"

启动横幅列出发现的内容:SQL servers: PROD, WAREHOUSE。对平台的认证用 --api-key <key>ZPLCLOUD_API_KEY

为无人值守操作做持久化:

  • Windows: setx ZPLCLOUD_SQL_PROD_CONNECTION "…",或 zplcloud proxy --agent "Lager" --service-install --api-key sk_zplcloud_…
  • Linux/Raspberry Pi: 同样的 --service-install 标志;它会写入 systemd 单元 zplcloud-agent.service,带 Restart=always
  • 用文件替代 env: 二进制旁的 sqlservers.json~/.zplcloud/,形如 { "sqlServers": { "PROD": "Server=…" } }
  • Docker: docker-compose.agent.yml 中的 ZPLCLOUD_SQL_PROD_CONNECTION

让人浪费一小时连接字符串注意事项

  • Encrypt=True;TrustServerCertificate=True 是自签名证书内部服务器的务实搭配。有了真证书后去掉 TrustServerCertificate
  • 命名实例需要 Server=host\INSTANCE;非默认端口是 Server=host,1433 - 逗号,不是冒号。
  • 使用专用 SQL 登录,仅对标签所需的那几张表授予 SELECT。agent 以该用户执行所有操作,所以数据库是权限边界——不是平台。

第 2 步 - 创建数据源

数据源中,运行中的 agent 出现在 Remote SQL Server 下,每个配置名一个芯片。点击芯片预填表单。

字段
名称Lager-Artikel
类型SQL Server
服务器PROD--sql PROD=… 中的名称)
查询SELECT ean, name, price FROM artikel

测试运行 SELECT 1 并返回 server · database字段通过带 CommandBehavior.SchemaOnlySELECT TOP 1 * 读取列元数据 - 它获取模式而不拉取数据。如果深度嵌套的查询不返回模式,agent 会用 SingleRow 重试一次。

第 3 步 - agent 实际执行什么

你的基础查询被包装为子查询。过滤、排序和分页由 agent 附加:

SELECT * FROM ( SELECT ean, name, price FROM artikel ) AS ds
WHERE ean LIKE @p0
ORDER BY name
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY

有三件事值得读两遍:

1. 值是参数,绝不是字符串拼接。 过滤器构建器发出 @p0@p1、…,并通过 SqlCommand.Parameters 绑定值。用户输入的值在任何地方都不会变成 SQL 文本。

2. 分页是原生的。 limit 10 变成 FETCH NEXT 10 ROWS ONLY;SQL Server 完成工作,只在线路上返回十行,而不是一百万。

3. 行数是独立查询。 当你要求总数时,agent 用相同的 WHERE 和相同参数执行 SELECT COUNT(*) FROM (<base>) AS ds

硬性限制(来自 agent 源码)

限制适用处
每次请求行数1000RowCaplimit 被钳制到 1…1000;未设置时默认 100
命令超时15 s测试、describe、查询和计数
语句类型SELECT基础查询被验证;多语句被拒绝
排序/过滤列已验证标识符不作为自由格式 SQL 透传

如果你在一个视图中需要超过 1000 行 - 批量打印、完整目录 - 平台用递增的 OFFSET 翻页遍历结果集。每页是对你服务器的一次独立 1000 行请求,所以无论总量多少内存都保持平稳。

15 秒超时是刻意的。如果你的基础查询无法在 15 秒内应答,它属于索引视图或带正确索引的表,而不是标签数据源。

第 4 步 - 在设计器和 Print Views 中使用

  • 设计器 → 测试数据 选项卡 → 数据源: 选择数据源并按加载。字段 binding 用真实行而不是占位文本渲染,所以你在任何东西到达打印机前就能看到实际字段长度。
  • Print Views → 配置 → 数据源(Data Hub): 视图的预览及其打印使用实时查询。操作员看到的是当前数据;没有人重新上传 CSV。

故障模式及含义

症状原因
agent 启动但没有芯片出现--sql 名称缺失,或 agent 用另一个 workspace 的密钥认证
测试 立即失败连接字符串错误(实例、端口、凭证) - 错误从 SQL Server 透传
测试 挂起后失败15 s 超时:从 agent 机器服务器不可达,或防火墙静默丢弃包
字段 无返回基础查询对 SchemaOnly 嵌套太深;agent 回退到 SingleRow,这至少需要一行存在
查询可用,Print View 为空视图绑定到另一个数据源,或过滤器排除了所有行

套餐

data hub(通过 CLI agent 的 SQL Server 和 MongoDB 数据源)属于 Pro 套餐。详情见定价页面

相关

更多文章