C# ODBC执行查询后如何获取已声明变量的值?
问题根源与解决方法
原SQL仅给变量赋值后用PRINT输出,不会返回可被OdbcDataReader或ExecuteScalar捕获的结果集,且C#代码的参数设置完全错误,导致无法获取变量值。以下是适配SQL Server和Oracle的具体解决方法:
方案一:通过返回结果集获取值(通用适配)
这种方式无需处理输出参数,直接让SQL返回查询结果,兼容性更强。
SQL Server 版本
SELECT '[' + OBJECT_SCHEMA_NAME(o.[object_id]) + '].[' + OBJECT_NAME([object_id]) + ']' AS object_name FROM(SELECT [object_id] = OBJECT_ID('dbo.ARSTREAM', 'U')) o
Oracle 版本
Oracle无OBJECT_ID这类函数,需从数据字典表查询:
SELECT owner || '.' || table_name AS object_name FROM all_tables WHERE owner = 'DBO' AND table_name = 'ARSTREAM'
对应C#代码修改
直接执行查询,用ExecuteScalar或OdbcDataReader获取结果:
void main() { string sqlq = "-- 替换为对应数据库的SQL语句"; OdbcConnection conn = new OdbcConnection($"DSN={Form3.comboBox1.Text};UID={luid};pwd={lpwd}"); OdbcCommand command = new OdbcCommand(sqlq, conn); conn.Open(); // 用ExecuteScalar直接获取单个值 var objectName = command.ExecuteScalar()?.ToString(); // 或用DataReader方式 /* using(OdbcDataReader dr = command.ExecuteReader()) { if(dr.Read()) { objectName = dr.GetString(0); } } */ conn.Close(); }
方案二:通过输出参数获取值(分数据库适配)
若必须用变量存储后返回,需设置输出参数,注意SQL Server和Oracle的语法差异。
SQL Server 版本
修改SQL并定义输出参数:
DECLARE @object_name SYSNAME OUTPUT SELECT @object_name = '[' + OBJECT_SCHEMA_NAME(o.[object_id]) + '].[' + OBJECT_NAME([object_id]) + ']' FROM(SELECT [object_id] = OBJECT_ID('dbo.ARSTREAM', 'U')) o
对应C#代码:
command.CommandText = @"DECLARE @object_name SYSNAME OUTPUT SELECT @object_name = '[' + OBJECT_SCHEMA_NAME(o.[object_id]) + '].[' + OBJECT_NAME([object_id]) + ']' FROM(SELECT [object_id] = OBJECT_ID('dbo.ARSTREAM', 'U')) o"; // 添加输出参数 OdbcParameter param = command.Parameters.Add("@object_name", OdbcType.NVarChar, 128); param.Direction = ParameterDirection.Output; command.ExecuteNonQuery(); var objectName = param.Value?.ToString();
Oracle 版本
Oracle用冒号标识绑定变量:
DECLARE v_object_name VARCHAR2(200); BEGIN SELECT owner || '.' || table_name INTO v_object_name FROM all_tables WHERE owner = 'DBO' AND table_name = 'ARSTREAM'; :object_name := v_object_name; END;
对应C#代码:
command.CommandText = @"DECLARE v_object_name VARCHAR2(200); BEGIN SELECT owner || '.' || table_name INTO v_object_name FROM all_tables WHERE owner = 'DBO' AND table_name = 'ARSTREAM'; :object_name := v_object_name; END;"; // 添加输出参数,Oracle用:前缀 OdbcParameter param = command.Parameters.Add(":object_name", OdbcType.VarChar, 200); param.Direction = ParameterDirection.Output; command.ExecuteNonQuery(); var objectName = param.Value?.ToString();
关键注意点
- 原代码中
command.Parameters.Add("@object_name", query);完全错误:未设置参数输出方向,query变量未定义,且参数绑定逻辑不成立。 - ODBC连接时,SQL Server参数用
@前缀,Oracle用:前缀,需根据数据库类型动态调整。 - 优先选择方案一的结果集方式,兼容性更强,无需处理不同数据库的输出参数语法差异。
内容的提问来源于stack exchange,提问作者Jedd
相关产品推荐
相关产品推荐

