执行一下这个sql:

SELECT B.[name], C.[name] AS [type], B.length, B.isoutparam, B.isnullable
FROM sysobjects AS A INNER JOIN";
syscolumns AS B ON A.id = B.id AND A.xtype = 'P' AND A.name = '你的存储过程名' INNER JOIN
systypes C ON B.xtype = C.xtype AND C.[name] <> 'sysname'
ORDER BY ROW_NUMBER() OVER (ORDER BY B.id), B.isoutparam 

 

看到结果了吧,此时此刻你是否有豁然开朗的感觉?

正是源于此,下面这个类就有了用武之地,从此不用繁琐的配置存储过程参数

using System;
using System.Collections;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Xml;

namespace fnSwordLibrary.DataBase
{
    public class CEx_SqlProcedure
    {
        #region 数据成员
        private SqlConnection _SqlConnection = null;
        private String _Procedure = String.Empty;
        private SqlCommand _SqlCmd = new SqlCommand();
        private Hashtable _InputTable = null; // 保存input参数和值
        private String _LastError = String.Empty;
        #endregion

        #region 构造函数
        public CEx_SqlProcedure()
        {
            _InputTable = new Hashtable();
            _SqlCmd.CommandType = CommandType.StoredProcedure;
        }

        public CEx_SqlProcedure(SqlConnection SqlConnection)
            : this()
        {
            this.SqlConnection = SqlConnection;
        }

        public CEx_SqlProcedure(String Procedure, SqlConnection SqlConnection)
            : this()
        {
            this.SqlConnection = SqlConnection;
            this.Procedure = Procedure;
        }
        #endregion

        #region 属性
        public String LastError
        {
            get
            {
                return this._LastError;
            }
        }

        public Object ReturnValue
        {
            get
            {
                return _SqlCmd.Parameters["RetVal"].Value;
            }
        }

        public SqlConnection SqlConnection
        {
            set
            {
                this._SqlConnection = value;
                _SqlCmd.Connection = this._SqlConnection;
            }
        }

        public String Procedure
        {
            set
            {
                this._Procedure = value;
                _SqlCmd.CommandText = this._Procedure;
            }

            get
            {
                return this._Procedure;
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 执行存储过程,仅返回是否成功标志
        /// </summary>
        /// <param name="Procedure">存储过程名</param>
        /// <returns>是否成功标志</returns>
        public Boolean ExecuteNonQuery(String Procedure)
        {
            this.Procedure = Procedure;
            return ExecuteNonQuery();
        }

        /// <summary>
        /// 执行存储过程,仅返回是否成功标志
        /// </summary>
        /// <returns>是否成功标志</returns>
        public Boolean ExecuteNonQuery()
        {
            Boolean RetValue = true;
            // 绑定参数
            if (Bindings() == true)
            {
                try
                {
                    // 执行
                    _SqlCmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    _LastError = "execute command error: " + ex.Message;
                    RetValue = false;
                }
            }
            else
            {
                RetValue = false;
            }

            _InputTable.Clear();

            return RetValue;
        }

        /// <summary>
        /// 执行存储过程,返回SqlDataReader
        /// </summary>
        /// <param name="Procedure">存储过程名</param>
        /// <returns>数据库读取行的只进流SqlDataReader</returns>
        public SqlDataReader ExecuteReader(String Procedure)
        {
            this.Procedure = Procedure;
            return ExecuteReader();
        }

        /// <summary>
        /// 执行存储过程,返回SqlDataReader
        /// </summary>
        /// <returns>数据库读取行的只进流SqlDataReader</returns>
        public SqlDataReader ExecuteReader()
        {
            SqlDataReader sqlReader = null;
            // 绑定参数
            if (Bindings() == true)
            {
                try
                {
                    // 执行
                    sqlReader = _SqlCmd.ExecuteReader();
                }
                catch (Exception ex)
                {
                    _LastError = "execute command error: " + ex.Message;
                }
            }

            _InputTable.Clear();

            return sqlReader;
        }

        /// <summary>
        /// 执行存储过程,返回SqlDataAdapter
        /// </summary>
        /// <param name="Procedure">存储过程名</param>
        /// <returns>SqlDataAdapter</returns>
        public SqlDataAdapter ExecuteAdapter(String Procedure)
        {
            this.Procedure = Procedure;
            return ExecuteAdapter();
        }

        /// <summary>
        /// 执行存储过程,返回SqlDataAdapter
        /// </summary>
        /// <returns>SqlDataAdapter</returns>
        public SqlDataAdapter ExecuteAdapter()
        {
            SqlDataAdapter sqlAdapter = null;

            // 绑定参数
            if (Bindings() == true)
            {
                try
                {
                    // 执行
                    sqlAdapter = new SqlDataAdapter(_SqlCmd);
                }
                catch (Exception ex)
                {
                    _LastError = "execute command error: " + ex.Message;
                }
            }

            _InputTable.Clear();

            return sqlAdapter;
        }

        /// <summary>
        /// 获取output的键值
        /// </summary>
        /// <param name="Output">output键名称</param>
        /// <returns>output键值</returns>
        public Object GetOutputValue(String Output)
        {
            return _SqlCmd.Parameters[Output].Value;
        }

        /// <summary>
        /// 设置Input参数值
        /// </summary>
        /// <param name="Key">参数名</param>
        /// <param name="Value">参数值</param>
        public void SetInputValue(String Key, Object Value)
        {
            if (Key == null)
            {
                return;
            }
            if (!Key.StartsWith("@"))
            {
                Key = "@" + Key;
            }

            if (_InputTable.ContainsKey(Key))
            {
                _InputTable[Key] = Value;
            }
            else
            {
                _InputTable.Add(Key, Value);
            }
        }

        /// <summary>
        /// 获取已设置的Input参数值
        /// 注:存储过程被成功执行后, Input参数被清空
        /// </summary>
        /// <param name="Key">参数名</param>
        /// <returns>参数值</returns>
        public Object GetInputValue(String Key)
        {
            if (Key == null)
            {
                return null;
            }
            if (!Key.StartsWith("@"))
            {
                Key = "@" + Key;
            }

            if (_InputTable.ContainsKey(Key))
            {
                return _InputTable[Key];
            }
            else
            {
                return null;
            }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 给SqlCommand对象绑定参数
        /// </summary>
        /// <returns>是否成功标志</returns>
        private Boolean Bindings()
        {
            _SqlCmd.Parameters.Clear();
            XmlReader sqlXmlReader = GetParameters();
            try
            {
                while (sqlXmlReader.Read())
                {
                    try
                    {
                        if (Byte.Parse(sqlXmlReader["isoutparam"]) == 1)
                        {
                            // 绑定output参数
                            _SqlCmd.Parameters.Add(sqlXmlReader["name"],
                             GetSqlDbType(sqlXmlReader["type"]),
                             Int32.Parse(sqlXmlReader["length"])).Direction = ParameterDirection.Output;
                        }
                        else
                        {
                            // 绑定input参数,并赋值
                            _SqlCmd.Parameters.Add(sqlXmlReader["name"],
                             GetSqlDbType(sqlXmlReader["type"]),
                             Int32.Parse(sqlXmlReader["length"])).Value = this.GetInputValue(sqlXmlReader["name"]);
                            /*
                             * 不必担心赋值的ParametersValue类型问题,SqlParameter.Value是object类型,自动转换
                             */
                        }
                    }
                    catch (Exception ex)
                    {
                        _LastError = sqlXmlReader["name"] + " parameter error: " + ex.Message;
                        return false;
                    }
                }

                // 绑定返回值
                _SqlCmd.Parameters.Add("RetVal", SqlDbType.Variant).Direction = ParameterDirection.ReturnValue;
            }
            catch (Exception ex)
            {
                _LastError = "binding parameter error: " + ex.Message;
                return false;
            }

            return true;
        }

        /// <summary>
        /// 由存储过程名, 取包含参数的XmlReader
        /// </summary>
        /// <param name="Procedure">存储过程名</param>
        /// <returns>包含参数的XmlReader</returns>
        private XmlReader GetParameters()
        {
            String sqlStr = "SELECT B.[name], C.[name] AS [type], B.length, B.isoutparam, B.isnullable";
            sqlStr += " FROM sysobjects AS A INNER JOIN";
            sqlStr += " syscolumns AS B ON A.id = B.id AND A.xtype = 'P' AND A.name = '" + _Procedure + "' INNER JOIN";
            sqlStr += " systypes C ON B.xtype = C.xtype AND C.[name] <> 'sysname'";
            sqlStr += " ORDER BY ROW_NUMBER() OVER (ORDER BY B.id), B.isoutparam";
            sqlStr += " FOR XML RAW";
            SqlCommand sqlCmd = new SqlCommand(sqlStr, _SqlConnection);
            // <row name="Action" type="varchar" length="50" isoutparam="0" isnullable="1" />
            XmlReader sqlXmlReader = null;
            try
            {
                sqlXmlReader = sqlCmd.ExecuteXmlReader();
            }
            catch (Exception ex)
            {
                if (sqlXmlReader != null) sqlXmlReader.Close();
                sqlXmlReader = null;
                _LastError = "get parameters error: " + ex.Message;
            }
            finally
            {
                sqlCmd.Dispose();
                sqlCmd = null;
            }
            return sqlXmlReader;
        }

        protected internal static SqlDbType GetSqlDbType(String TypeName)
        {
            switch (TypeName)
            {
                case "image":
                    return SqlDbType.Image;
                case "text":
                    return SqlDbType.Text;
                case "uniqueidentifier":
                    return SqlDbType.UniqueIdentifier;
                case "tinyint":
                    return SqlDbType.TinyInt;
                case "smallint":
                    return SqlDbType.SmallInt;
                case "int":
                    return SqlDbType.Int;
                case "smalldatetime":
                    return SqlDbType.SmallDateTime;
                case "real":
                    return SqlDbType.Real;
                case "money":
                    return SqlDbType.Money;
                case "datetime":
                    return SqlDbType.DateTime;
                case "float":
                    return SqlDbType.Float;
                case "sql_variant":
                    return SqlDbType.Variant;
                case "ntext":
                    return SqlDbType.NText;
                case "bit":
                    return SqlDbType.Bit;
                case "decimal":
                    return SqlDbType.Decimal;
                case "numeric":
                    return SqlDbType.Decimal;
                case "smallmoney":
                    return SqlDbType.SmallMoney;
                case "bigint":
                    return SqlDbType.BigInt;
                case "varbinary":
                    return SqlDbType.VarBinary;
                case "varchar":
                    return SqlDbType.VarChar;
                case "binary":
                    return SqlDbType.Binary;
                case "char":
                    return SqlDbType.Char;
                case "timestamp":
                    return SqlDbType.Timestamp;
                case "nvarchar":
                    return SqlDbType.NVarChar;
                case "nchar":
                    return SqlDbType.NChar;
                case "xml":
                    return SqlDbType.Xml;
                default:
                    return SqlDbType.Variant;
            }
        }
        #endregion
    }
}


 

// 调用示例
// 设置连接对象
CEx_SqlProcedure SqlProcedure = new CEx_SqlProcedure("doArticle", SqlConnection);
// 填充参数
SqlProcedure.SetInputValue("@Action", "GetArticles");
SqlProcedure.SetInputValue("@Keywords", Keyword);
SqlProcedure.SetInputValue("@SortID", Sort);
SqlProcedure.SetInputValue("@CurPage", CurPage);
SqlProcedure.SetInputValue("@PageSize", PageSize);
// 执行
SqlProcedure.ExecuteAdapter().Fill(sqlDataSet);
// 取output和返回值(为了简洁,我直接用object)
object MaxPage = SqlProcedure.GetOutputValue("@MaxPage");
object ReturnValue = SqlProcedure.ReturnValue;


 

 


本文转载:CSDN博客