Ansible执行SQL Server插入语句成功却报错,如何消除该错误?
解决Ansible mssql_script模块执行INSERT语句时的无结果集错误
问题描述
使用Ansible的community.general.mssql_script模块向SQL Server插入带IF NOT EXISTS条件判断的数据时,数据能成功写入,但模块始终抛出错误:
Statement not executed or executed statement has no resultset
直接在SQL控制台执行该语句无任何问题,目前只能靠ignore_errors: Yes避免playbook中断。
错误原因
mssql_script模块的内部逻辑要求执行的SQL语句必须返回结果集:
- 当
IF NOT EXISTS条件不满足(数据已存在)时,无任何语句执行,自然没有结果集返回; - 即使条件满足执行了
INSERT,INSERT语句本身也不会生成结果集,模块因此判定执行失败。
解决方法
在SQL脚本末尾添加SELECT语句,强制返回结果集即可,推荐两种实用实现:
方式1:返回固定结果集
最简单的处理方式,在脚本最后添加固定SELECT语句,确保无论条件是否满足都有结果返回:
修改后的playbook任务:
- name: 'Add value to Db table' local_action: module: community.general.mssql_script login_user: "{{ mssql_login_user }}" login_password: "{{ mssql_login_password }}" login_host: "server.DOMAIN.LOCAL" login_port: "1433" db: DB script: | IF NOT EXISTS (SELECT * FROM DB.dbo.Table WHERE Value2 = %(value2)s) BEGIN INSERT INTO DB.dbo.Table (Value1, Value2) VALUES (%(value1)s, %(value2)s) END -- 强制返回结果集,让模块识别执行成功 SELECT 1 AS ExecutionResult; params: value2: 'This is value 2' value1: 'This is value 1' run_once: True
方式2:返回受影响行数(更实用)
通过变量捕获INSERT语句影响的行数,最后返回该值,还能在Ansible中后续判断是否真的完成插入:
修改后的playbook任务:
- name: 'Add value to Db table' local_action: module: community.general.mssql_script login_user: "{{ mssql_login_user }}" login_password: "{{ mssql_login_password }}" login_host: "server.DOMAIN.LOCAL" login_port: "1433" db: DB script: | DECLARE @RowsAffected INT = 0; IF NOT EXISTS (SELECT * FROM DB.dbo.Table WHERE Value2 = %(value2)s) BEGIN INSERT INTO DB.dbo.Table (Value1, Value2) VALUES (%(value1)s, %(value2)s); SET @RowsAffected = @@ROWCOUNT; -- 捕获INSERT影响的行数 END SELECT @RowsAffected AS RowsAffected; -- 返回结果集 params: value2: 'This is value 2' value1: 'This is value 1' register: insert_result run_once: True # 可选:后续根据返回行数判断插入状态 - name: Print insert result debug: msg: "成功插入{{ insert_result.query_result[0].RowsAffected }}条数据"
验证效果
修改后去掉ignore_errors: Yes,执行playbook时模块会正常识别SQL执行成功,不再抛出错误,同时还能获取执行结果用于后续逻辑判断。
内容的提问来源于stack exchange,提问作者Tngld
相关产品推荐
相关产品推荐

