using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace LZBS.DBUtility
{
    public class SqlHelp
        {
            #region 定义字段及其属性
            /// <summary>
            /// 定义连接字符串
            /// </summary>
            private static string connString = System.Configuration.ConfigurationSettings.AppSettings["ConnString"].ToString();
            /// <summary>
            /// 定义连接字段conn
            /// </summary>
            private static SqlConnection conn;
            /// <summary>
            /// 定义连接字符串属性
            /// </summary>
            public static string ConnString
            {
                get { return SqlHelp.connString; }
                set { SqlHelp.connString = value; }
            }
            /// <summary>
            /// 定义连接字段属性
            /// </summary>
            public static SqlConnection Conn
            {
                get { return SqlHelp.conn; }
                set { SqlHelp.conn = value; }
            }
            #endregion

            /// <summary>
            /// 构造函数
            /// </summary>
            //static SqlHelp()
            //{
            //    //对于单个的类，它的静态构造函数将先于普通构造函数执行，
            //    //因为普通构造函数需要在实例化该类的时候执行，
            //    //而静态构造函数访问该类的同时就开始执行。
            //    //而对于有继承关系的父类和子类来说，父类的普通构造函数先于子类的普通构造函数执行，
            //    //简而言之就是被依赖的先构造，依赖于人的后构造。
            //    ConnString = System.Configuration.ConfigurationSettings.AppSettings["ConnString"].ToString();
            //}

            public SqlHelp()
            {
            }

            #region  执行简单SQL语句

            /// <summary>
            /// 用于执行SQL语句，针对Update,Insert,Delete操作,成功则返回影响的行数，失败返回-1
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <returns>针对Update,Insert,Delete操作，成功则返回影响的行数，失败返回-1</returns>
            public static int ExecuteSQL(string sqlString)
            {
                SqlCommand cmd = new SqlCommand();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    cmd.CommandText = sqlString;
                    cmd.Connection = Conn;
                    if (Conn.State == ConnectionState.Closed)
                        Conn.Open();
                    int rows = cmd.ExecuteNonQuery();
                    return rows;
                }
                catch (SqlException e)
                {
                    throw e;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            /// <summary>
            /// 用于执行带参数的SQL语句，针对Update,Insert,Delete操作
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <param name="cmdParms">参数列表</param>
            /// <returns>返回影响的行数</returns>
            public static int ExecuteSQL(string sqlString, params SqlParameter[] cmdParams)
            {
                SqlCommand cmd = new SqlCommand();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    PrepareCommand(cmd, sqlString, cmdParams);
                    int rows = cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                    return rows;
                }
                catch (SqlException e)
                {
                    throw e;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            /// <summary>
            /// 用于执行SQL语句，针对Update,Insert,Delete操作,
            /// 并且设置在终止执行命令的尝试并生成错误之前的等待时间
            /// 默认值为 30 秒
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <param name="Times">设置在终止执行命令的尝试并生成错误之前的等待时间</param>
            /// <returns>针对Update,Insert,Delete操作，成功则返回影响的行数，失败返回-1</returns>
            public static int ExecuteSQL(string sqlString, int Times)
            {

                SqlCommand cmd = new SqlCommand();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    cmd.CommandText = sqlString;
                    cmd.Connection = Conn;
                    cmd.CommandTimeout = Times;
                    int rows = cmd.ExecuteNonQuery();
                    return rows;
                }
                catch (SqlException e)
                {
                    throw e;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            /// <summary>
            /// 根据指定的select语句返回一个DataTable
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <returns>根据指定的select语句返回一个DataTable</returns>
            public static DataTable GetDataTable(string sqlString)
            {
                using (Conn = new SqlConnection(ConnString))
                {
                    try
                    {
                        SqlDataAdapter sda = new SqlDataAdapter(sqlString, Conn);
                        DataSet ds = new DataSet();
                        sda.Fill(ds);
                        DataTable dt = ds.Tables[0];
                        ds.Dispose();
                        sda.Dispose();
                        return dt;
                    }
                    catch (SqlException e)
                    {
                        throw e;
                    }
                    finally
                    {
                        if (Conn.State == ConnectionState.Open)
                            Conn.Dispose();
                    }
                }
            }

            /// <summary>
            /// 根据指定的select语句返回
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <param name="cmdParms">参数列表</param>
            /// <returns>一个DataTable</returns>
            public static DataTable GetDataTable(string sqlString, SqlParameter[] cmdParams)
            {
                SqlCommand cmd = new SqlCommand();
                DataSet ds = new DataSet();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    PrepareCommand(cmd, sqlString, cmdParams);
                    SqlDataAdapter sda = new SqlDataAdapter(cmd);
                    sda.Fill(ds);
                    cmd.Parameters.Clear();
                    DataTable dt = ds.Tables[0];
                    return dt;
                }
                catch (SqlException e)
                {
                    throw e;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    ds.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }


            /// <summary>
            /// 根据指定的Select语句获取集合中的第一行条数据
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <returns>若有结果返回第一行条数据，否则返回null</returns>
            public static DataRow GetFirstRow(string sqlString, SqlParameter[] cmdParams)
            {
                DataTable dt = GetDataTable(sqlString, cmdParams);
                if (dt.Rows.Count > 0)
                {
                    return dt.Rows[0];
                }
                else
                {
                    return null;
                }
            }

            /// <summary>
            /// 根据指定的Select语句获取集合中的第一行条数据
            /// </summary>
            /// <param name="sqlString">SQL语句</param>
            /// <param name="cmdParams">参数列表</param>
            /// <returns>若有结果返回第一行条数据，否则返回null</returns>
            public static DataRow GetFirstRow(string sqlString)
            {
                DataTable dt = GetDataTable(sqlString);
                if (dt.Rows.Count > 0)
                {
                    return dt.Rows[0];
                }
                else
                {
                    return null;
                }
            }

            /// <summary>
            /// 执行多条SQL语句，实现数据库事务
            /// </summary>
            /// <param name="SQLStringList">多条SQL语句</param>
            /// <returns>成功则返回影响的行数，失败返回0</returns>
            public static int ExecuteSqlTran(List<String> sqlStringList)
            {
                SqlCommand cmd = new SqlCommand();
                Conn = new SqlConnection(ConnString);
                if (Conn.State == ConnectionState.Closed)
                    Conn.Open();
                SqlTransaction tx = Conn.BeginTransaction();
                try
                {
                    cmd.Connection = Conn;
                    cmd.Transaction = tx;
                    int count = 0;
                    for (int i = 0; i < sqlStringList.Count; i++)
                    {
                        string strsql = sqlStringList[i];
                        if (strsql.Trim().Length > 1)
                        {
                            cmd.CommandText = strsql;
                            count += cmd.ExecuteNonQuery();
                        }
                    }
                    tx.Commit();
                    return count;
                }
                catch
                {
                    tx.Rollback();
                    return 0;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            #endregion

            #region 生成对应的SqlCommand命令对象

            /// <summary>
            /// 根据SQL语句和参数生成对应的SQL命令对象
            /// </summary>
            /// <param name="cmd">SqlCommand 对象</param>
            /// <param name="cmdText">SQL语句</param>
            /// <param name="cmdParms">SQL参数数组</param>
            private static void PrepareCommand(SqlCommand cmd, string cmdText, SqlParameter[] cmdParams)
            {
                if (Conn.State != ConnectionState.Open)
                    Conn.Open();
                cmd.Connection = Conn;
                cmd.CommandText = cmdText;
                if (cmdParams != null)
                {
                    foreach (SqlParameter parameter in cmdParams)
                    {
                        if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
                            (parameter.Value == null))
                        {
                            parameter.Value = DBNull.Value;
                        }
                        cmd.Parameters.Add(parameter);
                    }
                }
            }

            ///// <summary>
            ///// 根据SQL语句和参数生成对应的SQL命令对象
            ///// </summary>
            ///// <param name="cmd">SqlCommand 对象</param>
            ///// <param name="trans">SqlTransaction 组件，可以为null</param>
            ///// <param name="cmdText">SQL语句</param>
            ///// <param name="cmdParms">SQL参数数组</param>
            //private static void PrepareCommand(SqlCommand cmd, SqlTransaction trans, string cmdText, SqlParameter[] cmdParms)
            //{
            //    if (Conn.State != ConnectionState.Open)
            //        Conn.Open();
            //    cmd.Connection = Conn;
            //    if (trans != null)
            //        cmd.Transaction = trans;
            //    cmd.CommandText = cmdText;
            //    if (cmdParms != null)
            //    {
            //        foreach (SqlParameter parameter in cmdParms)
            //        {
            //            if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
            //                (parameter.Value == null))
            //            {
            //                parameter.Value = DBNull.Value;
            //            }
            //            cmd.Parameters.Add(parameter);
            //        }
            //    }
            //}

            /// <summary>
            /// 根据存储过程名称和参数生成对应的SQL命令对象
            /// </summary>
            /// <param name="cmd">SqlCommand 对象</param> 
            /// <param name="storedProcName">存储过程名</param>
            /// <param name="parameters">存储过程参数</param>
            /// <returns></returns>
            private static SqlCommand PrepareProcedureCommand(SqlCommand cmd, string storedProcName, SqlParameter[] cmdParms)
            {
                if (Conn.State != ConnectionState.Open)
                    Conn.Open();
                cmd.Connection = Conn;
                cmd.CommandText = storedProcName;
                cmd.CommandType = CommandType.StoredProcedure;
                foreach (SqlParameter parameter in cmdParms)
                {
                    if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
                        (parameter.Value == null))
                    {
                        parameter.Value = DBNull.Value;
                    }
                    cmd.Parameters.Add(parameter);
                }
                return cmd;
            }
            #endregion

            #region 存储过程

            /// <summary>
            /// 根据存储过程名称获取一个 DataTable
            /// </summary>
            /// <param name="ProcName">存储过程名称</param>
            /// <returns>返回一个 DataTable</returns>
            public static DataTable RunProcedure(string ProcName)
            {
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand();
                SqlDataAdapter sda = new SqlDataAdapter();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    if (Conn.State != ConnectionState.Open)
                        Conn.Open();
                    cmd.Connection = Conn;
                    cmd.CommandText = ProcName;
                    cmd.CommandType = CommandType.StoredProcedure;
                    sda.SelectCommand = cmd;
                    sda.Fill(ds);
                    DataTable dt = ds.Tables[0];
                    return dt;
                }
                catch
                {
                    return null;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    ds.Dispose();
                    sda.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }


            /// <summary>
            /// 根据存储过程名称和参数获取一个 DataTable
            /// </summary>
            /// <param name="ProcName">存储过程名称</param>
            /// <param name="parameters">存储过程参数</param>
            /// <returns>返回一个 DataTable</returns>
            public static DataTable RunProcedure(string ProcName, SqlParameter[] parameters)
            {
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand();
                SqlDataAdapter sda = new SqlDataAdapter();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    sda.SelectCommand = PrepareProcedureCommand(cmd, ProcName, parameters);
                    sda.Fill(ds);
                    DataTable dt = ds.Tables[0];
                    cmd.Parameters.Clear();
                    return dt;
                }
                catch
                {
                    return null;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    ds.Dispose();
                    sda.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }
            /// <summary>
            /// 根据存储过程名称和参数获取一个 DataTable
            /// </summary>
            /// <param name="ProcName">存储过程名称</param>
            /// <param name="parameters">存储过程参数</param>
            /// <param name="Times">设置在终止执行命令的尝试并生成错误之前的等待时间</param>
            /// <returns>返回一个 DataTable</returns>
            public static DataTable RunProcedure(string ProcName, SqlParameter[] parameters, int Times)
            {
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand();
                SqlDataAdapter sda = new SqlDataAdapter();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    sda.SelectCommand = PrepareProcedureCommand(cmd, ProcName, parameters);
                    sda.SelectCommand.CommandTimeout = Times;
                    sda.Fill(ds);
                    DataTable dt = ds.Tables[0];
                    cmd.Parameters.Clear();
                    return dt;
                }
                catch
                {
                    return null;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    ds.Dispose();
                    sda.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            /// <summary>
            /// 针对Update,Insert,Delete操作的存储过程,成功则返回影响的行数，失败返回-1
            /// </summary>
            /// <param name="ProcName">存储过程名称</param>
            /// <param name="parameters">存储过程参数</param>
            /// <returns></returns>
            public static int GetEffectProcedure(string ProcName, SqlParameter[] parameters)
            {
                SqlCommand cmd = new SqlCommand();
                try
                {
                    Conn = new SqlConnection(ConnString);
                    cmd = PrepareProcedureCommand(cmd, ProcName, parameters);
                    int rows = cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                    return rows;
                }
                catch (SqlException e)
                {
                    throw e;
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                    if (Conn.State == ConnectionState.Open)
                        Conn.Dispose();
                }
            }

            #endregion
        }
}
