You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi环境下限制SQL Server查询为只读的技术咨询

自定义查询模块的SQL写入风险防控方案

一、能不能把ADOConnection或ADOQuery设成只读?

  • ADOConnection本身没有直接的只读开关,但可以通过ADOQuery的属性做些限制:
    • 把ADOQuery的LockType设为ltReadOnly,再把ExecuteOptions改成eoExecuteNoRecords(只用来执行查询类操作)。但这只是客户端层面的限制,如果用户构造的SQL里带了写入语句,组件本身拦不住——毕竟最终能不能执行还是看数据库账号的权限。
    • 说白了,这种方式防君子不防小人,恶意用户要是绕开组件的约束写恶意SQL,照样能执行写入操作,可靠性不高。

二、SQL Server能不能把当前会话设成只读?

SQL Server没有Oracle那种直接的SET SESSION READONLY命令,但有两种办法能达到类似的会话级只读效果:

  1. 开启只读事务
    • 在执行用户的自定义查询前,先跑一句SET TRANSACTION READ ONLY;,开启只读事务。这时候会话里只要有写入操作(DELETE/UPDATE/INSERT这些),直接就会报错:无法在只读事务中执行数据修改语句。
    • 要注意:这个设置只针对当前事务,如果用户的查询里自己写了事务提交或回滚,可能会打破这个限制;不过临时表操作在只读事务里是允许的(因为临时表存在tempdb里,不受当前数据库的只读事务约束),刚好能满足管理员用临时表的需求。
  2. 临时切换到只读账号
    • 虽然应用用的是统一的读写账号,但可以在执行普通用户的查询前,用EXECUTE AS USER = '你的只读用户名';临时切换到只读权限的数据库用户,查完之后再用REVERT;切回原来的账号。
    • 这种方式更彻底,只读账号本身就没写入权限,就算执行写入SQL也会被数据库直接拦下来,但得提前建好对应的只读账号,把权限配置好。

三、关于关键词过滤的问题

你说的查关键词的办法确实不靠谱,恶意用户可以玩各种花样绕过去——比如大小写乱改(DeLeTe)、插注释(DELETE/**/FROM)、转编码之类的,最多只能当个辅助手段,不能靠这个当核心防护。

四、管理员和普通用户的区别处理

  • 管理员用户:不用设任何只读限制,保留原来的读写权限,方便他们用临时表之类的操作。
  • 普通自定义查询用户:优先用上面说的“开只读事务”或者“切换只读账号”的办法,从数据库层面拦写入操作,比客户端组件的限制靠谱多了。

内容的提问来源于stack exchange,提问作者user1937012

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:48:27