ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SQLSERVER 批量授权要改 TYPE?把脚本贴给走 TaoToken 的 Codex 对照 sysobjects

SQLSERVER 批量授权要改 TYPE?把脚本贴给走 TaoToken 的 Codex 对照 sysobjects 1. 从一段能跑但会漏权限的脚本说起SQLSERVER 批量授权这件事很多人第一次接触都是因为接手了一个老库某个业务账号需要读全库的表DBA 不想一张张点于是翻出一段用sysobjects加CURSOR的脚本把TYPEU的用户表全查出来再拼GRANT select,insert,delete,update批量执行。这段脚本本身没问题问题出在它只覆盖了「用户表」这一种对象。一旦库里还有视图、存储过程、标量函数、表值函数脚本跑完看着没报错业务一调接口就报「对象不存在或权限不足」排查半天才发现是漏授权。我试过在一个两百多张表、几十个视图和函数的库上直接套用原脚本结果视图查询全挂存储过程调用直接 229 错误。后来才明白sysobjects里的TYPE字段决定了对象类型不同类型要配不同的GRANT权限表给增删改查视图给 select存储过程和函数给 execute表值函数还得额外给 select。手改的时候最容易漏两类东西——系统存储过程混在TYPEP里被一起授权以及标量函数和表值函数分不清FN和TF导致权限给错。这篇就按「排障」视角来写先讲清楚原脚本为什么会在扩展场景下翻车再讲怎么用走 TaoToken 的 Codex 对照脚本逐段检查TYPE和GRANT的对应关系最后你仍然在 SSMS 里执行验证。TaoToken 在这里的角色很明确它只提供 Key 和 Base URL不替你执行任何 SQLSQL 的最终执行和权限确认都在你自己的数据库里完成。2. 前置准备注册 TaoToken 并给 Codex 配好 Base URL在让 Codex 帮你对照脚本之前需要先把模型通道配好。打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册账号进入控制台创建一个 API Key。这个 Key 就是后面填进 Codex 配置里的凭证。创建 Key 的入口在控制台的 API Keys 页面路径是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建完记得复制保存页面刷新后一般不再完整显示。接下来是 Codex 的配置。Base URL 填https://taotoken.net/api注意这里不要加/v1也不要带任何 UTM 参数就填这个干净的地址。Key 填你刚才创建的那串。配置写进 Codex 对应的配置文件后重启一下让配置生效。注意TaoToken 只负责把请求转发到模型它不会连接你的 SQL Server也不会执行任何GRANT语句。所有 SQL 的执行动作都在你自己的 SSMS 里完成这一点在排障时尤其重要别指望模型通道帮你改库。如果你更习惯在网页里直接和模型对话来检查脚本也可以用模型对话入口 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 把脚本贴进去逐段问。长期做数据库脚本审查和编码的话Coding Plan 会更顺手入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。3. 可复制配置把原脚本和扩展需求一起交给 Codex配置好之后关键是把「原脚本」和「你要扩展到的对象类型」一起给 Codex让它对照着检查。不要只丢一句「帮我改批量授权脚本」那样它给的东西往往不贴你的库。先看原始脚本它长这样DECLARE ACUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPEU DECLARE NAME VARCHAR(100) DECLARE SQL VARCHAR(512) OPEN ACUR FETCH NEXT FROM ACUR INTO NAME WHILE fetch_status0 BEGIN EXEC (grant select,insert,delete,update ON [ NAME] TO username;) FETCH NEXT FROM ACUR INTO NAME END CLOSE ACUR DEALLOCATE ACUR这段只处理TYPEU也就是用户表。你要扩展到的对象和对应权限是这样的对象类型sysobjects 中的 TYPE需要授予的权限备注用户表Uselect,insert,delete,update原脚本覆盖视图Vselect建议加status0过滤存储过程Pexecute需排除系统存储过程标量函数FNexecute容易和 TF 混淆表值函数TFselect不是 execute把这张表和原脚本一起贴给 Codex让它逐段核对。你可以这样组织提问先贴原脚本再贴上面这张对照表然后要求它指出原脚本在扩展到 V、P、FN、TF 时分别要改哪一行、补哪条 GRANT以及哪些地方容易漏。Codex 返回的检查结果里重点看三处。第一处是TYPEP的过滤条件原 excerpt 里用的是name not like dt%来剔除系统存储过程这个规则不一定在所有库上都准Codex 一般会提醒你改用is_ms_shipped0更稳妥。第二处是标量函数和表值函数的权限差异FN给 executeTF给 select这两个搞反了函数调用会直接失败。第三处是视图的status0这个条件用来排除无效视图不加的话可能对已经损坏的视图执行授权而报错。让 Codex 把修正后的完整脚本给你但不要直接拿去跑。它给的是「对照后的候选脚本」你还要在 SSMS 里逐段确认。4. 验证请求在 SSMS 里执行并检查最终权限拿到 Codex 对照后的脚本下一步是在 SSMS 里执行并验证。这里给一个把五类对象都覆盖到的版本你可以按自己库的实际情况调整DECLARE NAME VARCHAR(100) DECLARE SQL VARCHAR(512) -- 用户表增删改查 DECLARE ACUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPEU AND is_ms_shipped0 OPEN ACUR FETCH NEXT FROM ACUR INTO NAME WHILE fetch_status0 BEGIN SET SQL GRANT SELECT,INSERT,DELETE,UPDATE ON [ NAME] TO username; EXEC (SQL) FETCH NEXT FROM ACUR INTO NAME END CLOSE ACUR DEALLOCATE ACUR -- 视图select DECLARE VCUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPEV AND status0 OPEN VCUR FETCH NEXT FROM VCUR INTO NAME WHILE fetch_status0 BEGIN SET SQL GRANT SELECT ON [ NAME] TO username; EXEC (SQL) FETCH NEXT FROM VCUR INTO NAME END CLOSE VCUR DEALLOCATE VCUR -- 存储过程execute排除系统存储过程 DECLARE PCUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPEP AND is_ms_shipped0 OPEN PCUR FETCH NEXT FROM PCUR INTO NAME WHILE fetch_status0 BEGIN SET SQL GRANT EXECUTE ON [ NAME] TO username; EXEC (SQL) FETCH NEXT FROM PCUR INTO NAME END CLOSE PCUR DEALLOCATE PCUR -- 标量函数execute DECLARE FNCUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPEFN AND is_ms_shipped0 OPEN FNCUR FETCH NEXT FROM FNCUR INTO NAME WHILE fetch_status0 BEGIN SET SQL GRANT EXECUTE ON [ NAME] TO username; EXEC (SQL) FETCH NEXT FROM FNCUR INTO NAME END CLOSE FNCUR DEALLOCATE FNCUR -- 表值函数select DECLARE TFCUR CURSOR FOR SELECT name FROM SYSOBJECTS WHERE TYPETF AND is_ms_shipped0 OPEN TFCUR FETCH NEXT FROM TFCUR INTO NAME WHILE fetch_status0 BEGIN SET SQL GRANT SELECT ON [ NAME] TO username; EXEC (SQL) FETCH NEXT FROM TFCUR INTO NAME END CLOSE TFCUR DEALLOCATE TFCUR执行完之后用下面这条语句查一下username最终拿到的权限确认没有漏对象SELECT dp.permission_name, dp.state_desc, o.name AS object_name, o.type_desc FROM sys.database_permissions dp JOIN sys.objects o ON dp.major_id o.object_id JOIN sys.database_principals pr ON dp.grantee_principal_id pr.principal_id WHERE pr.name username ORDER BY o.type_desc, o.name;这条查询会把username在库里的所有对象级权限列出来按对象类型排序。你重点核对四件事表是不是都有增删改查四条视图是不是都有 select存储过程和标量函数是不是都有 execute表值函数是不是都有 select。如果某类对象一条权限都没有说明对应的 CURSOR 段没跑到或者过滤条件把对象全排除了。提示is_ms_shipped0比name not like dt%更可靠因为系统对象的命名规律在不同版本和不同库里并不完全一致用系统标记字段判断更稳。5. 本篇常见错排查排障视角下这段脚本最容易出的问题集中在几个点上逐个说。第一个是TYPE写错导致对象漏掉。比如把表值函数写成TYPEIF那是内联表值函数和TF是多语句表值函数两者在sysobjects里类型不同。如果你库里两种都有只查TF就会漏掉IF的那批。检查办法是先用SELECT DISTINCT type FROM sysobjects WHERE type IN (U,V,P,FN,TF,IF)看看库里到底有哪些类型再决定脚本要覆盖哪些。第二个是系统存储过程被误授权。原 excerpt 用name not like dt%剔除但有些系统存储过程不以dt开头会被一起GRANT EXECUTE给业务账号。虽然多数情况下不会立刻出问题但权限给宽了始终是隐患。改用is_ms_shipped0之后系统对象会被干净地排除。第三个是标量函数和表值函数权限给反。FN是标量函数调用方式是SELECT dbo.fn_name(...)需要 executeTF是表值函数调用方式是SELECT * FROM dbo.tf_name(...)需要 select。如果给TF授了 execute 而没授 select查询会报权限错误。反过来给FN授 select 也没用调用时照样失败。第四个是视图的status0漏加。有些库里存在已经失效或被删除依赖的视图status为负对这类视图执行GRANT可能报错中断整个 CURSOR。加上status0可以跳过它们让脚本跑完。第五个是SQL变量长度不够。原脚本用VARCHAR(512)如果对象名很长加上 GRANT 语句可能被截断导致执行失败。对象名超过 100 字符的情况少见但拼出来的语句超过 512 是可能的改成VARCHAR(1000)或NVARCHAR(1000)更保险。第六个是执行完没验证。很多人跑完脚本看到「命令已成功完成」就以为好了实际上可能某个 CURSOR 因为过滤条件把对象全排除了一条权限都没授。用第 4 节那条sys.database_permissions查询核对一遍才能确认最终权限符合预期。6. 把脚本审查和权限验证串起来回到排障的完整链路原脚本只覆盖TYPEU扩展到视图、存储过程、标量函数、表值函数时TYPE和GRANT的对应关系必须逐类核对手改容易漏系统存储过程、漏权限类型、搞反函数权限。用走 TaoToken 的 Codex 对照原脚本和对照表逐段检查能把这些容易漏的点提前暴露出来但最终执行和验证仍然在 SSMS 里完成。如果你在配置 Codex 或检查脚本时遇到接入层面的问题比如 Base URL 填错、Key 没生效可以对照接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 排查或者直接在 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 重新生成一个 Key 试试。需要长期做这类脚本审查和数据库编码的Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 会比单次对话更省事。脚本改完、权限授完、sys.database_permissions查完这条排障链路才算真正闭环。
返回列表