首页 > 开发 > 综合 > 正文

SQLHelper.cs

2024-07-21 02:26:13
字体:
来源:转载
供稿:网友

//copyright(c) 2000-2006 shixin corporation
//all rights reserverd
//文件名: sqlhelper.cs
//创建者:
//创建日期: 2006-03-21
//概述: dataaccess层的数据访问helper文件,模仿自microsoft daab1.0。
//修改人/修改日期: 
//开放str_connection连接字符串,因为sqlconnection是非托管资源,无法自动回收。

using system;
using system.data;
using system.xml;
using system.data.sqlclient;
using system.collections;
using system.configuration;
using system.collections.specialized;

using sps.common;


namespace sps.dataaccess
{
    /**//// <summary>
    /// sqlhelper 被dataaccess里的任何类调用,执行insert,update,setvalid和select等组成的存储过程
    /// </summary>
    public class sqlhelper
    {
        //缓存sqlparameter数组对象的hashtable
        private static hashtable paramcache = hashtable.synchronized(new hashtable());

        //连接字符串
        public static string str_connection;

        //sqlconnection
        //private static sqlconnection conn;

        "public functions"#region "public functions"
        /**//// <summary>
        /// 获取sqlconnection
        /// </summary>
        /// <remark>
        /// 因为sqlconnection不是托管资源,所以在这里无法回收,所以在这里屏蔽掉
        /// </remark>
        /// <returns>sqlconnection对象</returns>
//        public static sqlconnection getconnection()
//        {
//            if(conn==null)
//                conn=new sqlconnection(str_connection);
//            return conn;
//        }

        /**//// <summary>
        /// 执行xxxinsert,xxxupdate,xxxsetvalid类型的存储过程
        /// </summary>
        /// <remarks>
        /// 参数hashtable里的key名需要和存储过程里的参数名保持一致;
        /// 存储过程的参数全部要在hashtable中存在;
        /// </remarks>
        /// <param name="hashtable">由存储过程参数组成的hashtable</param>
        /// <param name="strspname">存储过程名称</param>
        /// <returns>insert情况的pkid、或update、setvalid情况的改变记录数</returns>
        public static int modifytable(hashtable hashtable,string strspname)
        {
            //获取sql连接
            //sqlconnection conn=getconnection();
            using(sqlconnection conn=new sqlconnection(str_connection))
            {
                //依据连接字符串和存储过程名称 构造出这个存储过程的参数数组
                sqlparameter[] sqlparas=getspparameterset(conn.connectionstring,strspname);

                //循环位每个存储参数数组的元素赋值   
                for(int i=0,j=sqlparas.length;i<j;i++)
                {
                    string strkeyname=sqlparas[i].parametername;
               
                    //当没有输入参数
                    try
                    {sqlparas[i].value=hashtable[strkeyname];}
                    catch
                    {sqlparas[i].value=null;}
                   
                    //如果输入参数是null
                    if(sqlparas[i].value==null)
                    {
                        switch(sqlparas[i].sqldbtype)
                        {
                            case sqldbtype.int:
                                sqlparas[i].value=-1;
                                break;
                            case sqldbtype.decimal:
                                sqlparas[i].value=-1;
                                break;
                            default:
                                sqlparas[i].value=dbnull.value;
                                break;
                        }
                    }
                }
               
                //执行存储过程
                sqlhelper.executenonquery(conn,commandtype.storedprocedure,strspname,sqlparas);

                //取出输出参数的值,
                //注意: insert,update,setvalid存储过程,只允许第一个参数类型为 out
                return (int)sqlparas[0].value;
            }
        }
       
        /**//// <summary>
        /// 执行getxxx类型的存储过程
        /// </summary>
        /// <remarks>
        /// 参数hashtable里的key名需要和存储过程里的参数名保持一致;
        /// 存储过程的参数全部要在hashtable中存在;
        /// </remarks>
        /// <param name="hashtable">由存储过程参数组成的hashtable</param>
        /// <param name="strspname">存储过程名称</param>
        /// <returns>dataset</returns>
        public static dataset getdataset(hashtable hashtable,string strspname)
        {
            //获取sql连接
            //sqlconnection conn=getconnection();

            using(sqlconnection conn=new sqlconnection(str_connection))
            {
                //依据连接字符串和存储过程名称 构造出这个存储过程的参数数组
                sqlparameter[] sqlparas=getspparameterset(conn.connectionstring,strspname);

                //循环位每个存储参数数组的元素赋值   
                for(int i=0,j=sqlparas.length;i<j;i++)
                {
                    string strkeyname=sqlparas[i].parametername;

                    //当没有输入参数
                    try
                    {sqlparas[i].value=hashtable[strkeyname];}
                    catch
                    {sqlparas[i].value=null;}
                   
                    //如果输入参数是null
                    if(sqlparas[i].value==null)
                    {
                        switch(sqlparas[i].sqldbtype)
                        {
                            case sqldbtype.int:
                                sqlparas[i].value=-1;
                                break;
                            case sqldbtype.decimal:
                                sqlparas[i].value=-1;
                                break;
                            default:
                                sqlparas[i].value=dbnull.value;
                                break;
                        }
                    }
                }
               
                //执行存储过程
                dataset dtreturn=sqlhelper.executedataset(conn,commandtype.storedprocedure,strspname,sqlparas);

                //返回结果集
                return dtreturn;
            }
        }
        #endregion

       
        private utility methods & constructors#region private utility methods & constructors

        static sqlhelper()
        {
            namevaluecollection nvc=(namevaluecollection)configurationsettings.getconfig("database");
            str_connection="server="+ desencryptor.desdecrypt(nvc["server"])
                +";database="+ desencryptor.desdecrypt(nvc["database"]) +";uid="
                + desencryptor.desdecrypt(nvc["uid"])
                +";pwd="+ desencryptor.desdecrypt(nvc["pwd"]) +"";
//            str_connection="server=.;database=ql_sps;uid=sa;pwd=sa";
        }

        /**//// <summary>
        /// 把sqlparameter数组赋值给command
        ///
        /// this behavior will prevent default values from being used, but
        /// this will be the less common case than an intended pure output parameter (derived as inputoutput)
        /// where the user provided no input value.
        /// </summary>
        /// <param name="command">要添加参数的sqlcommand</param>
        /// <param name="commandparameters">被添加的sqlparameter数组</param>
        private static void attachparameters(sqlcommand command, sqlparameter[] commandparameters)
        {
            foreach (sqlparameter p in commandparameters)
            {
                //check for derived output value with no value assigned
                if ((p.direction == parameterdirection.inputoutput) && (p.value == null))
                {
                    p.value = dbnull.value;
                }
               
                command.parameters.add(p);
            }
        }

        /**//// <summary>
        /// 按需创建sqlcommand,并且设定connection,transaction,命令类别
        /// </summary>
        /// <param name="command">要创建的sqlcommand</param>
        /// <param name="connection">sql server连接</param>
        /// <param name="transaction">事务或null值</param>
        /// <param name="commandtype">命令类别 (stored procedure)</param>
        /// <param name="commandtext">存储过程名称</param>
        /// <param name="commandparameters">与sqlcommand有关的参数或null值</param>
        private static void preparecommand(sqlcommand command, sqlconnection connection, sqltransaction transaction, commandtype commandtype, string commandtext, sqlparameter[] commandparameters)
        {
            //如果连接没有打开,则打开连接
            if (connection.state != connectionstate.open)
            {
                connection.open();
            }

            //把数据库连接与sqlcommand关联起来
            command.connection = connection;

            //设置存储过程名称
            command.commandtext = commandtext;

            //如果需要transaction,则设置transaction
            if (transaction != null)
            {
                command.transaction = transaction;
            }

            //设置命令类型
            command.commandtype = commandtype;

            //添加参数
            if (commandparameters != null)
            {
                attachparameters(command, commandparameters);
            }

            return;
        }

       
        /**//// <summary>
        ///  执行一个不返回结果集的存储过程
        /// </summary>
        /// <remarks>
        /// e.g.: 
        ///  int result = executenonquery(conn, commandtype.storedprocedure, "publishorders", new sqlparameter("@prodid", 24));
        /// </remarks>
        /// <param name="connection">sql server数据库连接</param>
        /// <param name="commandtype">命令类型 (stored procedure)</param>
        /// <param name="commandtext">存储过程名</param>
        /// <param name="commandparameters">参数数组</param>
        /// <returns>返回命令所影响的记录数</returns>
        private static int executenonquery(sqlconnection connection, commandtype commandtype, string commandtext, params sqlparameter[] commandparameters)
        {   
            //创建一个sqlcommand
            sqlcommand cmd = new sqlcommand();
            preparecommand(cmd, connection, (sqltransaction)null, commandtype, commandtext, commandparameters);
           
            //finally, execute the command.
            int retval = cmd.executenonquery();
   
            // detach the sqlparameters from the command object, so they can be used again.
            cmd.parameters.clear();
            return retval;
        }
       
       
       
        /**//// <summary>
        /// 执行一个带参数的存储过程,返回一个结果集
        /// </summary>
        /// <remarks>
        /// e.g.: 
        ///  dataset ds = executedataset(conn, commandtype.storedprocedure, "getorders", new sqlparameter("@prodid", 24));
        /// </remarks>
        /// <param name="connection">sql server连接</param>
        /// <param name="commandtype">命令类别(stored procedure)</param>
        /// <param name="commandtext">存储过程名称</param>
        /// <param name="commandparameters">参数数组</param>
        /// <returns>返回的dataset</returns>
        private static dataset executedataset(sqlconnection connection, commandtype commandtype, string commandtext, params sqlparameter[] commandparameters)
        {
            //创建一个命令
            sqlcommand cmd = new sqlcommand();
            preparecommand(cmd, connection, (sqltransaction)null, commandtype, commandtext, commandparameters);
           
            //创建 dataadapter 和 dataset
            sqldataadapter da = new sqldataadapter(cmd);
            dataset ds = new dataset();

            da.fill(ds);       
            cmd.parameters.clear();
           
            //返回结果集
            return ds;                       
        }

        /**//// <summary>
        /// 从存储过程里面,构造出sqlparameter数组
        /// </summary>
        /// <param name="connectionstring">sql server连接字符串</param>
        /// <param name="spname">存储过程名称</param>
        /// <param name="includereturnvalueparameter">标志是否把返回值加入sqlparameter数组</param>
        /// <returns>sqlparameter数组</returns>
        private static sqlparameter[] discoverspparameterset(string connectionstring, string spname, bool includereturnvalueparameter)
        {
           
            using (sqlconnection cn = new sqlconnection(connectionstring))
            using (sqlcommand cmd = new sqlcommand(spname,cn))
            {
                cn.open();
                cmd.commandtype = commandtype.storedprocedure;

                //要返回的数组从下面而来
                sqlcommandbuilder.deriveparameters(cmd);

                if (!includereturnvalueparameter)
                {
                    //默认sqlparameter数组的第一个元素是存储过程的返回值
                    cmd.parameters.removeat(0);
                }

                sqlparameter[] discoveredparameters = new sqlparameter[cmd.parameters.count];

                cmd.parameters.copyto(discoveredparameters, 0);

                return discoveredparameters;
            }
        }

        //深拷贝缓存里的参数数组
        private static sqlparameter[] cloneparameters(sqlparameter[] originalparameters)
        {
            sqlparameter[] clonedparameters = new sqlparameter[originalparameters.length];
            for (int i = 0, j = originalparameters.length; i < j; i++)
            {
                clonedparameters[i] = (sqlparameter)((icloneable)originalparameters[i]).clone();
            }
            return clonedparameters;
        }

        /**//// <summary>
        /// 从存储过程解析出这个存储过程的参数的集合
        /// </summary>
        /// <remarks>
        /// 首先从数据库查询, 然后缓存起来供以后调用
        /// </remarks>
        /// <param name="connectionstring">sql server 的 connection string</param>
        /// <param name="spname">存储过程名称</param>
        /// <returns>sqlparameters数组</returns>
        public static sqlparameter[] getspparameterset(string connectionstring, string spname)
        {
            return getspparameterset(connectionstring, spname, false);
        }

        /**//// <summary>
        /// 从存储过程解析出这个存储过程的参数的集合
        /// </summary>
        /// <remarks>
        /// 首先从数据库查询, 然后缓存起来供以后调用
        /// </remarks>
        /// <param name="connectionstring">sql server 的 connection string</param>
        /// <param name="spname">存储过程名称</param>
        /// <param name="includereturnvalueparameter">标志返回值是否放到返回的参数数组</param>
        /// <returns>sqlparameters数组</returns>
        private static sqlparameter[] getspparameterset(string connectionstring, string spname, bool includereturnvalueparameter)
        {
            //定义key
            string hashkey = connectionstring + ":" + spname + (includereturnvalueparameter ? ":include returnvalue parameter":"");

            sqlparameter[] cachedparameters;
           
            //依据key从缓存hashtable里取出值
            cachedparameters = (sqlparameter[])paramcache[hashkey];

            if (cachedparameters == null)
            {    //如果取出的值是null,则从数据库获取存储过程的所有参数,并且放入缓存       
                cachedparameters = (sqlparameter[])(paramcache[hashkey] = discoverspparameterset(connectionstring, spname, includereturnvalueparameter));
            }
           
            return cloneparameters(cachedparameters);
        }   
        #endregion
    }   
}

项目中一直使用的一个类,觉得还是蛮好用的。
public abstract class sqlhelper {
 
        public sqlhelper() {
        }
       
        /**//// <summary>
        /// 连接字符串
        /// </summary>
        public static string conn_string = "provider=microsoft.jet.oledb.4.0;data source="+ environment.currentdirectory + @"/salarystat.mdb;user id=admin;password=;jet oledb:database password=tcyald";

        /**//// <summary>
        /// 用于执行一段sql语句,只有三个最简的必要参数,省去了commandtype。
        /// to excute a sql statement, which reuturns a integer stand for effect line number.
        /// default command type is text
        /// </summary>
        /// <param name="connstring">连接字符串 (conntection string)</param>
        /// <param name="cmdtext">command的字符串 (sql statement)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>返回影响行数 (effect line number)</returns>
        public static int executenonquery(string connstring, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();

            using (oledbconnection conn = new oledbconnection(connstring)) {
                preparecommand(cmd, conn, null, commandtype.text, cmdtext, cmdparms);
   
                int val = cmd.executenonquery();
                cmd.parameters.clear();
                return val;
   
            }
        }

        /**//// <summary>
        /// 用于执行一段sql语句。
        /// to excute a sql statement, which reuturns a integer stand for effect line number.
        /// </summary>
        /// <param name="connstring">连接字符串 (connection string)</param>
        /// <param name="cmdtype">command的字符串 (sql statement)</param>
        /// <param name="cmdtext">command的类型,具体见:commandtype (command type)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>返回影响行数 (effect line number)</returns>
        public static int executenonquery(string connstring, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {

            oledbcommand cmd = new oledbcommand();

            using (oledbconnection conn = new oledbconnection(connstring)) {
                preparecommand(cmd, conn, null, cmdtype, cmdtext, cmdparms);
                int val = cmd.executenonquery();
                cmd.parameters.clear();
                return val;
            }
        }

        /**//// <summary>
        /// 用于执行一段sql语句。传入的值是connection.
        /// to excute a sql statement, which reuturns a integer stand for effect line number.
        /// a connection is passed in instead of a connection string
        /// </summary>
        /// <param name="conn">一个以初始化好的oledbconnection (a conncection)</param>
        /// <param name="connstring">连接字符串 (conntection string)</param>
        /// <param name="cmdtext">command的字符串 (sql statement)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>返回影响行数 (effect line number)</returns>
        public static int executenonquery(oledbconnection conn, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {

            oledbcommand cmd = new oledbcommand();

            preparecommand(cmd, conn, null, cmdtype, cmdtext, cmdparms);
            int val = cmd.executenonquery();
            cmd.parameters.clear();
            return val;
        }

        /**//// <summary>
        /// 用于执行一段sql语句。需要传入一个事务transaction.
        /// to excute a sql statement, which reuturns a integer stand for effect line number.
        /// a transaction is reqired
        /// </summary>
        /// <param name="trans">一个trasaction (trasaction)</param>
        /// <param name="cmdtype">command的字符串 (sql statement)</param>
        /// <param name="cmdtext">command的类型,具体见:commandtype (command type)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>返回影响行数 (effect line number)</returns>
        public static int executenonquery(oledbtransaction trans, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();
            preparecommand(cmd, trans.connection, trans, cmdtype, cmdtext, cmdparms);
            int val = cmd.executenonquery();
            cmd.parameters.clear();
            return val;
        }

        /**//// <summary>
        /// 用于执行一个select语句返回一个datareader,省略了commandtype参数
        /// to excute a sql statement, and reuturns a datareader.
        /// default command type is text
        /// </summary>
        /// <param name="connstring">连接字符串 (conntection string)</param>
        /// <param name="cmdtext">command的字符串 (sql statement)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>datareader</returns>
        public static oledbdatareader executereader(string connstring, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();
            oledbconnection conn = new oledbconnection(connstring);

            // we use a try/catch here because if the method throws an exception we want to
            // close the connection throw code, because no datareader will exist, hence the
            // commandbehaviour.closeconnection will not work
            try {
                preparecommand(cmd, conn, null, commandtype.text, cmdtext, cmdparms);
                oledbdatareader rdr = cmd.executereader(commandbehavior.closeconnection);
                //    cmd.parameters.clear();
                return rdr;
            }
            catch {
                conn.close();
                throw;
            }
        }

        /**//// <summary>
        /// 用于执行一个select语句返回一个datareader
        /// to excute a sql statement, and reuturns a datareader.
        /// </summary>
        /// <param name="connstring">连接字符串 (connection string)</param>
        /// <param name="cmdtype">command的字符串 (sql statement)</param>
        /// <param name="cmdtext">command的类型,具体见:commandtype (command type)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>datareader</returns>
        public static oledbdatareader executereader(string connstring, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();
            oledbconnection conn = new oledbconnection(connstring);

            // we use a try/catch here because if the method throws an exception we want to
            // close the connection throw code, because no datareader will exist, hence the
            // commandbehaviour.closeconnection will not work
            try {
                preparecommand(cmd, conn, null, cmdtype, cmdtext, cmdparms);
                oledbdatareader rdr = cmd.executereader(commandbehavior.closeconnection);
                //    cmd.parameters.clear();
                return rdr;
            }
            catch {
                conn.close();
                throw;
            }
        }

        /**//// <summary>
        /// 用于读取一个值,查询所返回的是结果集中第一行的第一列,省去了commandtype
        /// to excute , a sql statement, and returns the first column of the first line
        /// default command type is text
        /// </summary>
        /// <param name="connstring">连接字符串 (conntection string)</param>
        /// <param name="cmdtext">command的字符串 (sql statement)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>the first column of the first line</returns>
        public static object executescalar(string connstring, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();

            using (oledbconnection conn = new oledbconnection(connstring)) {
                preparecommand(cmd, conn, null, commandtype.text, cmdtext, cmdparms);
                object val = cmd.executescalar();
                cmd.parameters.clear();
                return val;
            }
        }

        /**//// <summary>
        /// 用于读取一个值,查询所返回的是结果集中第一行的第一列
        /// to excute a sql statement, and returns the first column of the first line
        /// </summary>
        /// <param name="connstring">连接字符串 (connection string)</param>
        /// <param name="cmdtype">command的字符串 (sql statement)</param>
        /// <param name="cmdtext">command的类型,具体见:commandtype (command type)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>the first column of the first line</returns>
        public static object executescalar(string connstring, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {
            oledbcommand cmd = new oledbcommand();

            using (oledbconnection conn = new oledbconnection(connstring)) {
                preparecommand(cmd, conn, null, cmdtype, cmdtext, cmdparms);
                object val = cmd.executescalar();
                cmd.parameters.clear();
                return val;
            }
        }


        /**//// <summary>
        /// 用于读取一个值,查询所返回的是结果集中第一行的第一列
        /// to excute a sql statement, and returns the first column of the first line
        /// a connection is passed in instead of a connection string
        /// </summary>
        /// <param name="conn">一个以初始化好的oledbconnection (a conncection)</param>
        /// <param name="connstring">连接字符串 (conntection string)</param>
        /// <param name="cmdtext">command的字符串 (sql statement)</param>
        /// <param name="cmdparms">参数列表 (paramters)</param>
        /// <returns>the first column of the first line</returns>
        public static object executescalar(oledbconnection conn, commandtype cmdtype, string cmdtext, params oledbparameter[] cmdparms) {
  
            oledbcommand cmd = new oledbcommand();

            preparecommand(cmd, conn, null, cmdtype, cmdtext, cmdparms);
            object val = cmd.executescalar();
            cmd.parameters.clear();
            return val;
        }

        /**//// <summary>
        /// 在执行sql语句之前的准备工作
        /// </summary>
        /// <param name="cmd">command</param>
        /// <param name="conn">connection</param>
        /// <param name="trans">trasaction</param>
        /// <param name="cmdtype">command类型</param>
        /// <param name="cmdtext">command字符串</param>
        /// <param name="cmdparms">参数列表</param>
        private static void preparecommand(oledbcommand cmd, oledbconnection conn, oledbtransaction trans, commandtype cmdtype, string cmdtext, oledbparameter[] cmdparms) {

            if (conn.state != connectionstate.open)
                conn.open();

            cmd.connection = conn;
            cmd.commandtext = cmdtext;

            if (trans != null)
                cmd.transaction = trans;

            cmd.commandtype = cmdtype;

            if (cmdparms != null) {
                foreach (oledbparameter parm in cmdparms)
                    cmd.parameters.add(parm);
            }
        }

        /**//// <summary>
        /// 根据sql语句查询返回dataset
        /// </summary>
        /// <param name="sqlstring">查询的sql语句</param>
        /// <returns>dataset</returns>
        public static dataset getdataset(string sqlstring) {
            using (oledbconnection connection = new oledbconnection(conn_string)) {
                dataset ds = new dataset();
                try {
                    connection.open();
                    oledbdataadapter command = new oledbdataadapter(sqlstring,connection);
                    command.fill(ds,"ds");
                }
                catch(system.data.oledb.oledbexception ex) {
                    throw new exception(ex.message);
                }
                return ds;
            }
        }
 
        /**//// <summary>
        /// 根据sql语句和查询参数查询返回dataset
        /// </summary>
        /// <param name="sqlstring">查询的sql语句</param>
        /// <param name="cmdparms">参数</param>
        /// <returns>dataset</returns>
        public static dataset getdataset(string sqlstring,params oledbparameter[] cmdparms) {
            using (oledbconnection connection = new oledbconnection(conn_string)) {
                oledbcommand cmd = new oledbcommand();
                preparecommand(cmd, connection, null,commandtype.text,sqlstring, cmdparms);
                using( oledbdataadapter da = new oledbdataadapter(cmd) ) {
                    dataset ds = new dataset();
                    try {
                        da.fill(ds,"ds");
                        cmd.parameters.clear();
                    }
                    catch(system.data.oledb.oledbexception ex) {
                        throw new exception(ex.message);
                    }
                    return ds;
                }
            }
        }
    }

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表