原生C++下模拟.Net平台的 DataTable,DataRow,只有部分功能,以后转Qt版和Python版。

news2024/9/19 10:34:08

C#  db_

C++ CLI   csharp_db

C++  _db

_db.h

/*******************************************************************************************
文件名						: _db.h

作者							: 李锋

功能							: 数据库操作

创建时间						: 2023年10月30日

最后一次修改时间				:  2024年08月11日
********************************************************************************************/
#pragma once

#include"_database_in.h"

_LF_BEGIN_









/*****************************************************************

                        前置声明

 ****************************************************************/
class _db;
class _table;
class _field;
class _DataTable;
class _DataColumn;
class _DataRow;
class _FieldValue;

/*****************************************************************

                        _DataFormat

*****************************************************************/


/*

    /// <summary>
    /// 数据访问格式
    /// </summary>
    enum _DataFormat
    {
        dfMDB,                      //Access2000,2003数据库
        dfAccdb,                    //2007数据库
        dfDBF,
        dfDB,
        dfInterBase,
        dfSQLServer,                //SQL数据库
        dfOracle,                   //Oracle数据库
        dfSybase,
        dfInformix,
        dfDB2,
        dfSQLite,                   //Android数据库
        dfMySQL
    };
*/


/// <summary>
/// 数据访问格式
/// </summary>
enum class _DataFormat
{
    dfMDB,                      //Access2000,2003数据库
    dfAccdb,                    //2007数据库
    dfDBF,
    dfDB,
    dfInterBase,
    dfSQLServer,                //SQL数据库
    dfOracle,                   //Oracle数据库
    dfSybase,
    dfInformix,
    dfDB2,
    dfSQLite,                   //Android数据库
    dfMySQL,


                  
    dfUnknown,                  //未知数据格式
};

/*****************************************************************

                        _EditorStatus

*****************************************************************/
/*
    /// <summary>
    /// 数据编缉状态
    /// </summary>
    enum EditorStatus_
    {
        esView,       //查看状态
        esUpdate,     //更新状态
        esDelete,     //删除状态
        esAppend,     //添加状态
        esNull        //未设置
    };


*/

/// <summary>
/// 数据编缉状态
/// </summary>
enum class _EditorStatus
{
    esView,       //查看状态
    esUpdate,     //更新状态
    esDelete,     //删除状态
    esAppend,     //添加状态
    esNull        //未设置
};


/*  
    /// <summary>
    /// 记录改变状态
    /// </summary>
    enum DataChange_
    {
        dcNot,                              //没有改变
        dcUpdate,                           //记录已更新
        dcDelete,                           //记录已删除
        dcInsert,                           //记录已添加
        dcSelect,                           //记录已选择

        /// <summary>
        /// 记录已改变,可能是删除,可以是添加,可能是修改
        /// </summary>
        dcChanged
    };
*/

/*****************************************************************

                        _DataChange

*****************************************************************/
/// <summary>
/// 记录改变状态
/// </summary>
enum class _DataChange
{
    dcNot,                              //没有改变
    dcUpdate,                           //记录已更新
    dcDelete,                           //记录已删除
    dcInsert,                           //记录已添加
    dcSelect,                           //记录已选择

    /// <summary>
    /// 记录已改变,可能是删除,可以是添加,可能是修改
    /// </summary>
    dcChanged
};

/*****************************************************************

                        _SQLDataType

*****************************************************************/

/// <summary>
/// 标准SQL数据类型
/// </summary>
/// 创建时间:2024-08-12    最后一次修改时间:2024-08-12
enum class _SQLDataType
{
    /// <summary>
    /// 存储整数,无小数部分
    /// </summary>
    sdtINTEGER,

    /// <summary>
    /// 存储精确数值,包含小数部分
    /// </summary>
    sdtDECIMAL,


    /// <summary>
    /// 存储日期
    /// </summary>
    sdtDATE,

    /// <summary>
    /// 存储时间
    /// </summary>
    sdtTIME,


    /// <summary>
    /// 存储日期和时间
    /// </summary>
    sdtTIMESTAMP,

    /// <summary>
    /// 存储固定长度字符串
    /// </summary>
    sdtCHAR,

    /// <summary>
    /// 存储可变长度字符串
    /// </summary>
    sdtVARCHAR,

    /// <summary>
    /// 存储固定长度的二进制串
    /// </summary>
    sdtBINARY,

    /// <summary>
    /// 存储可变长度的二进制串
    /// </summary>
    sdtVARBINARY,
};

/*
    /// <summary>
    /// 数据类型
    /// </summary>
    enum DataType_
    {
        //----------------------------------------------------------------C#数据类型
        /// <summary>
        /// 8位无符号整数
        /// </summary>
        dtByte = 1,


        /// <summary>
        ///16位无符号整数
        /// </summary>
        dtInt16 = 2,


        /// <summary>
        ///32位无符号整数
        ///</summary>
        dtInt32 = 3,


        /// <summary>
        ///64位无符号整数
        ///</summary>
        dtInt64 = 4,

        /// <summary>
        /// 小数
        /// </summary>
        dtFloat = 5,

        /// <summary>
        /// 小数
        /// </summary>
        dtDouble = 6,


        /// <summary>
        /// 时间日期
        /// </summary>
        dtDateTime = 7,

        /// <summary>
        /// 字符串
        /// </summary>
        dtString = 8,

        /// <summary>
        /// 对象 例:Image数据
        /// </summary>
        dtObject = 9,



        //--------------------------------------------------------------------自定义数据类型
        /// <summary>
        /// 正数或0
        /// </summary>
        dtPlusNumberOrZero = 21,

        /// <summary>
        /// 负数或0
        /// </summary>
        dtNegativeOrZero = 22,

        /// <summary>
        /// 正整数
        /// </summary>
        dtPositiveInteger = 23,

        /// <summary>
        /// 正整数或0
        /// </summary>
        dtPositiveIntegerOrZero = 24,

        /// <summary>
        /// 正数
        /// </summary>
        dtPlusNumber = 25,




        /// <summary>
        /// 整数
        /// </summary>
        dtJavaInteger,


        /// <summary>
        /// 小数
        /// </summary>
        dtJavaFloat,

        /// <summary>
        /// 双精度小数
        /// </summary>
        dtJavaDouble,

        /// <summary>
        /// 时间日期
        /// </summary>
        dtJavaDateTime,

        /// <summary>
        /// 字符串
        /// </summary>
        dtJavaString,



        /// <summary>
        /// 图片,二进制数据
        /// </summary>
        dtJavaBinaryStream,


        /// <summary>
        /// tinyint TINYINT 1字节 (-128,127) (0,255) 小整数值
        /// </summary>
        dtJavaBoolean,

        /// <summary>
        /// byte[]
        /// </summary>
        dtJavaByteArray,


        /// <summary>
        ///未知数据类型
        /// </summary>
        dtNULL = -1,
    };
*/


//_DataType 定义在  base\_DataType.h 中






/*
    class _field
    {
        /// <summary>
        /// 字段名
        /// </summary>
        const _string& Name;

        /// <summary>
        /// 字段值
        /// </summary>
        const _string& Value;

        /// <summary>
        /// 字段类型
        /// </summary>
        DataType_ DataType;


        /// <summary>
        /// 字段描述
        /// </summary>
        const _string& Desc;



        _field(const _string& sName, const _string& sValue, DataType_ dt)
        {
            Name = sName;
            Value = sValue;
            DataType = dt;
            Desc = "";
        }

        _field()
        {
            Name = "";
            Value = "";
            DataType = csharp_DataType::dtNULL;
            Desc = "";
        }


        int GetSQLServerXType()
        {
            int iResult = -1;
            switch (DataType)
            {
                case csharp_DataType::dtDateTime:
                    iResult = -1;
                    break;
                case csharp_DataType::dtFloat:
                    iResult = -1;
                    break;
                default:
                    iResult = -1;
                    break;
            }

            return iResult;
        }



        void SetSQLServerXType(int iXTypeVale)
        {
            const _string& sTypeName = SQLServerXTYPConverToCSharpTypeName(iXTypeVale);

            if(sTypeName == "DateTime")
            {
                DataType = csharp_DataType::dtDateTime;
            }
            else if(sTypeName == "Int32")
            {
                DataType = csharp_DataType::dtInt32;
            }
            else if (sTypeName == "String")
            {
                DataType = csharp_DataType::dtString;
            }
            else if (sTypeName == "Object")
            {
                DataType = csharp_DataType::dtObject;
            }
            else if (sTypeName == "Double")
            {
                DataType = csharp_DataType::dtDouble;
            }
        }


        /// <summary>
        /// 把SQLServer xtype值转换为 C# 数据类型
        /// </summary>
        /// <param name="iXTypeVale"></param>
        /// <returns></returns>
        static Type SQLServerXTYPConverToCSharpType(int iXTypeVale)
        {
            const _string& sXTypeString = GetSQLServerXTypeString(iXTypeVale);


            SqlDbType sdtType = XTypeStringConverToSqlDbType(sXTypeString);


            Type tType = SqlDbTypeConvertToCSharpType(sdtType);

            return tType;
        }


        /// <summary>
        /// 把SQLServer xtype值转换为 C# 数据类型名的字符串
        /// </summary>
        /// <param name="iXTypeVale"></param>
        /// <returns></returns>
        static const _string& SQLServerXTYPConverToCSharpTypeName(int iXTypeVale)
        {
            return SQLServerXTYPConverToCSharpType(iXTypeVale).Name;
        }


        /// <summary>
        /// 以字符串表示的SQLServer数据类型
        /// </summary>
        /// <param name="iXTypeVale"></param>
        /// <returns></returns>
        static const _string& GetSQLServerXTypeString(int iXTypeVale)
        {
            
            //34 image
            //35 text
            //36 uniqueidentifier
            //48 tinyint
            //52 smallint
            //56 int
            //58 smalldatetime
            //59 real
            //60 money
            //61 datetime
            //62 float
            //98 sql_variant
            //99 ntext
            //104 bit
            //106 decimal
            //108 numeric
            //122 smallmoney
            //127 bigint
            //165 varbinary
            //167 varchar
            //173 binary
            //175 char
            //189 timestamp
            //231 sysname
            //231 nvarchar
            //239 nchar
           

            switch (iXTypeVale)
            {
            case 34:
                return "image";
            case 35:
                return "text";
            case 36:
                return "uniqueidentifier";
            case 48:
                return "tinyint";
            case 52:
                return "smallint";
            case 56:
                return "int";
            case 58:
                return "smalldatetime";
            case 59:
                return "real";
            case 60:
                return "money";
            case 61:
                return "datetime";
            case 62:
                return "float";
            case 98:
                return "sql_variant";
            case 99:
                return "ntext";
            case 104:
                return "bit";
            case 106:
                return "decimal";
            case 108:
                return "numeric";
            case 122:
                return "smallmoney";
            case 127:
                return "bigint";
            case 165:
                return "varbinary";
            case 167:
                return "varchar";
            case 173:
                return "binary";
            case 175:
                return "char";
            case 189:
                return "timestamp";
            case 231:
                return "nvarchar";
                //case 231:
                //SQL Server 实例包括用户定义的名为 sysname 的数据类型。
                //sysname 用于表列、变量以及用于存储对象名的存储过程参数。sysname 的精确定义与标识符规则相关;
                //因此,SQL Server 的各个实例会有所不同。sysname 与 nvarchar(128) 作用相同。
                //return "sysname";
            case 239:
                return "nchar";
            case 241:
                return "xml";

            }

            return "未知";
        }


        /// <summary>
        /// SqlDbType转换为C#数据类型
        /// </summary>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        static Type SqlDbTypeConvertToCSharpType(SqlDbType sqlType)
        {
            switch (sqlType)
            {
            case SqlDbType.BigInt:
                return typeof(Int64);
            case SqlDbType.Binary:
                return typeof(Object);
            case SqlDbType.Bit:
                return typeof(Boolean);
            case SqlDbType.Char:
                return typeof(String);
            case SqlDbType.DateTime:
                return typeof(DateTime);
            case SqlDbType.Decimal:
                return typeof(Decimal);
            case SqlDbType.Float:
                return typeof(Double);
            case SqlDbType.Image:
                return typeof(Object);
            case SqlDbType.Int:
                return typeof(Int32);
            case SqlDbType.Money:
                return typeof(Decimal);
            case SqlDbType.NChar:
                return typeof(String);
            case SqlDbType.NText:
                return typeof(String);
            case SqlDbType.NVarChar:
                return typeof(String);
            case SqlDbType.Real:
                return typeof(Single);
            case SqlDbType.SmallDateTime:
                return typeof(DateTime);
            case SqlDbType.SmallInt:
                return typeof(Int16);
            case SqlDbType.SmallMoney:
                return typeof(Decimal);
            case SqlDbType.Text:
                return typeof(String);
            case SqlDbType.Timestamp:
                return typeof(Object);
            case SqlDbType.TinyInt:
                return typeof(Byte);
            case SqlDbType.Udt://自定义的数据类型
                return typeof(Object);
            case SqlDbType.UniqueIdentifier:
                return typeof(Object);
            case SqlDbType.VarBinary:
                return typeof(Object);
            case SqlDbType.VarChar:
                return typeof(String);
            case SqlDbType.Variant:
                return typeof(Object);
            case SqlDbType.Xml:
                return typeof(Object);
            default:
                return null;
            }
        }



        /// <summary>
        ///  sql server数据类型(如:varchar), 转换为SqlDbType类型
        /// </summary>
        /// <param name="sqlTypeString"></param>
        /// <returns></returns>
        static SqlDbType XTypeStringConverToSqlDbType(const _string& sXTypeString)
        {
            SqlDbType dbType = SqlDbType.Variant;//默认为Object

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




/*********************************************************************************

                                _field


 ********************************************************************************/
/// <summary>
/// 表中的字段
/// </summary>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
class _field : public _Object
{
public:
    /// <summary>
    /// 字段名
    /// </summary>
    _string Name;
     

    /// <summary>
    /// 字段所属数据类型
    /// </summary>
    _SQLDataType SQLDataType;


    /// <summary>
    /// 字段描述
    /// </summary>
    _string Desc;
};


/*********************************************************************************

                                _Table


********************************************************************************/
class _Table
{

};

/*********************************************************************************

                                _FieldData


 ********************************************************************************/
/// <summary>
/// 字段值,_DataColumn中的字段数据
/// </summary>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
class _FieldValue : public _Object
{
public:
    /// <summary>
    /// 指向列数据的指针
    /// </summary>
    const _DataColumn* DataColumnPtr;
     

    /// <summary>
    /// 指向值
    /// </summary>
    _ByteArray Value;   

    inline _FieldValue(const _DataColumn* pdc, const _ByteArray& ba)
    {
        DataColumnPtr = pdc;
        Value = ba;
    }

    inline _FieldValue()
    {
        DataColumnPtr = null;         

    }

    /// <summary>
    /// 返回用字符串表示的对象,如sSplitString分隔字符串不等于空,则每个对象用sSplitString分隔。
    /// </summary>
    /// <param name="sSplitString">分隔字符串</param>
    /// <returns>返回用字符表示的对象</returns>
    /// 创建时间:2024-08-12    最后一次修改时间:2024-08-13
    virtual _string ToSplitString(const _string& sSplitString = _t("")) const override;

     
    const _db* GetDB()const;
};


/// <summary>
/// 数据行,所有数据保存在 _DataColumn中
/// </summary>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
class _DataRow : public _Object
{
public:
    /// <summary>
    /// 指向列数据的指针
    /// </summary>
    const _DataColumn* DataColumnPtr = null;
};

/// <summary>
/// 数据列
/// </summary>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
class _DataColumn : public _Object
{ 

public:
    /// <summary>
    /// 指向数据表的指针
    /// </summary>
    const _DataTable* DataTablePtr = null;

    /// <summary>
    /// 字段名
    /// </summary>
    _string Name;

    /// <summary>
    /// 数据类型,这个数据类型可能是SQLServer,可能是
    /// MySQL,或者其他,要根据数据库_db中的 _DataFormat 判断。
    /// </summary>
    int SQLDataType;


    /// <summary>
    /// 字值列表
    /// </summary>
    _DList<_FieldValue> FieldValueList;



    _DataColumn();
    _DataColumn(const _DataTable* pdt);
    _DataColumn(const _DataColumn& r);
};

class _DataTable : public _Object
{
private:
    _DList<_DataColumn> m_Columns;

    
public:
    /// <summary>
    /// 指向数据库的指针
    /// </summary>
    const _db* DatabasePtr = null;


    inline _DataColumn& Columns(const size_t& nIndex) { return m_Columns[nIndex]; }

    void AddColumn(const _DataColumn& dc);
    _DataTable();
    _DataTable(const _DataTable& r);
    void PrintFieldInfo()const;

    const _FieldValue& GetFieldValue(const size_t& nRowIndex, const size_t& nColumnIndex)const;
    const _FieldValue& GetFieldValue(const size_t& nRowIndex, const _string& sFieldName)const;

public: //----------------------------------------属性
    inline size_t GetRowsCount()const { return m_Columns[0].FieldValueList.Count; }

    /// <summary>
    /// 获取行数
    /// </summary>
    __declspec(property(get = GetRowsCount)) const size_t RowsCount;

    inline size_t GetColumnsCount()const { return m_Columns.Count; }
    __declspec(property(get = GetColumnsCount)) const size_t ColumnsCount;

};

 


/// <summary>
/// 
/// </summary>
/// 创建时间:2024-08-12    最后一次修改时间:2024-08-12
class _db : public _Object
{
/* 

        /// <summary>
        /// 数据库名子
        /// </summary>
        private const _string& _database_name;
        /// <summary>
        /// 数据库名子
        /// </summary>
        virtual const _string& database_name { get { return _database_name; } set { _database_name = value; } }


        /// <summary>
        ///
        /// </summary>
        private const _string& _user_name;
        /// <summary>
        /// 数据库用户
        /// </summary>
        virtual const _string& user_name { get { return _user_name; } set { _user_name = value; } }



        /// <summary>
        ///
        /// </summary>
        private const _string& _user_password;
        /// <summary>
        ///  数据库密码
        /// </summary>
        virtual const _string& user_password { get { return _user_password; } set { _user_password = value; } }


        /// <summary>
        ///
        /// </summary>
        private const _string& _database_source;

        /// <summary>
        ///  提供数据源的数据服务器名
        /// </summary>
        virtual const _string& database_source { get { return _database_source; } set { _database_source = value; } }


        /// <summary>
        /// DB-Engines 数据库流行度排行榜 9 月更新已发布,排名前二十如下:总体排名和上个月相比基本一致,
        /// 其中排名前三的 Oracle、MySQL 和 Microsoft SQL Server 也是分数增加最多的三个数据库,对于
        /// 很多做互联网的同学来说,Oracle和Microsoft SQL Server排名前
        /// </summary>
        static _StringList DbManufacturerList = new _StringList {
           "Oracle", "MySQL", "Microsoft SQL Server", "PostgreSQL", "MongoDB","Redis",
           "IBM Db2","Elasticsearch","SQLite","Cassandra","Microsoft Access","MariaDB",
           "Splunk","Hive","Microsoft Azure SQL Database","Amazon DynamoDB","Teradata",
           "Neo4j","SAP HAHA","FileMaker"};
*/
protected:
    /// <summary>
    /// 数据库格式
    /// </summary>
    _DataFormat _df;
     
    /// <summary>
    /// 数据库名子
    /// </summary>
    _string _DatabaseName;

    /// <summary>
    /// 用户名
    /// </summary>
    _string  _UserName;
     
    /// <summary>
    /// 用户密码
    /// </summary>
    _string  _UserPassword;
     
    /// <summary>
    /// 数据源
    /// </summary>
    _string _DataSource;
     

public:

    //-------------------------------------------------------------构造       

    inline _db(_DataFormat df)   { _df = df; }

    //-----------------------------------------------------------------------属性重写


   
    /// <summary>
    /// 数据访问格式
    /// </summary>
    __declspec(property(get = GetDataFormat)) const _DataFormat& DataFormat;
    inline const _DataFormat& GetDataFormat()const { return _df; }


    /// <summary>
     /// 数据库名子
     /// </summary>
    __declspec(property(get = GetDatabaseName)) const _string& DatabaseName;
    inline const _string& GetDatabaseName()const { return _DatabaseName; }



    /// <summary>
    /// 用户名
    /// </summary>
    __declspec(property(get = GetUserName)) const _string& UserName;
    inline const _string& GetUserName()const { return _UserName; }


    /// <summary>
    /// 用户密码
    /// </summary>
    inline const _string& GetUserPassword()const { return _UserPassword; }
    __declspec(property(get = GetUserPassword)) const _string& UserPassword;

    
    /// <summary>
    /// 数据源
    /// </summary>
    __declspec(property(get = GetDataSource)) const _string& DataSource;
    inline const _string& GetDataSource()const { return _DataSource; }
     

    //-------------------------------------------------------------方法重写


    /// <summary>
    /// 执行特定的SQL内容
    /// </summary>
    /// <param name="sCaptionName">标题名</param>
    /// <param name="sCheckTableName">需要检查的表名</param>
    /// <returns></returns>
    virtual bool exec_dict_sql_content(const _string& sCaptionName, const _string& sCheckTableName)
    {
        return false;
    }

 

    virtual bool ExecSQLFile(const _string& sFileName)
    {
        return false;
    }

    //virtual DbConnection GetConnection()
    //{
    //    return null;
    //}


    //virtual DbDataAdapter GetViewDbDataAdapter()
    //{
    //    return null;
    //}


    virtual int ExecSQLNon(const _string& sSQL)const;
    


    /// <summary>
    /// 返回记录条数
    /// </summary>
    /// <param name="sTableName">表句</param>
    /// <returns></returns>
    int getRecordCount(const _string& sTableName)
    {
        //_DataTable dt = ExecSQLQuery("SELECT Count(*) fd_sum FROM " + sTableName);
        //return (int)dt->Rows[0]["fd_sum"];

        return 0;
    }



    /// <summary>
    /// 返回最后一条记录的某个字段值
    /// </summary>
    /// <param name="sFileName"></param>
    /// <returns></returns>
    _FieldValue getFieldValueForLastRecord(const _string& sFieldName, const _string& sTableName, 
        const _string& sCondition)
    {
        /*
        const _string& ssql = "";

        if (sCondition == "")
        {
            ssql = "SELECT TOP 1 " + sFieldName + " FROM " + sTableName + " ORDER BY " + sFieldName + " DESC";
        }
        else
        {
            ssql = "SELECT TOP 1 " + sFieldName + " FROM " + sTableName + " WHERE " + sCondition + " ORDER BY " + sFieldName + " DESC";
        }


        _DataTable dt = ExecSQLQuery(ssql);
        if (dt->Rows->Count > 0)
        {
            return dt->Rows[0][sFieldName];
        }
        else
        {
            return null;
        }
        */
    }


    /// <summary>
    /// 获取最后一条记录。 创建时间:2014-04-16
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <returns>如果成功,返回最后一记录,否则返回NULL</returns>
    _DataRow getLastRecord(const _string& sTableName)
    {
        /*
        const _string& ssql = "SELECT TOP 1 * FROM " + sTableName + " ORDER BY fd_id DESC";
        _DataTable dt = ExecSQLQuery(ssql);
        if (dt->Rows->Count > 0) return dt->Rows[0];
        return null;
        */

        return _DataRow();
    }

    /// <summary>
    /// 获取第一条记录。 创建时间:2014-04-16
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <returns>如果成功,返回第一条记录,否则返回NULL</returns>
    _DataRow getFirstRecord(const _string& sTableName)
    {
        /*
        const _string& ssql = "SELECT TOP 1 * FROM " + sTableName + " ORDER BY fd_id";
        _DataTable dt = ExecSQLQuery(ssql);
        if (dt->Rows->Count > 0) return dt->Rows[0];
        return null;
        */
    }




    /// <summary>
    /// 在目录sPath下创建一个数据库。
    /// </summary>
    /// <param name="sDatabaseName">数据库名</param>
    /// <param name="sPath">路径名</param>
    /// 创建时间:????-??-??  最后一次修改时间:2020-04-03
    /// <returns>如果成功,则返回空字符串,失败返回错误原因。</returns>
    virtual const _string& CreateDatabase(const _string& sDatabaseName, const _string& sPath = "")
    {



        return "";
    }





    /// <summary>
    /// 创建一个系统数据库,如果数据库存在或者创建成功,返回true
    /// </summary>
    /// <param name="sPath"></param>
    /// <returns></returns>
    static bool createAppRepository(const _string& sPath)
    {
        /*
        if (sPath->Trim()->Length == 0)
            return false;
#if _WINDOWS_PLATFORM_
        if (File.Exists(sPath + "AppRepository" + ".accdb"))
        {
            return true;
        }

        //数据库密码 = gce::DES_Encrypt("lh",csharp_DB_Global::ind_des_key);
        AccessDB_ db = new AccessDB_(sPath + "AppRepository" + ".accdb", gce::DES_Encrypt("lh", csharp_DB_Global::ind_des_key));


        db.create_app_co_user();
        db.create_app_ind_user();
        db.create_app_module();
#endif
        return true;
        */

        return false;
    }


    /// <summary>
    /// 判断是否存在数据库sDatabaseName
    /// </summary>
    /// <param name="sDatabaseName">数据库名</param>  
    /// 创建时间:2020-03-03  最后一次修改时间: 2021-07-04
    /// <returns></returns>
    static bool IsExistDatabase(const _string& sDatabaseName)
    {
        /*
#if _WINDOWS_PLATFORM_

        SqlDb_ dbMaster = new SqlDb_("master", "sa", gce::TextDecrypt2(csharp_DB_Global::m_db_pwd, csharp_DB_Global::m_text_key), csharp_DB_Global::m_IP);

        const _string& ssql = "SELECT * FROM master..sysdatabases where name = \'" + sDatabaseName.Trim() + "\'";

        return dbMaster.ExecSQLQuery(ssql).Rows.Count != 0;



#else
        throw new Exception(gce::OnCodeDidNotFinishError);
#endif
*/
        return false;
    }




    /// <summary>
    /// 这个表的作用是保存软件使用者的公司的必要信息。
    /// </summary>
    virtual bool create_app_co_user()
    {
        return false;
    }

    /// <summary>
    /// 这个表的作用是保存软件使用者的个人必要信息。
    /// </summary>
    /// <returns></returns>
    virtual bool create_app_ind_user()
    {
        return false;
    }


    /// <summary>
    /// 所有可用模块集合
    /// </summary>
    /// <param name="ConnectionString"></param>
    virtual bool create_app_module()
    {
        return false;
    }


    /// <summary>
    /// 如果个人通信薄类型不存在,则创建
    /// </summary>
    /// <param name="ConnectionString"></param>
    virtual bool create_ind_individual_addressbook_type()
    {
        return false;
    }


    /// <summary>
    /// 如模块表不存在,则自动创建
    /// </summary>
    /// <param name="ConnectionString"></param>
    virtual bool create_ind_module()
    {
        return false;
    }

    /// <summary>
    /// 如临时模块不存在,则自动创建
    /// </summary>
    /// <returns></returns>
    virtual bool create_ind_module_tmp()
    {
        return false;
    }


    /// <summary>
    /// 如果系统表不存在,则自动创建
    /// </summary>
    /// <returns></returns>
    virtual bool create_System()
    {
        return false;
    }


    /// <summary>
    /// 创建审批流表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_approval_flow()
    {
        return true;
    }


    //------------------------------------------------------------------------------------个人相关模块
    virtual bool create_dict_notepad()
    {
        return true;
    }



    /// <summary>
    /// 个人相关.sql(工作计划,工作日志,审批请求,审阅审批,使用设备,集团通迅录,个人通迅录,个人信息,记事本,建议与改进,使用帮助)
    /// </summary>
    /// <returns></returns>
    virtual bool create_个人相关()
    {
        return true;
    }







    /// <summary>
    /// 如果ind_notepad表不存在,则创建ind_notepad表。
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_notepad()
    {
        return false;
    }

    /// <summary>
    /// 如果ind_payout表不存在,则创建ind_payout表。
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_payout()
    {
        return false;
    }

    /// <summary>
    /// 创建个人收入类型表
    /// </summary>
    /// <param name="ConnectionString"></param>
    virtual bool create_ind_payout_type()
    {
        return false;
    }

    /// <summary>
    /// 创建银行存款数量表 
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_bank_cash()
    {
        return false;
    }

    /// <summary>
    /// 银行取款表。
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_bank_debits()
    {
        return false;
    }

    /// <summary>
    /// 银行存款表。
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_bank_deposit()
    {
        return false;
    }


    /// <summary>
    /// 现金计数表
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_cash()
    {
        return false;
    }


    /// <summary>
    /// 创建客户表
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_co_customer()
    {
        return false;
    }

    /// <summary>
    ///创建每天收入表
    /// </summary>
    /// <param name="cn"></param>
    /// <returns></returns>
    virtual bool create_ind_earning()
    {
        return false;
    }

    /// <summary>
    /// 创建每天收入类型表
    /// </summary>
    /// <param name="ConnectionString"></param>
    virtual bool create_ind_earning_type()
    {
        return false;
    }


    /// <summary>
    /// 创建个人通信薄  
    /// </summary>
    /// <returns></returns>
    virtual bool create_ind_individual_addressbook()
    {

        return false;
    }


    /// <summary>
    /// 创建自然人表
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_natural_person()
    {

        return false;
    }


    /// <summary>
    /// 创建公司表
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_company()
    {
        return false;
    }


    /// <summary>
    /// 创建关系表
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_relation()
    {
        return false;
    }


    /// <summary>
    /// 创建银行帐户
    /// </summary>
    /// <returns></returns>
    virtual bool create_fc_bank()
    {
        return false;
    }

    /// <summary>
    /// 创建项目表
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_project()
    {
        return false;
    }



    /// <summary>
    /// 创建员工表
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_employee()
    {
        return false;
    }


    /// <summary>
    /// 
    /// </summary>
    /// 创建时间: 2021-10-03      最后一次修改时间:2021-10-03
    /// <returns></returns>
    virtual bool create_crm_rote()
    {

        return false;
    }



    /// <summary>
    /// 个人通信录视图
    /// </summary>
    /// <returns></returns>
    virtual bool create_pro_crm_np_AddressBook_view()
    {
        return false;
    }


    /// <summary>
    /// 创建职位表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_job()
    {
        return false;
    }


    /// <summary>
    /// 创建部门表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_department()
    {
        return false;
    }



    /// <summary>
    /// 创建供应商品信息
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_supplier()
    {
        return false;
    }

    /// <summary>
    /// 创建送货记录
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_deliver_goods()
    {
        return false;
    }

    /// <summary>
    /// 创建送货记录分析表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_deliver_goods_statistic()
    {
        return false;
    }

    /// <summary>
    /// 创建拿货记录分析表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_stock_statistic()
    {
        return false;
    }


    /// <summary>
    /// 创建存货记录
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_stock()
    {
        return false;
    }


    /// <summary>
    /// 创建新闻分类表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_news_class()
    {
        return false;
    }


    /// <summary>
    /// 创建新闻信息表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_news_info()
    {
        return false;
    }


    /// <summary>
    /// 资金借出记录
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_loan()
    {
        return false;
    }


    /// <summary>
    /// 资产管理 ------------------------商品表
    /// </summary>
    /// <returns></returns>
    virtual bool create_dict_merchandise()
    {
        return false;
    }


    /// <summary>
    /// 资产管理 ------------------------资产管理
    /// </summary>
    /// <returns></returns>
    virtual bool create_资产管理()
    {
        return false;
    }

    /// <summary>
    /// 资产视图
    /// </summary>
    /// <returns></returns>
    virtual bool create_pro_assets_view()
    {
        return false;
    }


    /// <summary>
    /// 资产分类视图
    /// </summary>
    /// <returns></returns>
    virtual bool create_pro_assets_class_view()
    {
        return false;

    }

    //---------------------------------------------------------------------------------合同管理模块

    /// <summary>
    /// 创建合同管理模块
    /// </summary>
    /// <returns></returns>
    virtual bool create_crm_contract()
    {
        return false;
    }


    /// <summary>
    /// 创建每天支出记录
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_payout()
    {
        return false;
    }

    virtual bool create_co_login_info()
    {
        return false;
    }

    virtual bool create_co_runtime_parameter()
    {
        return false;
    }


    virtual bool create_co_runtime_user()
    {
        return false;
    }

    /// <summary>
    /// 创建每天支出记录的触发器
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_payout_trigger()
    {
        return false;
    }

    /// <summary>
    /// 创建现金记录
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_cash()
    {
        return false;
    }


    /// <summary>
    /// 创建定价表
    /// </summary>
    /// <returns></returns>
    virtual bool create_co_pricing_of_product()
    {
        return false;
    }

 

        /**
         * 函数名:create_crm_natural_person
         * 作用: 在数据库sDBName中创建表crm_natural_person
         * 参数:[sDBName]数据库名
         * 返回值:boolean
         * 作者:李锋
         * 创建时间:2020/1/26 22:21
         * 最后一次修改日期:2020/1/26 22:21
         */
        static bool create_crm_natural_person(const _string& sDBName)
    {
        /*
        if (sDBName->Trim()->Length == 0)
            return false;


        const _string& ssql = "SELECT [fd_content] FROM [dict_sql] WHERE [fd_caption] = \'crm_natural_person.sql\'";

        //[MyFamily]

        const _string& sCreate = "";


        _DataTable dt = csharp_DB_Global::db_repository.ExecSQLQuery(ssql);

        if (dt->Rows->Count > 0)
            sCreate = dt->Rows[0][0]->ToString();
        else
            return false;

        sCreate = sCreate.Replace("MyFamily", sDBName);

        return csharp_DB_Global::db_repository.ExecNonSQL(sCreate) != 0;
        */

            return false;
    }




    /// <summary>
    /// 在数据库sDBName中创建表sTableName
    /// 在AppRepository数据库中,必须存在dict_sql这个表,在这个表中保存有创建表的SQL语句。
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <param name="sDBName">数据库名</param>
    /// 创建时间:2020/02/09  最后一次修改时间:2020/02/09
    /// <returns>如果成功,返回真</returns>
    static bool create_table(const _string& sTableName, const _string& sDatabaseName)
    {
        /*
        if (sDatabaseName.Trim() == "")
            return false;

        const _string& ssql = "SELECT [fd_content] FROM [dict_sql] WHERE [fd_caption] = \'" + sTableName + ".sql\'";

        const _string& sCreate = "";

        _DataTable dt = csharp_DB_Global::db_repository.ExecSQLQuery(ssql);

        if (dt->Rows->Count > 0)
            sCreate = dt->Rows[0][0]->ToString();
        else
            return false;

        sCreate = sCreate.Replace("[MyFamily]", "[" + sDatabaseName + "]");


        return csharp_DB_Global::db_repository.ExecNonSQL(sCreate) != 0;
        */

        return false;
    }



    //--------------------------------------------------------------操作


    /// <summary>
    /// 把sSourceTableName的数据拷贝到sDestTable,并清空sDestTableName表的数据,注意,两个表结构必须一样的
    /// </summary>
    /// <param name="sDestTableName">目标表,这个表原有的数据会清空</param>
    /// <param name="dbDest">目标数据库</param>
    /// <param name="sSourceTableName">源数据库的表名</param>
    /// 创建时间:2020-05-02  最后一次修改时间:2020-05-02
    /// <param name="dbSource">源数据库</param>
    static void TableCopy(const _string& sDestTableName, _db dbDest, const _string& sSourceTableName, _db dbSource)
    {
        /*
#if _WINDOWS_PLATFORM_
        //清空原有表的数据
        dbDest.ExecNonSQL("DELETE   FROM [" + sDestTableName + "]");

        //复制表数据
        _DataTable dtSource = dbSource.ExecSQLQuery("SELECT * FROM [" + sSourceTableName + "]");

        SqlBulkCopy sbc = new SqlBulkCopy(dbDest.GetConnection().ConnectionString);

        try
        {
            sbc.DestinationTableName = sDestTableName;

            sbc.WriteToServer(dtSource);  //写入数据库

            sbc.Close();
        }
        finally
        {
            sbc.Close();
        }
#else

        throw new Exception(gce::OnCodeDidNotFinishError);
#endif
*/
    }



    virtual _DataTable ExecSQLQuery(const _string& sSQL) const;


    /// <summary>
    /// 返回最大的索引号,如果表中没有记录,则返回0
    /// </summary>
    /// <param name="sTableName"></param>
    /// <param name="sCondition"></param>
    /// <returns></returns>
    int GetMaxID(const _string& sTableName, const _string& sCondition = "")
    {
        /*
        const _string& ssql = "";

        if (sCondition.Length == 0)
            ssql = "SELECT Max(fd_id) AS max_id FROM " + sTableName;
        else
            ssql = "SELECT Max(fd_id) AS max_id FROM " + sTableName + " WHERE " + sCondition;


        _DataTable dt = ExecSQLQuery(ssql);



        //如果sTableName表中没有记录,Max(fd_id)返回null,dt.getRowsCount() = 1,不管
        //怎样,dt.getRowsCount()都返回1


        if (dt->Rows[0]["max_id"] == DBNull::Value)
        {
            return 0;
        }
        else
        {
            return (int)dt->Rows[0]["max_id"];
        }
        */

        return 0;
    }


    /*

    AVG(column) 返回某列的平均值
    BINARY_CHECKSUM
    CHECKSUM
    CHECKSUM_AGG
    Count(column) 返回某列的行数(不包括NULL值)
    Count(*) 返回被选行数
    Count(DISTINCT column) 返回相异结果的数目
    First(column) 返回在指定的域中第一个记录的值(SQLServer2000 不支持)
    LAST(column) 返回在指定的域中最后一个记录的值(SQLServer2000 不支持)
    MAX(column) 返回某列的最高值
    MIN(column) 返回某列的最低值
    STDEV(column)
    STDEVP(column)
    SUM(column) 返回某列的总和
    VAR(column)
    VARP(column)
    */


    /// <summary>
    /// SUM(column) 返回某列的总和 (创建于:2014-04-16)
    /// </summary>
    /// <param name="sFieldName">列名</param>
    /// <param name="sTable">表名</param>
    /// <param name="sCondition">条件</param>
    /// <returns>返回值</returns>
    float fun_sum(const _string& sFieldName, const _string& sTable, const _string& sCondition)
    {
        /*
        float f_sum = 0;
        const _string& ssql = "SELECT SUM(" + sFieldName + ") AS fd_sum FROM " + sTable;

        if (sCondition->Trim()->Length != 0)
        {
            ssql += " WHERE " + sCondition;
        }

        _DataTable dt = ExecSQLQuery(ssql);

        f_sum = System::Convert::ToSingle(dt->Rows[0]["fd_sum"]);

        return f_sum;
        */
        return 0;
    }


    /// <summary>
    /// 从索引号号得到某个字段的值
    /// </summary>
    /// <param name="sIDValue">索引号</param>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sTableName">表名</param>
    /// <returns>如果不存在,则返回空值</returns>
    const _string& GetValueFromID(const _string& sIDValue, const _string& sFieldName, const _string& sTableName)
    {
        /*
        const _string& ssql = "SELECT [" + sFieldName + "]  FROM [" + sTableName + "] WHERE [fd_id] =" + sIDValue;

        _DataTable dt = ExecSQLQuery(ssql);

        if (dt->Rows->Count > 0)
        {

            return dt->Rows[0][sFieldName]->ToString()->Trim();

        }
        else
        {
            return "";
        }
    */
        return _string();
    }



    /// <summary>
    /// 创建时间: 2020-06-20      最后一次修改时间:2020-06-20
    /// </summary>
    /// <param name="sIDValue">索此号</param>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sFieldValue">字段值</param>
    /// <param name="sTableName">表名</param>
    /// <returns></returns>
    bool UpdateValueFromID(const _string& sIDValue, const _string& sFieldName, const _string& sFieldValue, const _string& sTableName)
    {
        /*
        const _string& ssql = "UPDATE [" + sTableName + "] SET [" + sFieldName + "] = \'" + gce::CheckSQLString(sFieldValue) + "\'" +
            " WHERE [fd_id] =" + sIDValue;

        return ExecNonSQL(ssql) != 0;
          */
        return 0;
    }


    /// <summary>
    /// 创建时间: 2020-06-25      最后一次修改时间:2020-06-25
    /// 交换两条记录的ID号
    /// </summary>
    /// <param name="iID1"></param>
    /// <param name="iID2"></param>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    bool SwapID(int iID1, int iID2, const _string& sTableName)
    {
        /*
        int iTempID = GetMaxID(sTableName) + 1;

        //ID1变成iTempID
        if (ExecNonSQL("UPDATE [" + sTableName + "] SET [fd_id] = " + iTempID.ToString() + "  WHERE [fd_id] = " +
            iID1.ToString()) != 0)
        {
            //ID2变成ID1
            if (ExecNonSQL("UPDATE [" + sTableName + "] SET [fd_id] = " + iID1.ToString() + "  WHERE [fd_id] = " +
                iID2.ToString()) != 0)
            {
                //iTempID 变成 ID2
                if (ExecNonSQL("UPDATE [" + sTableName + "] SET [fd_id] = " + iID2.ToString() + "  WHERE [fd_id] = " +
                    iTempID.ToString()) != 0)
                {
                    return true;
                }
            }
        }
        return false;
          */
        return 0;
    }


    bool SwapStringFieldValue(int iID1, int iID2, const _string& sFieldName, const _string& sTableName)
    {
        /*
        _DataTable dt1 = ExecSQLQuery("SELECT [" + sFieldName + "]  FROM [" + sTableName + "] WHERE fd_id = " + iID1.ToString());

        object value1, value2;

        if (dt1.Rows.Count > 0)
        {
            value1 = dt1.Rows[0][sFieldName];

            _DataTable dt2 = ExecSQLQuery("SELECT [" + sFieldName + "]  FROM [" + sTableName + "] WHERE fd_id = " + iID2.ToString());

            if (dt2.Rows.Count > 0)
            {
                value2 = dt2.Rows[0][sFieldName];

                const _string& ssql1 = "UPDATE [" + sTableName + "] SET [" + sFieldName + "]= \'" + value1.ToString() + "\' WHERE fd_id=" +
                    iID2.ToString();

                const _string& ssql2 = "UPDATE [" + sTableName + "] SET [" + sFieldName + "]= \'" + value2.ToString() + "\' WHERE fd_id=" +
                    iID1.ToString();

                if (ExecNonSQL(ssql1) != 0)
                {
                    return ExecNonSQL(ssql2) != 0;
                }
            }
        }

        return false;
          */
        return 0;
    }



    /// <summary>
    /// 创建时间: 2020-06-20      最后一次修改时间:2020-06-20
    /// </summary>
    /// <param name="sIDValue"></param>
    /// <param name="sFieldName"></param>
    /// <param name="sFieldValue"></param>
    /// <param name="sTableName"></param>
    /// <param name="sModuleName"></param>
    /// <returns></returns>
    bool MIS_SetValueFromID(const _string& sIDValue, const _string& sFieldName, const _string& sFieldValue, const _string& sTableName, const _string& sModuleName)
    {
        /*
        if (csharp_MIS_Global::LoginUser.CanModuleWrite(sModuleName))
        {
            return UpdateValueFromID(sIDValue, sFieldName, sFieldValue, sTableName);
        }

        return false;
          */
        return 0;
    }


    /// <summary>
    /// 创建时间: 2020-06-20      最后一次修改时间:2020-06-20
    /// </summary>
    /// <param name="sIDValue"></param>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    bool DeleteFromID(const _string& sIDValue, const _string& sTableName)
    {
        /*
        const _string& ssql = "DELETE FROM [" + sTableName + "] WHERE fd_id=" + sIDValue;
        return ExecNonSQL(ssql) != 0;
          */
        return 0;
    }


    /// <summary>
    /// 创建时间: 2020-06-20      最后一次修改时间:2020-06-20
    /// </summary>
    /// <param name="sIDValue"></param>
    /// <param name="sTableName"></param>
    /// <param name="sModuleName"></param>
    /// <returns></returns>
    bool MIS_DeleteFromID(const _string& sIDValue, const _string& sTableName, const _string& sModuleName)
    {
        /*
        if (csharp_MIS_Global::LoginUser.CanModuleDelete(sModuleName))
        {
            return DeleteFromID(sIDValue, sTableName);
        }

        return false;
          */
        return 0;
    }



    /// <summary>
    /// 从索引号号得到某个字段的值
    /// </summary>
    /// <param name="sIDValue">索引号</param>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sTableName">表名</param>
    /// <returns>如果不存在,则返回空值</returns>
    const _string& GetValueFromID(int iIDValue, const _string& sFieldName, const _string& sTableName)
    {
        /*
        return GetValueFromID(iIDValue.ToString(), sFieldName, sTableName);
          */
        return _string();
    }


    /// <summary>
    /// 同时近回两个字段的值
    /// </summary>
    /// <param name="sIDValue">记录ID</param>
    /// <param name="sFieldName1">字段1</param>
    /// <param name="sFieldName2">字段2</param>
    /// <param name="sTableName">表名</param>
    /// <returns></returns>
    _Pair<_string, _string> GetPairValueFormID(const _string& sIDValue, const _string& sFieldName1, const _string& sFieldName2, const _string& sTableName)
    {
        /*
        _Pair<const _string&, const _string&> lp = new _Pair<const _string&, const _string&>();

        _DataTable dt = ExecSQLQuery("SELECT " + sFieldName1 + "," + sFieldName2 + " FROM " + sTableName +
            " WHERE fd_id =" + sIDValue);

        if (dt->Rows->Count > 0)
        {
            lp.First = dt->Rows[0][sFieldName1]->ToString()->Trim();
            lp.Second = dt->Rows[0][sFieldName2]->ToString()->Trim();
        }
        return lp;
          */
        return _Pair<_string, _string>();
    }




    /// <summary>
    /// 同时近回两个字段的值
    /// </summary>
    /// <param name="iIDValue">记录ID</param>
    /// <param name="sFieldName1">字段1</param>
    /// <param name="sFieldName2">字段2</param>
    /// <param name="sTableName">表名</param>
    /// <returns></returns>
    _Pair<_string, _string> GetPairValueFormID(int iIDValue, const _string& sFieldName1, const _string& sFieldName2, const _string& sTableName)
    {
        //return GetPairValueFormID(iIDValue.ToString(), sFieldName1, sFieldName2, sTableName);

        return _Pair<_string, _string>();
    }

    /// <summary>
    /// 从某个字段的值得到索引号,这个值必须是唯一的,字段的值必须是字符串,找到返回ID,否则返回-1
    /// </summary>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sValue">字段值</param>
    /// <param name="sTableName">表名</param>
    /// <returns>如找到,返回索引号,否则返回-1</returns>
    int GetIDFromValue(const _string& sFieldName, const _string& sValue, const _string& sTableName)
    {
        /*
        _DataTable dt = ExecSQLQuery("SELECT fd_id  FROM " + sTableName +
            " WHERE " + sFieldName + " = \'" + gce::CheckSQLString(sValue.Trim()) + "\'");

        if (dt->Rows->Count > 0)
        {
            return (int)dt->Rows[0]["fd_id"];
        }
        else
        {
            return -1;
        }
          */
        return 0;
    }


    /// <summary>
    /// 从某个字段的值得到索引号,这个值必须是唯一的,字段的值必须是字符串,找到返回ID,否则返回-1
    /// </summary>
    /// <param name="sFieldName"></param>
    /// <param name="sValue"></param>
    /// <param name="sTableName"></param>
    /// <param name="sCondition">条件</param>
    /// <returns></returns>
    int GetIDFromValue(const _string& sFieldName, const _string& sValue, const _string& sTableName, const _string& sCondition)
    {
        /*
        _DataTable dt = ExecSQLQuery("SELECT fd_id  FROM " + sTableName +
            " WHERE " + sFieldName + " = \'" + gce::CheckSQLString(sValue.Trim()) + "\' AND " + sCondition);
        if (dt->Rows->Count > 0)
        {
            return (int)dt->Rows[0]["fd_id"];
        }
        else
        {
            return -1;
        }
        */
    }



    /// <summary>
    /// 如创建了一个字典值,数组第一个无素是1,第二无素是ID,如果没有创建字典值,第一个元素是0,第二个元素还是ID,不充许字符串都是空格。  
    /// </summary>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sValue">字段值,必须是符串</param>
    /// <param name="sTableName">表名</param>
    /// <returns>返回字典ID</returns>
    _Pair<int,int> addName(const _string& sFieldName, const _string& sValue, const _string& sTableName)
    {
        /*
        if (sValue->Trim()->Length == 0)
        {
            throw new System.Exception("字段值不能为空值!");
        }

        int[] il = new int[2];
        int iid = GetMaxID(sTableName, "") + 1;
        if (sValue->Trim()->Length != 0)
        {
            il[1] = GetIDFromValue(sFieldName, sValue, sTableName);
            if (il[1] == -1)
            {
                const _string& ssql = "INSERT INTO " + sTableName + "(fd_id," + sFieldName + ") VALUES(" + iid.ToString() + ",\'" + gce::CheckSQLString(sValue) + "\')";
                if (ExecNonSQL(ssql) != 0)
                {
                    il[0] = 1; il[1] = iid;
                }
                else { throw new Exception("无法创建字典值“" + sValue + "”"); }
            }
            else
            {
                il[0] = 0;
            }
        }
        else
        {
            throw new Exception("字段值不能为空!");
        }
        return il;
        */
       
        return _Pair<int, int>();
    }


#if _WINDOWS_DESKTOP_
    /// <summary>
    /// 添加一个字段值,返回字段值的ID,如果有添加动作,则会在列表框中添另一个项。
    /// 创建时间: ????-??-??      最后一次修改时间:2020-05-30
    /// </summary>
    /// <param name="sFieldName"></param>
    /// <param name="sValue"></param>
    /// <param name="sTableName"></param>
    /// <param name="lic"></param>
    /// <returns></returns>
    int addName2(const _string& sFieldName, const _string& sValue, ComboBox lic, const _string& sTableName)
    {
        int[] il = addName(sFieldName, sValue, sTableName);

        if (il[0] != 0)
        {
            _Pair<int, const _string&> p = new _Pair<int, const _string&>(il[1], sValue.Trim());
            lic.Items.Add(p); //把字典值添加到选择框          
            lic.SelectedItem = p;
        }
        return il[1];
    }





    /// <summary>
    /// 创建时间: 2020-05-30      最后一次修改时间:2020-05-30
    /// </summary>
    /// <param name="sOldNameCN"></param>
    /// <param name="sNewNameCN"></param>
    /// <param name="lic"></param>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    bool ModifyNameCN(const _string& sOldNameCN, const _string& sNewNameCN, ComboBox cb, const _string& sTableName)
    {
        if (sOldNameCN.Trim() == sNewNameCN.Trim())
            return false;


        int iFindID = find_s(sTableName, "fd_name_cn", sNewNameCN);

        if (iFindID != -1)
            return false;


        dict_table dtTable = new dict_table(sTableName);

        if (!dtTable.readDataFromName_CN(sOldNameCN))
        {
            return false;
        }

        dtTable.fd_name_cn = sNewNameCN;

        if (csharp_MIS_Global::LoginUser != null)
        {
            dtTable.fd_ntext_ext1 = "此记录由用户(" + csharp_MIS_Global::LoginUser.fd_user_name + ")在" + System::DateTime.Now.ToString() + "修改过!";

        }


        int iFind = cb.FindString(sOldNameCN);

        if (iFind != -1)
        {
            cb.Items[iFind] = new _Pair<int, const _string&>(dtTable.ID, dtTable.fd_name_cn);
            cb.SelectedIndex = iFind;
        }


        return dtTable.UpdateSQL() != 0;

    }







#elif _WINDOWS_WEB_
    /// <summary>
    /// 添加一个字段值,返回字段值的ID,如果有添加动作,则会在列表框中添另一个项。
    /// </summary>
    /// <param name="sFieldName"></param>
    /// <param name="sValue"></param>
    /// <param name="sTableName"></param>
    /// <param name="lic"></param>
    /// <returns></returns>
    int addName2(const _string& sFieldName, const _string& sValue, ListItemCollection lic, const _string& sTableName)
    {
        int[] il = addName(sFieldName, sValue, sTableName);

        if (il[0] != 0 && lic != null)
            lic.Add(new ListItem(sValue, il[1]->ToString()));           //把字典值添加到选择框

        return il[1];
    }
#endif

    ///<summary>
    ///得到某个字段值的不重复的列表
    ///</summary>		
    _StringList GetDistinctTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sCondition)
    {
        /*
        const _string& tmp = "SELECT  Distinct " + sFieldName + "  FROM " + sTableName;

        if (sCondition->Trim()->Length != 0)
        {
            tmp += " WHERE ";
            tmp += sCondition;
        }


        _DataTable dt = this->ExecSQLQuery(tmp);

        if (dt->Rows->Count > 0)
        {
            const _string&[] sArray = new const _string&[dt->Rows->Count];

            for (int i = 0; i < dt->Rows->Count; ++i)
            {
                sArray[i] = dt->Rows[i][sFieldName]->ToString()->Trim();
            }
            return sArray;
        }
        return new const _string&[0];
          */
        return _StringList();
    }


    /// <summary>
    /// 读出所有字段
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableReadAllForCSharp(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56")//INTEGER
                    {
                        tmp = tmp + sf.First + "= (int)dt->Rows[0][\"" + sf.First + "\"];" + "\n";
                    }
                    else if (sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //SMALLMONEY,FLOAT,MONEY
                    {
                        tmp = tmp + sf.First + "=Convert::ToSingle(dt->Rows[0][\"" + sf.First + "\"]);" + "\n";
                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        tmp = tmp + sf.First + "=Convert::ToDateTime(dt->Rows[0][\"" + sf.First + "\"]);" + "\n";
                    }
                    else if (sf.Second == "239" || sf.Second == "99") //NCHAR,NTEXT
                    {
                        tmp = tmp + sf.First + "= dt->Rows[0][\"" + sf.First + "\"]->ToString();" + "\n";
                    }
                    else if (sf.Second == "34") //Images
                    {
                        //tmp += "protected Image ";
                    }
                }
            }
        }
        return tmp;
       */
        return "";
    }


    /// <summary>
    /// 读出所有字段
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableReadAllForJava(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56")//INTEGER
                    {
                        tmp = tmp + sf.First + "= dt.getInt(0,\"" + sf.First + "\");" + "\n";
                    }
                    else if (sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //SMALLMONEY,FLOAT,MONEY
                    {
                        tmp = tmp + sf.First + "= dt.getFloat(0,\"" + sf.First + "\");" + "\n";
                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        tmp = tmp + sf.First + "= dt.getDate(0,\"" + sf.First + "\");" + "\n";
                    }
                    else if (sf.Second == "239" || sf.Second == "99") //NCHAR,NTEXT
                    {
                        tmp = tmp + sf.First + "= dt.getString(0,\"" + sf.First + "\");" + "\n";
                    }
                    else if (sf.Second == "34") //Images
                    {
                        //tmp += "protected Image ";
                    }
                }
            }
        }
        return tmp;
          */
        return "";
    }


    /// <summary>
    /// 自动创建CSharp Insert语句
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableInsertSQLForCSharp(const _string& sTableName)
    {
        /*
        const _string& tmp = "fd_id = GetNewID();" + "\n";
        tmp += "ssql = \"INSERT INTO \" + m_sTableName + " + "\n";
        tmp += "\"(";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count - 1; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);
                    tmp = tmp + sf.First + ",";

                    if ((j + 1) == (j + 1) / 5 * 5)
                    {
                        tmp += "\"+\n\"";
                    }
                }
                tmp += ls.GetIndex(ls.Count - 1).First + ") VALUES(\" + " + "\n";

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56" || sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //INTEGER,SMALLMONEY,FLOAT,MONEY
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_author_id" || sf.First == "fd_modify_author_id")
                            {
                                tmp = tmp + "\"\"+" + " GetLoginID()" + "+\",\" +" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "\"\"+" + sf.First + ".ToString()" + "+\",\" +" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "\"\"+" + sf.First + ".ToString()" + "+\")\";" + "\n";
                        }
                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        if (j != ls.Count - 1)
                        {

                            if (sf.First == "fd_create_time" || sf.First == "fd_modify_time")
                            {
                                tmp = tmp + "\"\\\'\"+" + "System::DateTime.Now.ToString() " + "+\"\\',\"+" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "\"\\\'\"+" + sf.First + ".ToShortDateString()" + "+\"\\',\"+" + "\n";
                            }

                        }
                        else
                        {
                            tmp = tmp + "\"\\\'\"+" + sf.First + ".ToShortDateString()" + "+\"\\',)\";" + "\n";
                        }
                    }
                    else if (sf.Second == "239" || sf.Second == "99" || sf.Second == "231") //NCHAR,NTEXT,NVARCHAR
                    {
                        if (j != ls.Count - 1)
                        {

                            tmp = tmp + "\"\\\'\"+" + "gce::CheckSQLString(" + sf.First + ")" + "+\"\\',\"+" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "\"\\\'\"+" + "gce::CheckSQLString(" + sf.First + ")" + "+\"\\')\";" + "\n";
                        }
                    }
                    else if (sf.Second == "34") //Images
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "\"\"+" + "请除去IMAGE数据" + "+\",\" +" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "\"\"+" + "请除去IMAGE数据" + "+\")\";" + "\n";
                        }
                    }
                    else
                    {
                        throw new System.Exception(sf.Second.ToString());
                    }

                }
            }
        }
        return tmp;
          */
        return "";
    }

    /// <summary>
    /// 自动创建Java Insert语句
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableInsertSQLForJava(const _string& sTableName)
    {
        /*
        const _string& tmp = "fd_id = GetNewID();" + "\n";
        tmp += "ssql = \"INSERT INTO \" + m_sTableName + " + "\n";
        tmp += "\"(";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count - 1; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);
                    tmp = tmp + sf.First + ",";

                    if ((j + 1) == (j + 1) / 5 * 5)
                    {
                        tmp += "\"+\n\"";
                    }
                }
                tmp += ls.GetIndex(ls.Count - 1).First + ") VALUES(\" + " + "\n";

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56" || sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //INTEGER,SMALLMONEY,FLOAT,MONEY
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_author_id" || sf.First == "fd_modify_author_id")
                            {
                                tmp = tmp + "\"\"+" + "csharp_MIS_Global::getLoginID()" + "+\",\" +" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "\"\"+" + sf.First + "+\",\" +" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "\"\"+" + sf.First + "+\")\";" + "\n";
                        }
                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        if (j != ls.Count - 1)
                        {

                            if (sf.First == "fd_create_time" || sf.First == "fd_modify_time")
                            {
                                tmp = tmp + "\"\\\'\"+" + "csharp_MIS_Global::strCurrentTime() " + "+\"\\',\"+" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "\"\\\'\"+ gce::strDate(" + sf.First + ")" + "+\"\\',\"+" + "\n";
                            }

                        }
                        else
                        {
                            tmp = tmp + "\"\\\'\"+ gce::strDate(" + sf.First + ")" + "+\"\\',)\";" + "\n";
                        }
                    }
                    else if (sf.Second == "239" || sf.Second == "99" || sf.Second == "231") //NCHAR,NTEXT,NVARCHAR
                    {
                        if (j != ls.Count - 1)
                        {

                            tmp = tmp + "\"\\\'\"+" + "gce::CheckSQLString(" + sf.First + ")" + "+\"\\',\"+" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "\"\\\'\"+" + "gce::CheckSQLString(" + sf.First + ")" + "+\"\\')\";" + "\n";
                        }
                    }
                    else if (sf.Second == "34") //Images
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "\"\"+" + "请除去IMAGE数据" + "+\",\" +" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "\"\"+" + "请除去IMAGE数据" + "+\")\";" + "\n";
                        }
                    }
                    else
                    {
                        throw new System.Exception(sf.Second.ToString());
                    }

                }
            }
        }
        return tmp;
          */
        return "";
    }



    /// <summary>
    /// 自动创建Create语句
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableUpdateSQLForCSharp(const _string& sTableName)
    {
        /*
        const _string& tmp = "ssql =\"UPDATE \"+ m_sTableName +  \" SET \";" + "\n";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56" || sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //INTEGER,SMALLMONEY,FLOAT,MONEY
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_author_id")
                            {

                            }
                            else if (sf.First == "fd_modify_author_id")
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + " GetLoginID()" + "+\",\";" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + sf.First + ".ToString()" + "+\",\";" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + sf.First + ".ToString()" + "+\"\";" + "\n";
                        }

                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_time")
                            {

                            }
                            else if (sf.First == "fd_modify_time")
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + "System::DateTime.Now.ToString() " + "+\"\\',\";" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + sf.First + ".ToShortDateString()" + "+\"\\',\";" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + sf.First + ".ToShortDateString()" + "+\"\\'\";" + "\n";
                        }

                    }
                    else if (sf.Second == "239" || sf.Second == "99" || sf.Second == "231") //NCHAR,NTEXT,NVARCHAR
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+ gce::CheckSQLString(" + sf.First + ")+\"\\',\";" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+ gce::CheckSQLString(" + sf.First + ")+\"\\'\";" + "\n";
                        }

                    }
                    else if (sf.Second == "34") //Images
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + "请除去IMAGE数据" + "+\",\";" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + "请除去IMAGE数据" + "+\"\";" + "\n";
                        }
                    }
                }

            }
        }

        tmp += "ssql += \"  WHERE fd_id=\" + " + "fd_id.ToString(); ";
        return tmp;
          */
        return "";
    }


    /// <summary>
    /// 自动创建Create语句
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableUpdateSQLForJava(const _string& sTableName)
    {
        /*
        const _string& tmp = "ssql =\"UPDATE \"+ m_sTableName +  \" SET \";" + "\n";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56" || sf.Second == "122" || sf.Second == "62" || sf.Second == "60") //INTEGER,SMALLMONEY,FLOAT,MONEY
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_author_id")
                            {

                            }
                            else if (sf.First == "fd_modify_author_id")
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + "csharp_MIS_Global::getLoginID()" + "+\",\";" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + sf.First + "+\",\";" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + sf.First + "+\"\";" + "\n";
                        }

                    }
                    else if (sf.Second == "58" || sf.Second == "61") //SMALLDATETIME,DATETIME
                    {
                        if (j != ls.Count - 1)
                        {
                            if (sf.First == "fd_create_time")
                            {

                            }
                            else if (sf.First == "fd_modify_time")
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + " csharp_MIS_Global::strCurrentTime() " + "+\"\\',\";" + "\n";
                            }
                            else
                            {
                                tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + "gce::strDate(" + sf.First + " ) " + " +\"\\',\";" + "\n";
                            }
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+" + "gce::strDate(" + sf.First + ")" + "+\"\\'\";" + "\n";
                        }

                    }
                    else if (sf.Second == "239" || sf.Second == "99" || sf.Second == "231") //NCHAR,NTEXT,NVARCHAR
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+ gce::CheckSQLString(" + sf.First + ")+\"\\',\";" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\\\'\"+ gce::CheckSQLString(" + sf.First + ")+\"\\'\";" + "\n";
                        }

                    }
                    else if (sf.Second == "34") //Images
                    {
                        if (j != ls.Count - 1)
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + "请除去IMAGE数据" + "+\",\";" + "\n";
                        }
                        else
                        {
                            tmp = tmp + "ssql+=  \"" + sf.First + "=\"+" + "请除去IMAGE数据" + "+\"\";" + "\n";
                        }
                    }
                }

            }
        }

        tmp += "ssql += \"  WHERE fd_id=\" + " + "fd_id; ";
        return tmp;
          */
        return "";
    }





    /// <summary>
    /// 自动创建Access数据表语句
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getCreateAccessTableForCSharp(const _string& sTableName)
    {
        /*
        const _string& tmp = "";
        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {

            tmp += "ADOX.Catalog catalog = new Catalog();" + "\n";
            tmp += "ADODB.Connection cn = new ADODB.Connection();" + "\n";
            tmp += "cn.Open(getConnectString(), null, null, -1);" + "\n";
            tmp += "catalog.ActiveConnection = cn;" + "\n";
            tmp += "//---------------------------------------------------------------------创建表" + "\n";
            tmp += "ADOX.Table table = new ADOX.Table();" + "\n";
            tmp += "table.Name = \"" + sTableName + "\";" + "\n";
            tmp += "for (int i = 0; i < catalog.Tables.Count; ++i)" + "\n";
            tmp += "{";
            tmp += " \tif (catalog.Tables[i].Name == table.Name)" + "\n";
            tmp += " \t{" + "\n";
            tmp += "\t\treturn false;" + "\n";
            tmp += " \t}" + "\n";
            tmp += "}" + "\n";


            tmp += "//--------------------------------------------------------------------创建字段" + "\n";
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype],[prec] FROM [syscolumns] where [id]=\'" + sid + "\'");

                for (int i = 1; i < dt->Rows->Count; ++i)
                {
                    const _string& sFieldName = dt->Rows[i]["name"]->ToString();
                    int xtype = System::Convert::ToInt32(dt->Rows[i]["xtype"]);

                    tmp += "ADOX.Column " + sFieldName + " = new ADOX.Column();" + "\n";
                    tmp += sFieldName + ".ParentCatalog = catalog;" + "\n";
                    tmp += sFieldName + ".Name = " + "\"" + sFieldName + "\";" + "\n";

                    if (xtype == 56) //INTEGER
                    {
                        tmp += sFieldName + ".Type = DataTypeEnum.adInteger;" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"INTEGER\";" + "\n";
                        tmp += sFieldName + ".Properties[\"Default\"].Value = 1;" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adInteger, 0);" + "\n\n";
                    }
                    else if (xtype == 122)//SMALLMONEY
                    {
                        tmp += sFieldName + ".Type = DataTypeEnum.adCurrency;" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"SMALLMONEY\";" + "\n";
                        tmp += sFieldName + ".Properties[\"Default\"].Value = 1;" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adCurrency, 0);" + "\n\n";
                    }
                    else if (xtype == 63)//FLOAT
                    {

                    }
                    else if (xtype == 58 || xtype == 61) //SMALLDATETIME,DATETIME
                    {
                        tmp += sFieldName + ".Type = DataTypeEnum.adDate;" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"时间\";" + "\n";
                        tmp += sFieldName + ".Properties[\"Default\"].Value = \"Now()\";" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adDate, 0);" + "\n\n";
                    }
                    else if (xtype == 239) //NCHAR
                    {

                        tmp += sFieldName + ".Type = DataTypeEnum.adVarWChar;" + "\n";
                        tmp += sFieldName + ".DefinedSize = " + dt->Rows[i]["prec"]->ToString() + ";" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"NCHAR\";" + "\n";
                        tmp += sFieldName + ".Properties[\"Default\"].Value = \"\";" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adVarWChar, " + dt->Rows[i]["prec"]->ToString() + ");" + "\n\n";
                    }
                    else if (xtype == 99)//NTEXT
                    {
                        tmp += sFieldName + ".Type = DataTypeEnum.adLongVarWChar;" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"NTEXT\";" + "\n";
                        tmp += sFieldName + ".Properties[\"Default\"].Value = \"\";" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adLongVarWChar, 0);" + "\n\n";

                    }
                    else if (xtype == 34) //Images
                    {
                        tmp += sFieldName + ".Type = DataTypeEnum.adLongVarBinary;" + "\n";
                        tmp += sFieldName + ".Properties[\"Description\"].Value = \"adLongVarBinary\";" + "\n";
                        tmp += "table.Columns.Append(" + sFieldName + ", DataTypeEnum.adLongVarBinary, 0);" + "\n\n";

                    }

                }

            }
        }

        return tmp;
          */
          return "";
    }

    /// <summary>
    /// 获取protected的字段声明
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableFieldDeclareForCSharpProtected(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56") //INTEGER		IDENTITY (1, 1)	PRIMARY KEY,
                    {
                        tmp += "protected int ";
                    }
                    else if (sf.Second == "58") //SMALLDATETIME
                    {
                        tmp += "protected DateTime ";
                    }
                    else if (sf.Second == "239") //NCHAR
                    {
                        tmp += "protected const _string& ";
                    }
                    else if (sf.Second == "122") //SMALLMONEY
                    {
                        tmp += "protected float ";
                    }
                    else if (sf.Second == "99") //NTEXT
                    {
                        tmp += "protected const _string& ";
                    }
                    else if (sf.Second == "61") //DATETIME
                    {
                        tmp += "protected DateTime ";
                    }
                    else if (sf.Second == "34") //Images
                    {
                        tmp += "protected Image ";
                    }
                    else if (sf.Second == "62" || sf.Second == "60") //FLOAT,MONEY
                    {
                        tmp += "protected float ";
                    }

                    tmp = tmp + " " + sf.First + ";\n";

                }

            }
        }
        return tmp;
          */
        return "";
    }


    /// <summary>
    /// 获取public的字段声明
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableFieldDeclareForCSharpPublic1(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);
                    if (sf.First == "fd_id")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_create_time")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_modify_time")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_create_author_id")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_modify_author_id")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_nchar_ext1")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_nchar_ext2")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_ntext_ext1")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_ntext_ext2")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_integer_ext1")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_integer_ext2")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_float_ext1")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_float_ext2")
                    {
                        tmp += "//";
                    }
                    else if (sf.First == "fd_desc")
                    {
                        tmp += "//";
                    }

                    if (sf.Second == "56") //INTEGER		IDENTITY (1, 1)	PRIMARY KEY,
                    {
                        tmp += "int " + sf.First.Substring(3, sf.First.Length - 3);
                    }
                    else if (sf.Second == "58") //SMALLDATETIME
                    {
                        tmp += "DateTime " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "239") //NCHAR
                    {
                        tmp += "const _string& " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "122") //SMALLMONEY
                    {
                        tmp += "float " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "99") //NTEXT
                    {
                        tmp += "const _string& " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "61") //DATETIME
                    {
                        tmp += "DateTime " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "34") //Images
                    {
                        tmp += "Image " + sf.First.Substring(3, sf.First.Length - 3);

                    }
                    else if (sf.Second == "62" || sf.Second == "60") //FLOAT,MONEY
                    {
                        tmp += "float " + sf.First.Substring(3, sf.First.Length - 3);

                    }

                    tmp += "{  get{return " + sf.First + ";}  set{" + sf.First + "=value;} }";
                    tmp += "\n";
                }

            }
        }
        return tmp;
          */
        return "";
    }


    /// <summary>
    /// 获取public的字段声明
    /// </summary>
    /// <param name="sTableName"></param>
    /// <returns></returns>
    const _string& getTableFieldDeclareForCSharpPublic2(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56") //INTEGER		IDENTITY (1, 1)	PRIMARY KEY,
                    {
                        tmp += "int " + sf.First.Substring(3, sf.First.Length - 3) + "\n";
                    }
                    else if (sf.Second == "58") //SMALLDATETIME
                    {
                        tmp += "DateTime " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "239") //NCHAR
                    {
                        tmp += "const _string& " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "122") //SMALLMONEY
                    {
                        tmp += "float " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "99") //NTEXT
                    {
                        tmp += "const _string& " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "61") //DATETIME
                    {
                        tmp += "DateTime " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "34") //Images
                    {
                        tmp += "Image " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }
                    else if (sf.Second == "62" || sf.Second == "60") //FLOAT,MONEY
                    {
                        tmp += "float " + sf.First.Substring(3, sf.First.Length - 3) + "\n";

                    }

                    tmp += "{\n";
                    tmp += "\tget\n";
                    tmp += "\t{\n";
                    tmp += "\t\treturn " + sf.First + ";" + "\n";
                    tmp += "\t}\n";
                    tmp += "\tset\n";
                    tmp += "\t{\n";
                    tmp += "\t\t" + sf.First + "=value;" + "\n";
                    tmp += "\t}\n";
                    tmp += "}\n";

                    tmp += "\n\n";

                }

            }
        }
        return tmp;
          */
        return "";
    }

    const _string& getTableFieldDeclareForCSharpPublic3(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);

                    if (sf.Second == "56") //INTEGER		IDENTITY (1, 1)	PRIMARY KEY,
                    {
                        tmp += "int ";
                    }
                    else if (sf.Second == "58") //SMALLDATETIME
                    {
                        tmp += "DateTime ";
                    }
                    else if (sf.Second == "239") //NCHAR
                    {
                        tmp += "const _string& ";
                    }
                    else if (sf.Second == "122") //SMALLMONEY
                    {
                        tmp += "float ";
                    }
                    else if (sf.Second == "99") //NTEXT
                    {
                        tmp += "const _string& ";
                    }
                    else if (sf.Second == "61") //DATETIME
                    {
                        tmp += "DateTime ";
                    }
                    else if (sf.Second == "34") //Images
                    {
                        tmp += "Image ";
                    }
                    else if (sf.Second == "62" || sf.Second == "60") //FLOAT,MONEY
                    {
                        tmp += "float ";
                    }

                    tmp = tmp + " " + sf.First + ";\n";

                }

            }
        }
        return tmp;
          */
        return "";
    }

    //List<_field> GetFileds



    /// <summary>
    /// 获取字段信息描述
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <returns></returns>
    const _string& GetAllFieldDesc(const _string& sTableName)
    {
        /*
        const _string& tmp = "";

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
            throw new Exception("函数未完成!");
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");

            if (dt->Rows->Count > 0)
            {
                LPairList<const _string&, const _string&> ls = new LPairList<const _string&, const _string&>();

                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name],[xtype] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    ls.Add(dt->Rows[i]["name"]->ToString(), dt->Rows[i]["xtype"]->ToString());
                }

                for (int j = 0; j < ls.Count; j++)
                {
                    _Pair<const _string&, const _string&> sf = ls.GetIndex(j);
                    tmp += sf.First;
                    tmp += "    ";

                    tmp += "SQLServer类型:" + _field.GetSQLServerXTypeString(Convert::ToInt32(sf.Second)) + "(xtype值:" + sf.Second + ")";

                    tmp += "\t";

                    tmp += "C#类型:" + _field.SQLServerXTYPConverToCSharpTypeName(Convert::ToInt32(sf.Second));

                    tmp += "\n";
                }
            }
        }
        else
        {
            throw new Exception("函数未完成!");
        }

        return tmp;
          */
        return "";
    }


    const _string& GetFieldDesc(const _string& sFieldName, const _string& sTableName)
    {
        /*
        if (dataFormat == _DataFormat.dfSQLServer)
        {
            const _string& ssql = "select [syscolumns].[name],[syscolumns].[xtype] FROM [sysobjects],[syscolumns] where [syscolumns].[id] = [sysobjects].[id]  AND [sysobjects].[name] = \'";
            ssql += sTableName;
            ssql += "\'";
            ssql += " AND [syscolumns].[name] = \'";
            ssql += sFieldName;
            ssql += "\'";

            _DataTable dt = ExecSQLQuery(ssql);

            const _string& tmp = "";

            foreach(_DataRow dr in dt->Rows)
            {
                tmp += dr["name"]->ToString();
                tmp += "\t";
                tmp += "SQLServer类型:" + _field.GetSQLServerXTypeString(Convert::ToInt32(dr["xtype"])) + "(xtype值:" + dr["xtype"]->ToString() + ")";
                tmp += "\t";
                tmp += "C#类型:" + _field.SQLServerXTYPConverToCSharpTypeName(Convert::ToInt32(dr["xtype"]));

                tmp += "\n";
            }

            return tmp;
        }
        else
        {
            throw new Exception("函数未完成!");
        }
          */
        return "";
    }


    _DList<_field> GetAllFieldInfo(const _string& sTableName)
    {
        /*
        List<_field> lResult = new List<_field>();

        if (dataFormat == _DataFormat.dfSQLServer)
        {
            const _string& ssql = "select [syscolumns].[name],[syscolumns].[xtype] FROM [sysobjects],[syscolumns] where [syscolumns].[id] = [sysobjects].[id]  AND [sysobjects].[name] = \'";
            ssql += sTableName;
            ssql += "\'";

            _DataTable dt = ExecSQLQuery(ssql);

            foreach(_DataRow dr in dt->Rows)
            {
                _field tmpNew = new _field();
                tmpNew.Name = dr["name"]->ToString();
                tmpNew.SetSQLServerXType(System::Convert::ToInt32(dr["xtype"]));
                lResult.Add(tmpNew);
            }
        }
        else
        {
            throw new Exception("函数未完成!");
        }


        return lResult;
          */
        return _DList<_field>();
    }

    _field GetFieldInfo(const _string& sFieldName, const _string& sTableName)
    {
        /*
        _field fResult = new _field();

        if (dataFormat == _DataFormat.dfSQLServer)
        {
            const _string& ssql = "select [syscolumns].[name],[syscolumns].[xtype] FROM [sysobjects],[syscolumns] where [syscolumns].[id] = [sysobjects].[id]  AND [sysobjects].[name] = \'";
            ssql += sTableName;
            ssql += "\'";
            ssql += " AND [syscolumns].[name] = \'";
            ssql += sFieldName;
            ssql += "\'";

            _DataTable dt = ExecSQLQuery(ssql);

            foreach(_DataRow dr in dt->Rows)
            {
                _field tmpNew = new _field();
                tmpNew.Name = dr["name"]->ToString();
                tmpNew.SetSQLServerXType(System::Convert::ToInt32(dr["xtype"]));
                return tmpNew;
            }
        }
        else
        {
            throw new Exception("函数未完成!");
        }


        return fResult;
          */
        return _field();
    }


    /*
    ///<summary>
    ///得到某个字段值的列表
    ///</summary>
    void GetTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sSQL, List<const _string&> sl)
    {
        if (sl != null)
        {
            sl.Clear();

            const _string& tmp;

            if (sSQL->Trim()->Length == 0)
            {
                tmp = "SELECT " + sFieldName + " FROM " + sTableName;
            }
            else
            {
                tmp = sSQL;

            }

            _DataTable dt = this->ExecSQLQuery(tmp, false);

            if (dt->Rows->Count > 0)
            {
                for (int i = 0; i < dt->Rows->Count; i++)
                {
                    sl.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
                }
            }
        }
    }
    */

#if _WINDOWS_WEB_

    ///<summary>
    ///得到某个字段值的列表
    ///</summary>		
    void GetDistinctTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sCondition, ListItemCollection sList)
    {
        if (sList != null)
        {
            sList.Clear();

            const _string& tmp;

            if (sCondition->Trim()->Length == 0)
            {
                tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName;
            }
            else
            {
                tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName + " WHERE " + sCondition;

            }

            _DataTable dt = this->ExecSQLQuery(tmp);

            if (dt->Rows->Count > 0)
            {
                for (int i = 0; i < dt->Rows->Count; i++)
                {
                    sList.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
                }
            }
        }
    }


    ///<summary>
    ///得到某个字段值的列表
    ///</summary>	
    void GetTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sCondition, ListItemCollection sList)
    {
        if (sList != null)
        {
            sList.Clear();

            const _string& tmp;

            if (sCondition->Trim()->Length == 0)
            {
                tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName;
            }
            else
            {
                tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName + " WHERE " + sCondition;

            }

            _DataTable dt = this->ExecSQLQuery(tmp);

            if (dt->Rows->Count > 0)
            {
                for (int i = 0; i < dt->Rows->Count; i++)
                {
                    sList.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
                }
            }
        }
    }

#endif

    ///<summary>
    ///得到某个字段值的列表
    ///</summary>	
    _StringList GetTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sCondition)
    {
        /*
        _StringList sResult = new _StringList();


        const _string& tmp;

        if (sCondition->Trim()->Length == 0)
        {
            tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName;
        }
        else
        {
            tmp = "SELECT Distinct " + sFieldName + " FROM " + sTableName + " WHERE " + sCondition;

        }

        _DataTable dt = this->ExecSQLQuery(tmp);

        if (dt->Rows->Count > 0)
        {
            for (int i = 0; i < dt->Rows->Count; i++)
            {
                sResult.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
            }
        }

        return sResult;
          */
        return _StringList();
    }







    /// <summary>
    /// 获取表的两个字段值
    /// </summary>
    /// <param name="sFieldName1"></param>
    /// <param name="sFieldName2"></param>
    /// <param name="sTableName"></param>
    /// <param name="sCondition"></param>
    /// 创建时间:2020-05-07    最后一次修改时间:2020-05-07
    /// <returns></returns>
    _DList<_Pair<_string,_string>> GetTrimFieldValuePairList(const _string& sFieldName1, const _string& sFieldName2, const _string& sTableName, const _string& sCondition = "")
    {
        /*
        LStringPairList plResult = new LStringPairList();


        const _string& ssql = "SELECT [" + sFieldName1 + "],[" + sFieldName2 + "] FROM [" + sTableName + "]";

        if (sCondition->Trim()->Length != 0)
        {
            ssql += " WHERE " + sCondition;
        }


        _DataTable dt = ExecSQLQuery(ssql);


        foreach(_DataRow dr in dt->Rows)
        {
            const _string& s1 = dr[sFieldName1]->ToString()->Trim();
            const _string& s2 = dr[sFieldName2]->ToString()->Trim();
            plResult.Add(s1, s2);
        }

        return plResult;
          */
        return _DList<_Pair<_string, _string>>();
    }



    /// <summary>
    /// 查字段值为oFieldValue的第一条记录,如果找到,则返回第一条记录的ID,否则返回-1;
    /// 注意,字段类型必须为字符串
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <param name="sFieldName">字段名</param>
    /// <param name="sFileValue">字段值</param>
    /// <param name="s_condition">条件,可以为空</param>
    /// 创建时间: 约 2008-01-01          最后一次修改时间:2020-03-25
    /// <returns>如果找到,则返回第一条记录的ID,否则返回-1,字符串字段</returns>
    int find_s(const _string& sTableName, const _string& sFieldName, const _string& sFileValue, const _string& s_condition = "")
    {
        /*
        const _string& ssql = "SELECT [fd_id],[" + sFieldName + "] FROM [" + sTableName + "] WHERE ["
            + sFieldName + "] =\'" + gce::CheckSQLString(sFileValue) + "\'";

        if (s_condition.Trim() != "")
            ssql += " AND " + s_condition;

        _DataTable dt = ExecSQLQuery(ssql);
        if (dt->Rows->Count > 0)
        {
            return (int)dt->Rows[0]["fd_id"];

        }
        return -1;
        */
        return 0;
    }


    /// <summary>
    /// 检查数据库是否存在表名sTableName
    /// </summary>
    /// <param name="sTableName">表名</param>
    /// <returns></returns>
    bool IsExistTableName(const _string& sTableName)
    {
        /*

#if _WINDOWS_PLATFORM_

        bool bResult = false;

        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
            ADOX.Catalog catalog = new Catalog();
            ADODB.Connection cn = new ADODB.Connection();
            cn.Open(GetConnection().ConnectionString, null, null, -1);
            catalog.ActiveConnection = cn;

            for (int i = 0; i < catalog.Tables.Count; ++i)
            {
                if (catalog.Tables[i].Name.ToLower() == sTableName->Trim()->ToLower())
                {
                    bResult = true;
                    break;
                }
            }

            cn.Close();
            catalog.ActiveConnection = null;
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [name] FROM sysobjects WHERE type = \'U\' ORDER BY [name]");

            for (int i = 0; i < dt->Rows->Count; ++i)
            {
                if (dt->Rows[i]["NAME"]->ToString().ToLower() == sTableName->Trim()->ToLower())
                {
                    bResult = true;
                    break;
                }
            }

        }
        return bResult;

#else

        throw new Exception(gce::OnCodeDidNotFinishError);
#endif
        */
    }










#if _WINDOWS_DESKTOP_

    /// <summary>
    /// 把执行的结果集在DataGridView中显示
    /// </summary>
    /// <param name="sSQL">SQL语句</param>
    /// <param name="dg_view">DataGridView</param>
    /// <returns>返回执行结果集</returns>
    _DataTable ExecSQLView(const _string& sSQL, System.Windows.Forms.DataGridView dg_view)
    {

        _DataTable dt = new _DataTable();

        if (sSQL->Trim()->Length == 0) return dt;

        try
        {

            GetViewDbDataAdapter().SelectCommand.CommandText = sSQL;
            GetViewDbDataAdapter().Fill(dt);
        }
        catch (Exception e)
        {
            gce::ShowError(e.ToString(), "_db.ExecSQLView");

            gce::ShowError("执行 SQL语句: \n  " + sSQL + "\n出错!", "_db.ExecSQLView");
        }


        if (dg_view != null)
        {

            dg_view.DataSource = dt;

            //gvView.DataBind();

            //for(int i=0; i<gvView.Columns.Count; ++i)
            //{
            //	gvView.Columns[i].HeaderStyle.Width = 80;
            //}
        }
        return dt;
    }
#endif

#if _WINDOWS_WEB_

    /// <summary>
    /// 把执行的结果集在DataGridView中显示
    /// </summary>
    /// <param name="sSQL">SQL语句</param>
    /// <param name="dg_view">DataGridView</param>
    /// <returns>返回执行结果集</returns>
    _DataTable ExecSQLView(const _string& sSQL, System.Web.UI.WebControls.GridView dg_view)
    {

        _DataTable dt = new _DataTable();

        if (sSQL->Trim()->Length == 0) return dt;


        getViewDbDataAdapter().SelectCommand.CommandText = sSQL;
        getViewDbDataAdapter().Fill(dt);




        if (dg_view != null)
        {

            dg_view.DataSource = dt;

            //gvView.DataBind();

            //for(int i=0; i<gvView.Columns.Count; ++i)
            //{
            //	gvView.Columns[i].HeaderStyle.Width = 80;
            //}
        }
        return dt;
    }
#endif




#if _WINDOWS_DESKTOP_
    ///<summary>
    ///得到某个字段值的列表
    ///</summary>		
    void GetTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sCondition, ComboBox cb)
    {

        cb.Items.Clear();

        String ssql = "SELECT [" + sFieldName + "]  FROM [" + sTableName + "]";


        if (sCondition->Trim()->Length != 0)
        {
            ssql += " WHERE " + sCondition;
        }

        _DataTable dt = this->ExecSQLQuery(ssql);

        foreach(_DataRow dr in dt->Rows)
        {
            cb.Items.Add(dr[sFieldName]->ToString()->Trim());
        }

    }

    /// <summary>
    /// 创建时间: 2020-05-23  最后一次修改时间:2020-05-31
    /// 获取两个字段的值,在ComboBox中显示第二个字段的字符串值,如果有第三个字段,则在括号显示第三个字段。 
    /// 显示格式:LPairt( FieldName1, FieldName2(FieldName3 + FieldName4 + .....) )
    /// </summary>
    /// <param name="sIntFieldName">字段1,字段1必须是int整</param>
    /// <param name="sSplitFieldName">可以多个字段,用分隔符","表示</param>
    /// <param name="sTableName">表名</param>
    /// <param name="sCondition">条件</param>
    /// <param name="cb">ComboBox</param>
    void GetPairFieldValueList(const _string& sIntFieldName, const _string& sSplitFieldName, const _string& sTableName, const _string& sCondition, ComboBox cb)
    {
        cb.Items.Clear();


        UStringListCI_ sFileNameList = sSplitFieldName._SplitCI(",", true);

        const _string& ssql = "SELECT [" + sIntFieldName + "]";


        if (sFileNameList.Count != 0)
        {
            foreach(const _string& s in sFileNameList)
            {
                ssql += ",[" + s + "]";
            }
        }


        ssql += " FROM[" + sTableName + "]";



        if (sCondition->Trim()->Length != 0)
        {
            ssql += " WHERE " + sCondition;
        }

        _DataTable dt = this->ExecSQLQuery(ssql);

        foreach(_DataRow dr in dt->Rows)
        {
            _Pair<int, const _string&> p = new _Pair<int, const _string&>();

            p.First = (int)dr[sIntFieldName];
            p.Second = "";
            if (sFileNameList.Count > 0)
            {
                p.Second += dr[sFileNameList[0]]->ToString()->Trim();

                const _string& sTemp = "";

                for (int i = 1; i < sFileNameList.Count; ++i)
                {
                    sTemp += dr[sFileNameList[i]]->ToString()->Trim();
                }

                if (sTemp != "")
                {
                    p.Second = p.Second + "(" + sTemp + ")";
                }
            }

            cb.Items.Add(p);
        }
    }









    ///<summary>
    ///得到某个字段值的列表
    ///</summary>		
    void GetTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sSQL, ListBox lb)
    {
        if (lb == null || sTableName->Trim()->Length == 0)
            throw new Exception("lb == null || sTableName->Trim()->Length == 0");


        lb.Items.Clear();

        const _string& tmp;

        if (sSQL->Trim()->Length == 0)
        {
            tmp = "SELECT [" + sFieldName + "] FROM " + sTableName;
        }
        else
        {
            tmp = sSQL;

        }

        _DataTable dt = this->ExecSQLQuery(tmp);

        if (dt->Rows->Count > 0)
        {
            for (int i = 0; i < dt->Rows->Count; i++)
            {
                lb.Items.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
            }
        }

    }


    void GetIDAndNameCNList(const _string& sTableName, const _string& sCondition, ListView lv)
    {
        if (lv == null || sTableName->Trim()->Length == 0)
            throw new Exception("lv == null || sTableName->Trim()->Length == 0");

        lv.Items.Clear();

        const _string& sSQL = "SELECT [fd_id],[fd_name_cn] FROM [" + sTableName + "] ";

        if (sCondition->Trim()->Length != 0)
        {
            sSQL += " WHERE ";
            sSQL += sCondition;

        }

        _DataTable dt = this->ExecSQLQuery(sSQL);

        if (dt->Rows->Count > 0)
        {
            for (int i = 0; i < dt->Rows->Count; i++)
            {
                ListViewItem lvi = new ListViewItem();

                lvi.Text = dt->Rows[i]["fd_name_cn"]->ToString()->Trim();
                lvi.Name = dt->Rows[i]["fd_id"]->ToString();
                lvi.StateImageIndex = i;
                lvi.ImageIndex = i;

                lv.Items.Add(lvi);
            }
        }
    }






    /// <summary>
    /// 获取所有表
    /// </summary>
    /// <param name="il"></param>
    void getTableNames(IList il)
    {
        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
            ADOX.Catalog catalog = new Catalog();
            ADODB.Connection cn = new ADODB.Connection();
            cn.Open(GetConnection().ConnectionString, null, null, -1);
            catalog.ActiveConnection = cn;

            for (int i = 0; i < catalog.Tables.Count; ++i)
            {
                il.Add(catalog.Tables[i].Name);
            }

            cn.Close();
            catalog.ActiveConnection = null;
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [name] FROM sysobjects WHERE type = \'U\' ORDER BY [name]");

            for (int i = 0; i < dt->Rows->Count; ++i)
            {
                il.Add(dt->Rows[i]["NAME"]->ToString());
            }

        }

    }


    _StringList getTableNames()
    {
        _StringList ls = new _StringList();
        if (dataFormat == _DataFormat.dfAccdb || dataFormat == _DataFormat.dfMDB)
        {
            ADOX.Catalog catalog = new Catalog();
            ADODB.Connection cn = new ADODB.Connection();
            cn.Open(GetConnection().ConnectionString, null, null, -1);
            catalog.ActiveConnection = cn;

            for (int i = 0; i < catalog.Tables.Count; ++i)
            {
                ls.Add(catalog.Tables[i].Name);
            }

            cn.Close();
            catalog.ActiveConnection = null;
        }
        else if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [name] FROM sysobjects WHERE type = \'U\' ORDER BY [name]");

            for (int i = 0; i < dt->Rows->Count; ++i)
            {
                ls.Add(dt->Rows[i]["NAME"]->ToString());
            }

        }
        else if (dataFormat == _DataFormat.dfSQLite)
        {
            const _string& ssql = "SELECT [name] FROM sqlite_master WHERE type = \'table\' ORDER BY [name]";

            _DataTable dt = ExecSQLQuery(ssql);

            for (int i = 0; i < dt->Rows->Count; ++i)
            {
                ls.Add(dt->Rows[i]["name"]->ToString());
            }
        }

        return ls;
    }




    /// <summary>
    /// 获取某个表所有的字段名
    /// </summary>
    /// <param name="sTableName"></param>
    void getFields(const _string& sTableName, IList il)
    {
        if (dataFormat == _DataFormat.dfSQLServer)
        {
            _DataTable dt = ExecSQLQuery("SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'");
            if (dt->Rows->Count > 0)
            {
                il.Clear();
                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name] FROM [syscolumns] where [id]=\'" + sid + "\'");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    il.Add(dt->Rows[i]["name"]->ToString());
                }
            }
        }
    }


    _StringList getFields(const _string& sTableName)
    {
        _StringList slResult = new _StringList();
        const _string& ssql = "";

        if (dataFormat == _DataFormat.dfSQLServer)
        {
            ssql = "SELECT [id] FROM [sysobjects] where [name] =\'" + sTableName + "\'";
            _DataTable dt = ExecSQLQuery(ssql);
            if (dt->Rows->Count > 0)
            {
                const _string& sid = dt->Rows[0]["id"]->ToString();
                dt = ExecSQLQuery("select [name] FROM [syscolumns] where [id]=\'" + sid + "\' ORDER BY [colorder]");
                for (int i = 0; i < dt->Rows->Count; ++i)
                {
                    slResult.Add(dt->Rows[i]["name"]->ToString());
                }
            }
        }
        else if (dataFormat == _DataFormat.dfSQLite)
        {
            ssql = "PRAGMA table_info([" + sTableName + "])";
            _DataTable dt = ExecSQLQuery(ssql);
            foreach(_DataRow dr in dt->Rows)
            {
                slResult.Add(dr["name"]->ToString());
            }
        }

        return slResult;
    }


    ///<summary>
    ///得到某个字段值的不重复的列表
    ///</summary>		
    void GetDistinctTrimFieldValueList(const _string& sFieldName, const _string& sTableName, const _string& sSQL, ComboBox cb)
    {
        if (cb != null)
        {
            cb.Items.Clear();

            const _string& tmp;

            if (sSQL->Trim()->Length == 0)
            {
                tmp = "SELECT DISTINCT " + sFieldName + " FROM " + sTableName;
            }
            else
            {
                tmp = sSQL;

            }

            _DataTable dt = this->ExecSQLQuery(tmp);

            if (dt->Rows->Count > 0)
            {
                for (int i = 0; i < dt->Rows->Count; i++)
                {
                    cb.Items.Add(dt->Rows[i][sFieldName]->ToString()->Trim());
                }
            }
        }
    }

#endif

    static const _string& getColumnType(const _string& sType)
    {
        /*
        const _string& value = null;
        if (sType == "const _string&")
        {
            value = " text ";
        }
        else if (sType == "int")
        {
            value = " integer ";
        }
        else if (sType == "bool")
        {
            value = " boolean ";
        }
        else if (sType == "float")
        {
            value = " float ";
        }
        else if (sType == "double")
        {
            value = " double ";
        }
        else if (sType == "char")
        {
            value = " varchar ";
        }
        else if (sType == "long")
        {
            value = " long ";
        }
        
        // * SQLite 没有一个单独的存储类用于存储日期和/或时间,但SQLite是能够存储日期和时间为TEXT,REAL或INTEGER值。
         //   日期格式
//
        //    TEXT A date in a format like "YYYY-MM-DD HH:MM:SS.SSS".
         //   REAL The number of days since noon in Greenwich on November 24, 4714 B.C.
         //   INTEGER The number of seconds since 1970-01-01 00:00:00 UTC.
          
        else if (sType == "DateTime")
        {
            value = " text ";
        }
        return value;
        */
       
            return "";
    }





    /// <summary>
    /// 创建时间:2016-11-25 最后一次修改时间:2016-11-25
    /// 第一,以类名作为表名;第二,凡是以fd_开头定义的成员均作为字段名,第三、自动创建fd_id为AUTOINCREMENT
    /// </summary>
    /// <typeparam name="T">所有创建表的类,其中以类名作为表名</typeparam>
    /// <param name="df">数据库格式</param>
    /// <returns>返回创建表的的SQL语句</returns>
    static const _string& getCreateTableSql(_DataFormat df)
    {
        /*
        StringBuilder sb = new StringBuilder();

        if (df == _DataFormat.dfSQLite)
        {
            //将类名作为表名    	
            const _string& sTableName = typeof(T).Name;  // Utils.getTableName(clazz);
            sb.Append("create table ").Append(sTableName).Append(" (fd_id  INTEGER PRIMARY KEY AUTOINCREMENT,\n ");

            foreach(FieldInfo fi in typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
            {
                const _string& sFieldName = fi.Name;
                const _string& sFileType = fi.FieldType.Name;

                if (sFieldName.IndexOf("fd_id") == -1 && sFieldName.IndexOf("fd_") != -1)
                {
                    const _string& sValue = "";
                    if (sFileType == "String") { sValue = " text "; }
                    else if (sFileType == "Int32") { sValue = " integer "; }
                    else if (sFileType == "Int32") { sValue = " integer "; }
                    else if (sFileType == "Int64") { sValue = " long "; }
                     
                   // SQLite 没有一个单独的存储类用于存储日期和/或时间,但SQLite是能够存储日期和时间为TEXT,REAL或INTEGER值。
                   //     日期格式
                   // TEXT A date in a format like "YYYY-MM-DD HH:MM:SS.SSS".
                    //REAL The number of days since noon in Greenwich on November 24, 4714 B.C.
                    //INTEGER The number of seconds since 1970-01-01 00:00:00 UTC.
                     
                    else if (sFileType == "Single") { sValue = " float "; }
                    else if (sFileType == "DateTime") { sValue = " text "; }
                    else if (sFileType == "Boolean") { sValue = " boolean "; }
                    else if (sFileType == "Char") { sValue = " varchar "; }
                    else if (sFileType == "Double") { sValue = " double "; }
                    else if (sFileType == "MemoryStream") { sValue = " unknown "; }

                    if (sValue != "")
                        sb.Append(sFieldName).Append(sValue).Append(",\n ");
                }
            }//---------------foreach
            sb.Replace(",\n", ")", sb.Length - 3, 3); //括号收尾
        }
        else if (df == _DataFormat.dfSQLServer)
        {

        }
        else if (df == _DataFormat.dfAccdb)
        {

        }

        return sb.ToString();

              */
        return "";

    }//-------------------------------getCreateTableSql




     


};//------------------------------------------------------------_db






_LF_END_ 

_db.cpp

#include "X:\Work\Share\CCode\CPlatform\Base\_Macro.h"
 
#ifdef _USE_WINDOWS_
    #include <windows.h>
    #include <sqltypes.h>
    #include <sql.h>
    #include <sqlext.h>
#endif
 
#include "_db.h" //这个文件一定要在上面的几个头文件下面



_LF_BEGIN_


/***************************************************************
                        
                        _DataTable


 **************************************************************/


_DataTable::_DataTable()
{

}

void _DataTable::AddColumn(const _DataColumn& dc)
{
    m_Columns.Add(dc);
}

_DataTable::_DataTable(const _DataTable& r)
{
    std::cout << "	inline _DataTable(const _DataTable& r)" << "\n";

    DatabasePtr = r.DatabasePtr;

    m_Columns = r.m_Columns;     
}


void _DataTable::PrintFieldInfo() const
{
    for (auto& dc : m_Columns)
    {
        _cout << dc.Name << _t("(") << dc.SQLDataType << _t(")\n");
    }
}

/// <summary>
/// 获行第 nRowIndex 行和第 nColumnIndex列的字段数据的引用,行号和列号从1开始。
/// </summary>
/// <param name="nRowIndex">行</param>
/// <param name="nColumnIndex">列</param>
/// <returns></returns>
/// 创建时间:2024-08-12    最后一次修改时间:2024-08-12
const _FieldValue& _DataTable::GetFieldValue(const size_t& nRowIndex, const size_t& nColumnIndex) const
{
    lassert(nRowIndex != 0 && nRowIndex <= RowsCount && nColumnIndex != 0 && nColumnIndex <= ColumnsCount);


    return m_Columns[nColumnIndex - 1].FieldValueList[nRowIndex - 1];

}

const _FieldValue& _DataTable::GetFieldValue(const size_t& nRowIndex, const _string& sFieldName) const
{
    size_t nColumnIndex = 0;
    bool bFind = false;
    for (_DataColumn& dc : m_Columns)
    {
        ++nColumnIndex;
        if (dc.Name == sFieldName) {
            bFind = true;
            break;
        }
    }

    if (!bFind)
    {
        _string sInfo = _t("表中不存在字段 ") + sFieldName + _t("\n");

        lassert(false, sInfo.std_c_str());
    }



    return GetFieldValue(nRowIndex, nColumnIndex);
}


/*********************************************************************************

                                _FieldData


 ********************************************************************************/

_string _FieldValue::ToSplitString(const _string& sSplitString) const
{
    _string sResult;

    const _db* db = GetDB();
    const SQL_TIMESTAMP_STRUCT* tm;
    

    _DataFormat df = db->DataFormat;

    int iType = DataColumnPtr->SQLDataType;
     

    if (df == _DataFormat::dfSQLServer)
    {
        switch (iType)
        {
        case 4:  //Integer = 4
            return ga.intToString(Value.ToAny<int>());
        case 6: //float = 8
            return ga.doubleToStr(Value.ToAny<double>());
        case -8: case -10: //字符串             
            return (wchar_t*)Value.DataConst;
        case 93: //DATETIME                  
            tm = (SQL_TIMESTAMP_STRUCT*)Value.DataConst;
            
            //2024-08-11 02:21:33.273
            sResult.SetBuffer(50);

            sResult.Add(_tostr(tm->year));
            sResult.Add('-');

            if(tm->month < 10)
                sResult.Add(_t("0") + _tostr(tm->month));
            else
                sResult.Add(_tostr(tm->month));

            sResult.Add('-');

            if (tm->day < 10)
                sResult.Add(_t("0") + _tostr(tm->day));
            else
                sResult.Add(_tostr(tm->day));

            sResult.Add(_t(" "));

            if (tm->hour < 10)
                sResult.Add(_t("0") + _tostr(tm->hour));
            else
                sResult.Add(_tostr(tm->hour));


            sResult.Add(':');

            if (tm->minute < 10)
                sResult.Add(_t("0") + _tostr(tm->minute));
            else
                sResult.Add(_tostr(tm->minute));
             
            sResult.Add(':');

            if (tm->second < 10)
                sResult.Add(_t("0") + _tostr(tm->second));
            else
                sResult.Add(_tostr(tm->second));

            sResult.Add(_t("."));

            if(tm->fraction < 10)
                sResult.Add(_t("00") + _tostr(tm->fraction).substr(0,3));
            else if(tm->fraction < 100)
                sResult.Add(_t("0") + _tostr(tm->fraction).substr(0, 3));
            else
                sResult.Add(_tostr(tm->fraction).substr(0, 3));

            return sResult;

            break;
        default:
            _pin(iType);
            lassert(0, "未识别数据,请续写:_FieldValue::ToSplitString");
            break;
        }

    }

    return _string();
}

const _db* _FieldValue::GetDB() const
{
    lassert(DataColumnPtr != null, "_FieldValue::GetDB()");

    lassert(DataColumnPtr->DataTablePtr != null,"_FieldValue::GetDB()");

    lassert(DataColumnPtr->DataTablePtr->DatabasePtr != null, "_FieldValue::GetDB()");

    return DataColumnPtr->DataTablePtr->DatabasePtr;     
}


/*********************************************************************************

                                _FieldData


 ********************************************************************************/

_DataColumn::_DataColumn()
{
    DataTablePtr = NULL;
    SQLDataType = -1;
}

_DataColumn::_DataColumn(const _DataTable* pdt)
{
    DataTablePtr = pdt;
}


_DataColumn::_DataColumn(const _DataColumn& r)
{
    DataTablePtr = r.DataTablePtr;
    Name = r.Name;
    SQLDataType = r.SQLDataType;
    FieldValueList = r.FieldValueList;
}

 



/*********************************************************************************

                                _db


 ********************************************************************************/

int _db::ExecSQLNon(const _string& sSQL) const
{
    return 0;
}


_DataTable _db::ExecSQLQuery(const _string& sSQL)const
{
    return _DataTable();
}




_LF_END_  //-------------------------------------------------------------lf

_odbc.h

/*******************************************************************************************
文件名						: _odbc.h

作者							: 李锋

功能							: 用ODBC连接各种数据库

手机							: 13828778863

Email						: ruizhilf@139.com

创建时间						: 2024年08月11日

最后一次修改时间				:  2024年08月11日


 
在.NET C++项目中引用odbc32.lib库文件,可以按照以下步骤进行操作:

打开你的.NET C++项目。
右键单击项目名称,然后选择“属性”。
在弹出的属性窗口中,展开“配置属性”>“链接器”>“输入”。
在“附加依赖项”字段中,添加odbc32.lib。确保你添加的是完整的库文件名,
包括扩展名.lib。点击“确定”保存更改。
这样,你的项目就会链接到odbc32.lib库文件,使你能够使用ODBC API进
行数据库访问。请确保你已经正确安装了ODBC驱动程序,并且库文件路径设
置正确。
 

(1) 在Windows下用 ODBC 连接 SQL Sserver时 ODBC必须要配置
	https://www.jb51.net/database/324562z2u.htm

(2)
********************************************************************************************/
#pragma once

#include "_db.h"

_LF_BEGIN_
 

class _sql_odbc : public _db
{
private:
	/// <summary>
	/// 数据库环境句柄,属于老大级别的, 类型(SQLHENV)(void *)
	/// </summary>
	void* m_hEnviroment;  

	/// <summary>
	/// 数据库连接句柄,用于表示数据库是否连接上。 数据类型(SQLHDBC)(void *) 
	/// </summary>
	void* m_hDatabaseConnection;

	/// <summary>
	/// 执行语句句柄,最终执行SQL于句的句柄。数据类型(SQLHSTMT)(void *) 
	/// </summary>
	//void* m_hStatement;
 
public:
	_sql_odbc();
	~_sql_odbc();
	 

public:
	void* GetSqlHandle(const _string& ssql) const;


	bool ConnectSQLServer(const _string& DataSource, const _string& UserName,
		const _string& UserPassword);

	inline bool IsConnected()const { return m_hDatabaseConnection != 0; };

	int  GetRecordCount(const _string& sTableName)const;

	_DList<_string> GetFieldNames(const _string& ssql)const;

	_DataTable GetDataTable(const _string& sTableName)const;


	/// <summary>
	/// 执行SQL查询
	/// </summary>
	/// <param name="sSQL"></param>
	/// <returns></returns>
	/// 创建时间:2024-08-12    最后一次修改时间:2024-08-13
	_DataTable ExecSQLQuery(const _string& sSQL) const override;


	/// <summary>
	/// 用执行非SQL查询语句,不返回结果集create update insert delete等。
	/// 注意,只能执行一句语句,例如:
	///		"CREATE TABLE myTable (id INT, name VARCHAR(255))";
	/// 而不能用:
	///		"uses [test] \n CREATE TABLE myTable (id INT, name VARCHAR(255))";
	/// 
	///		这里是两句语句:
	///		(1) uses [test]
	///		(2) CREATE TABLE myTable (id INT, name VARCHAR(255)
	/// </summary>
	/// <param name="sSQL"></param>
	/// <returns>返回受影响的行数量</returns>
	/// 创建时间:2024-08-12    最后一次修改时间:2024-08-13 (已测试)
	int  ExecSQLNon(const _string& sSQL) const override;
	 

};


_LF_END_

_odbc.cpp

/*
在.NET C++项目中引用odbc32.lib库文件,可以按照以下步骤进行操作:

打开你的.NET C++项目。
右键单击项目名称,然后选择“属性”。
在弹出的属性窗口中,展开“配置属性”>“链接器”>“输入”。
在“附加依赖项”字段中,添加odbc32.lib。确保你添加的是完整的库文件名,包括扩展名.lib。
点击“确定”保存更改。
这样,你的项目就会链接到odbc32.lib库文件,使你能够使用ODBC API进行数据库访问。请确保你已
经正确安装了ODBC驱动程序,并且库文件路径设置正确。

*/

#include <windows.h>
#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>

#include "_odbc.h"

//https://tangxing.blog.csdn.net/article/details/116326324

_LF_BEGIN_

class FieldDesc
{
private:
    SQLSMALLINT _NameLength = 0;
    SQLSMALLINT _DataType = 0;
    SQLULEN _ColumnSize = 0;
    SQLSMALLINT _DecimalDigits = 0;
    SQLSMALLINT _Nullable = 0;    
public:
    SQLHSTMT       StatementHandle = 0;
    SQLUSMALLINT   ColumnNumber = 0;
    SQLWCHAR*       ColumnNamePtr;
    SQLSMALLINT    BufferLength = 150;
    SQLSMALLINT* NameLengthPtr = &_NameLength;
    SQLSMALLINT* DataTypePtr = & _NameLength;
    SQLULEN* ColumnSizePtr =  & _ColumnSize;
    SQLSMALLINT* DecimalDigitsPtr = &_DecimalDigits;
    SQLSMALLINT* NullablePtr = & _Nullable;

    FieldDesc()
    {
        ColumnNamePtr = _Memory::New<SQLWCHAR>(BufferLength);
    }
    ~FieldDesc()
    {
        _Memory::Delete<SQLWCHAR>(ColumnNamePtr, BufferLength);
    }
};

/// <summary>
/// ODBC API 参考:
/// https://learn.microsoft.com/zh-cn/sql/odbc/reference/syntax/sqldescribecol-function?view=aps-pdw-2016
/// </summary>
static class odbc_api
{
    /// <summary>
    /// SQLDescribeCol 返回结果集中一列的结果描述符 - 列名、类型、列大小、十进制数字和可为空性。 
    /// 此信息也可在 IRD 的字段中获取
    /// </summary>
    /// <param name="StatementHandle"> [输入] 输入语句句柄</param>
    /// <param name="ColumnNumber">
    ///     [输入]结果数据的列数,按顺序递增列顺序排序,从 1 开始。
    ///     ColumnNumber 参数也可以设置为 0 以描述书签列
    /// </param>
    /// <param name="ColumnName">
    ///     [输出]指向以 null 结尾的缓冲区的指针,该缓冲区将返回列名。
    ///     此值从 IRD 的“SQL_DESC_NAME”字段读取。 如果列未命名或无法确定列名,
    ///     驱动程序将返回一个空字符串。如果 ColumnName 为 NULL, 则 NameLengthPtr 
    ///     仍将返回总字符数 (不包括字符数据的 null 终止字符数,) ColumnName指向的缓冲区中返回
    /// </param>
    /// <param name="BufferLength">[输入]*ColumnName 缓冲区的长度(以字符为单位)。</param>
    /// <param name="NameLengthPtr">
    ///     [输出]指向缓冲区的指针,该缓冲区将返回 (排除 null 终止) 可在 *ColumnName 中返回的字符总数。 
    ///     如果可返回的字符数大于或等于 BufferLength,则*ColumnName 中的列名将被截断为 BufferLength
    ///     减去 null 终止字符的长度。
    /// </param>
    /// <param name="DataTypePtr">
    ///     [输出]指向要在其中返回列的 SQL 数据类型的缓冲区的指针。 此值从 IRD 的“SQL_DESC_CONCISE_TYPE”字
    ///     段读取。 这是 SQL 数据类型中的值之一,或特定于驱动程序的 SQL 数据类型。 如果无法确定数据类型,驱动
    ///     程序将返回SQL_UNKNOWN_TYPE。
    ///     在 ODBC 3 中。x、SQL_TYPE_DATE、SQL_TYPE_TIME或SQL_TYPE_TIMESTAMP分别在 * DataTypePtr 中返回日
    ///     期、时间或时间戳数据; 在 ODBC 2 中。返回 x、SQL_DATE、SQL_TIME 或 SQL_TIMESTAMP。 当 ODBC 2 时,
    ///     驱动程序管理器执行所需的映射。x 应用程序正在使用 ODBC 3。x 驱动程序或当 ODBC 3 时。x 应用程序正在
    ///     使用 ODBC 2。x 驱动程序。
    ///     当书签列) 的 ColumnNumber 等于 0 (时,将在 * DataTypePtr 中为可变长度书签返回SQL_BINARY。 如果 
    ///     ODBC 3 使用书签,则返回(SQL_INTEGER。使用 ODBC 2 的 x 应用程序。x 驱动程序或由 ODBC 2。使用 
    ///     ODBC 3 的 x 应用程序。x driver.)
    ///     有关这些数据类型的详细信息,请参阅附录 D:数据类型中的 SQL 数据类型。 有关特定于驱动程序的 SQL 
    ///     数据类型的信息,请参阅驱动程序的文档。
    /// </param>
    /// <param name="ColumnSizePtr">
    ///     [输出]指向缓冲区的指针,其中返回数据源上列) 以字符为单位的大小 (。 如果无法确定列大小,
    ///     驱动程序将返回 0。 有关列大小的详细信息,请参阅附录 D:数据类型中的 列大小、十进制数
    ///     字、传输八进制长度和显示大小 。
    /// </param>
    /// <param name="DecimalDigitsPtr">
    ///     [输出]指向缓冲区的指针,该缓冲区将返回数据源上列的十进制位数。 如果无法确定或不适用小数位数,
    ///     驱动程序将返回 0。 有关十进制数字的详细信息,请参阅附录 D:数据类型中的 列大小、十进制数字、
    ///     传输八进制长度和显示大小 。
    /// </param>
    /// <param name="NullablePtr">
    ///     [输出]指向缓冲区的指针,该缓冲区将返回一个值,该值指示列是否允许 NULL 值。 此值从 IRD 的
    ///     “SQL_DESC_NULLABLE”字段中读取。 值为以下值之一:
    ///     SQL_NO_NULLS:列不允许 NULL 值。
    ///     SQL_NULLABLE:列允许 NULL 值。
    ///     SQL_NULLABLE_UNKNOWN:驱动程序无法确定列是否允许 NULL 值。
    /// </param>
    /// <returns>SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。</returns>
    SQLRETURN _SQLDescribeCol(
        SQLHSTMT       StatementHandle,
        SQLUSMALLINT   ColumnNumber,
        SQLCHAR* ColumnName,
        SQLSMALLINT    BufferLength,
        SQLSMALLINT* NameLengthPtr,
        SQLSMALLINT* DataTypePtr,
        SQLULEN* ColumnSizePtr,
        SQLSMALLINT* DecimalDigitsPtr,
        SQLSMALLINT* NullablePtr)
    {
        return _SQLDescribeCol(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLengthPtr,
            DataTypePtr, ColumnSizePtr, DecimalDigitsPtr, NullablePtr);
    }



} api;







_sql_odbc::_sql_odbc() : _db(_DataFormat::dfSQLServer)
{
    
    
    //m_hStatement = NULL;

    m_hDatabaseConnection = NULL;

    m_hEnviroment = NULL;

}



_sql_odbc::~_sql_odbc()
{
   
    //_cout << _t("_sql_odbc::~_sql_odbc()\n");


    // 释放句柄,断开连接
    //if(m_hStatement != NULL)
    //    SQLFreeHandle(SQL_HANDLE_STMT, m_hStatement);

    if (m_hDatabaseConnection != NULL)
        SQLFreeHandle(SQL_HANDLE_DBC, m_hDatabaseConnection);

    if (m_hEnviroment != NULL)
        SQLFreeHandle(SQL_HANDLE_ENV, m_hEnviroment);
}


/// <summary>
/// 获取SQL语句执行名柄。
/// </summary>
/// <param name="ssql"></param>
/// <returns></returns>
void* _sql_odbc::GetSqlHandle(const _string& ssql) const
{
    SQLHANDLE hStatement = NULL;

    // 申请SQL语句句柄 
    SQLRETURN sqlReturn = SQLAllocHandle(SQL_HANDLE_STMT, m_hDatabaseConnection, &hStatement);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _pcn(ssql);  //打印SQL语句

        _cout << _t("申请SQL语句句柄失败!。\n");
        return 0;
    }



    /* 执行SQL语句 */
    sqlReturn = SQLExecDirect(hStatement, ssql.GetData(), SQL_NTS);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("---------------------------------------------------------------\n");
        _cout << _t("void* _sql_odbc::GetSqlHandle(const _string& ssql) const") << _t("\n");
        _cout << _t("---------------------------------------------------------------\n");
     

        _cout << _t("执行SQL语句失败,下面是SQL语名内容:") << "\n";

        _cout << _t("---------------------------------------------------------------\n\n");
        _cout <<  ssql << _t("\n\n");

        _cout << _t("---------------------------------------------------------------\n");

        return 0;
    }

    return hStatement;
}





/// <summary>
/// 用ODBC连接SQL Server 数据库
/// </summary>
/// <param name="DataSource">ODBC数据源,注意,不是数据库名称,是你在ODBC中创建的连接名称。</param>
/// <param name="UserName">用户名</param>
/// <param name="Password">密码</param>
/// <returns></returns>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
/// 参考文章:https://www.cnblogs.com/xihong2014/p/15303646.html
bool _sql_odbc::ConnectSQLServer(const _string& DataSource, const _string& UserName, const _string& UserPassword)
{
    //参考文章:https://www.cnblogs.com/xihong2014/p/15303646.html

    // 使用ODBC API建立数据库连接分为3部分:
    // 申请环境句柄,
    // 使用环境句柄申请连接句柄,
    // 使用连接句柄连接数据库。

 
    //保存数据源,用户名和密码,以备下次使用。
    _df = _DataFormat::dfSQLServer;
    
    _DataSource = DataSource;
    _UserName = UserName;
    _UserPassword = UserPassword;


    /* 申请环境变量 */
    // 申请各种句柄都靠这个函数,
    // 参数1是要申请句柄的类型,
    // 参数2为申请该句柄依靠的句柄(老大没依靠,所以是NULL),申请结果在参数3中保存
    SQLRETURN sqlReturn = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &m_hEnviroment);


    // 返回值代表着执行的意义,如下面判断,SUCCESS_WITH_INFO相当于是警告,虽然成功了,但是可能有问题
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "申请环境变量失败。" << "\n";
        return false;
    }


    // 设置ODBC环境属性
    SQLSetEnvAttr(m_hEnviroment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);

    /* 申请连接句柄 */
    sqlReturn = SQLAllocHandle(SQL_HANDLE_DBC, m_hEnviroment, &m_hDatabaseConnection);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "申请连接句柄失败。" << "\n";
        return false;
    }

   
    //准备连接工作,连接数据源
    sqlReturn = SQLConnect(m_hDatabaseConnection
        , _DataSource.GetData(), SQL_NTS
        , _UserName.GetData(), SQL_NTS
        , _UserPassword.GetData(), SQL_NTS);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("连接数据源失败。") << _t("\n");
        return false;
    }

    return true;
 
    /*
    SQLHANDLE m_hStatement;
 

    // 申请SQL语句句柄  
    sqlReturn = SQLAllocHandle(SQL_HANDLE_STMT, m_hDatabaseConnection, &m_hStatement);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "失败4" << "\n";
        return 0;
    }

    // 构造SQL语句  
    _string cstrSql = _t("SELECT * FROM crm_table where fd_id = 2");

    // 执行SQL语句  
    sqlReturn = SQLExecDirect(m_hStatement, (SQLWCHAR*)cstrSql.std_c_str(), SQL_NTS);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "失败5" << "\n";
        return 0;
    }



    // 获得返回结果的行数  
    SQLLEN sqlnIdCount = 0;
    sqlReturn = SQLRowCount(m_hStatement, (SQLLEN*)&sqlnIdCount);


    // 开始读取结果  
    // 读取第一行时要调用,以后依次调用就可以下移行数,直到不返回SQL_SUCCESS
    sqlReturn = SQLFetch(m_hStatement);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "失败6" << "\n";
        return 0;
    }


    SQLINTEGER sqlnID;
    SQLLEN sqlnIDLength = 0;

    // 获得数据  
    SQLGetData(m_hStatement, 1, SQL_C_ULONG, &sqlnID, 0, (SQLLEN*)&sqlnIDLength);
    // 参数1为执行语句的句柄,
    // 参数2为所要得到的数据位于的列数(SQL语句中),
    // 参数3为数据类型,这个比较多,需要看一下MSDN
    // 参数4为保存的位置(地址),
    // 参数5为参数4可用的位置,既然参数3已设定为长整型,所以这里可使用0
    // 参数6为实际返回的长度

    _pin(sqlnIDLength);
    _pin(sqlnID);

    */
    
}

/// <summary>
/// 获取表中的记录数。
/// 
/// 注意:用ODBC连接SQL Server数据库时,好像每一次执行查询,
///       都要释放查询句柄,否则就不能进行下一次查询?
/// </summary>
/// <param name="sTableName"></param>
/// <returns></returns>
/// 创建时间:2024-08-11    最后一次修改时间:2024-08-11
int _sql_odbc::GetRecordCount(const _string& sTableName) const
{
    _string sql(_t(""), 500);
    sql.Add(_t("select count(fd_id) as fd_count from "));
    sql.Add(sTableName);
     
    SQLHANDLE hStatement = NULL;
 
    // 申请SQL语句句柄 
    int sqlReturn = SQLAllocHandle(SQL_HANDLE_STMT, m_hDatabaseConnection, &hStatement);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _pcn(sql);  //打印SQL语句

        _cout << _t("申请SQL语句句柄失败!。\n");
        return 0;
    }



    /* 执行SQL语句 */
    sqlReturn = SQLExecDirect(hStatement, sql.GetData(), SQL_NTS);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _pcn(sql);  //打印SQL语句

        _cout << _t("执行SQL语句失败!。\n");

        return 0;
    }



    //受SQL语句影响的行数
    SQLLEN  nAffectedRows = 0;

     
    //调用SQLRowCount函数,它将返回一个整数值,表示受SQL语句影响的行数
    sqlReturn = SQLRowCount(hStatement, (SQLLEN*)&nAffectedRows);

    if(sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("SQLRowCount函数执行失败!\n");
        return -1;
    }


    if (nAffectedRows > 0)
    {
        _cout << _t("受SQL语句影响的行数不对!\n");
        return -1;
    }


    //https://blog.csdn.net/L946494/article/details/119825671
      
    // 开始读取结果  
    // 读取第一行时要调用,以后依次调用就可以下移行数,直到不返回SQL_SUCCESS
    sqlReturn = SQLFetch(hStatement);
    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        std::cout << "开始读取结果失败!" << "\n";
        return -1;
    }


    SQLINTEGER fd_count = 0;
    SQLLEN sqlnIDLength = 0;

    // 获得数据  
    // 参数1为执行语句的句柄,
    // 参数2为所要得到的数据位于的列数(SQL语句中),
    // 参数3为数据类型,这个比较多,需要看一下MSDN
    // 参数4为保存的位置(地址),
    // 参数5为参数4可用的位置,既然参数3已设定为长整型,所以这里可使用0
    // 参数6为实际返回的长度
    sqlReturn = SQLGetData(hStatement, 1, SQL_C_ULONG, &fd_count, 0, (SQLLEN*)&sqlnIDLength);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("执行函数SQLGetData失败!\n");
        return -1;
    }
     

    
    if (hStatement != NULL)
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hStatement);
    }

    return fd_count;
}


_DList<_string> _sql_odbc::GetFieldNames(const _string& ssql) const
{

    _DList<_string> sResult;

    FieldDesc fd;
    fd.StatementHandle = GetSqlHandle(ssql);


    SQLSMALLINT numColumns = 0;

    auto sqlReturn = SQLNumResultCols(fd.StatementHandle, &numColumns);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("调用ODBC API SQLNumResultCols出错 !\t");
    }

    for (int n = 1; n <= numColumns; ++n) {

        sqlReturn = SQLDescribeCol(fd.StatementHandle, n, fd.ColumnNamePtr, fd.BufferLength, fd.NameLengthPtr,
            fd.DataTypePtr, NULL, NULL, NULL);

        if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
        {
            _cout << _t("调用ODBC API SQLDescribeCol出错 !\t");
        }

        _pin(*fd.DataTypePtr);

        sResult.Add(_string(fd.ColumnNamePtr, *fd.NameLengthPtr));
    }



    return sResult;
}

_DataTable  _sql_odbc::GetDataTable(const _string& sTableName) const
{     
    return ExecSQLQuery( _t("select * from ") + sTableName);
}



/// <summary>
/// 
/// </summary>
/// <param name="sSQL"></param>
/// <returns></returns>
/// 创建时间:2024-08-12    最后一次修改时间:2024-08-13
_DataTable _sql_odbc::ExecSQLQuery(const _string& sSQL) const
{ 
    _DataTable dtResult;
    dtResult.DatabasePtr = this;

    //---------------------------------------------------------------------------获取字符信息
    FieldDesc fd;

    fd.StatementHandle = GetSqlHandle(sSQL);


    if (fd.StatementHandle == NULL){

        _cout << _t("-------------------------------------------------------------\n");
        _cout << _t("_DataTable _sql_odbc::ExecSQLQuery(const _string& sSQL) const") << _t("\n");
        _cout << _t("-------------------------------------------------------------\n");
        _cout << _t("获取SQL语句执行名柄失败!\n");

        return dtResult;
    }


    SQLSMALLINT nFieldsCount = 0; //字段数量

    auto sqlReturn = SQLNumResultCols(fd.StatementHandle, &nFieldsCount);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO){

        _cout << _t("调用ODBC API SQLNumResultCols出错 !\t");
    }

    for (int n = 1; n <= nFieldsCount; ++n) {

        sqlReturn = SQLDescribeCol(fd.StatementHandle, n, fd.ColumnNamePtr, fd.BufferLength, fd.NameLengthPtr,
            fd.DataTypePtr, NULL, NULL, NULL);

        if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
        {
            _cout << _t("调用ODBC API SQLDescribeCol出错 !\t");
        }

        

        _DataColumn dc(&dtResult);
       

        dc.Name = _string(fd.ColumnNamePtr, fd.BufferLength);
        dc.SQLDataType = *fd.DataTypePtr;     
        dtResult.AddColumn(dc);
    }

    //---------------------------------------------------------------------------记录数据
    //受SQL语句影响的行数
    SQLLEN  nAffectedRows = 0;


    //调用SQLRowCount函数,它将返回一个整数值,表示受SQL语句影响的行数
    sqlReturn = SQLRowCount(fd.StatementHandle, (SQLLEN*)&nAffectedRows);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("SQLRowCount函数执行失败!\n");
    }

    int nRow = 0;



    //在这里诹取每个字段的值
    _ByteArray tmpBuffer(1000);

    while (true) { //当SQLFetch返回不是  SQL_SUCCESS  和 SQL_SUCCESS_WITH_INFO时停止
    
        //https://blog.csdn.net/L946494/article/details/119825671

        //++nRow;   //记数

        // 开始读取结果  
        // 读取第一行时要调用,以后依次调用就可以下移行数,直到不返回SQL_SUCCESS
        sqlReturn = SQLFetch(fd.StatementHandle);
        if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO){

            break;
        }


        for (size_t n = 1; n <= nFieldsCount; ++n) { //n为列数
      
            _DataColumn& dc = dtResult.Columns(n - 1); //千万不能用 _DataColumn dc = dt.Columns(n - 1);

            SQLLEN sqlnIDLength = 0;

            // SQL_C_DEFAULT:指定结果的数据类型,根据数据表中的定义来决定,其他C类型名称见文末;
            // SQL_C_DEFAULT 是根据数据源类型来决定变量类型

            // 获得数据  
            // 参数1为执行语句的句柄,
            // 参数2为所要得到的数据位于的列数(SQL语句中),
            // 参数3为数据类型,这个比较多,需要看一下MSDN
            // 参数4为保存的位置(地址),
            // 参数5为参数4可用的位置,既然参数3已设定为长整型,所以这里可使用0
            // 参数6为实际返回的长度

            if (dc.SQLDataType == 93) //datatime 8
            {
               //SQL_C_BINARY 如果不用SQL_C_TYPE_TIMESTAMP,SQL Server中简单地把数据存到内在中,
               //例:2024-08-11 02:21:33.000 的数据内存,如果用了SQL_C_TYPE_TIMESTAMP,它会
               //把2024-08-11 02:21:33.000 的数据内存转为SQL_C_TYPE_TIMESTAMP的结构内存
               sqlReturn = SQLGetData(fd.StatementHandle, n, SQL_C_TYPE_TIMESTAMP, tmpBuffer.Data, 1000,
                   null);
               sqlnIDLength = sizeof(SQL_TIMESTAMP_STRUCT);  //16

            }else{

                sqlReturn = SQLGetData(fd.StatementHandle, n, SQL_C_BINARY, tmpBuffer.Data, 1000,
                    (SQLLEN*)&sqlnIDLength);
            }
         
            dc.FieldValueList.Add(_FieldValue(&dc,_ByteArray())); //添加一个新数据

            _ByteArray* pba = &dc.FieldValueList.Last()->Data.Value;

            if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO){

                _pin(sqlnIDLength);
                _cout << _t("错误:") << dc.SQLDataType << _t("\n");

            }else{

                //dc.SQLDataType == -10  wchar_t数据
             
                pba->SetBuffer(sqlnIDLength + 2);
                pba->Add(tmpBuffer.Data, sqlnIDLength);                
                pba->ZeroBufferAll();                   

            }
        }
    }


    if (fd.StatementHandle != NULL){

        SQLFreeHandle(SQL_HANDLE_STMT, fd.StatementHandle);
    }

    return dtResult;
}

int _sql_odbc::ExecSQLNon(const _string& sSQL) const
{
     

    int iResult = 0;
     
    //---------------------------------------------------------------------------获取字符信息
    FieldDesc fd;

    fd.StatementHandle = GetSqlHandle(sSQL);


    if (fd.StatementHandle == NULL) {

        _cout << _t("-------------------------------------------------------------\n");
        _cout << _t("_DataTable _sql_odbc::ExecSQLQuery(const _string& sSQL) const") << _t("\n");
        _cout << _t("-------------------------------------------------------------\n");
        _cout << _t("获取SQL语句执行名柄失败!\n");

        return 0;
    }
        
    //受SQL语句影响的行数
    SQLLEN  nAffectedRows = 0;


    //调用SQLRowCount函数,它将返回一个整数值,表示受SQL语句影响的行数
    auto sqlReturn = SQLRowCount(fd.StatementHandle, (SQLLEN*)&nAffectedRows);

    if (sqlReturn != SQL_SUCCESS && sqlReturn != SQL_SUCCESS_WITH_INFO)
    {
        _cout << _t("SQLRowCount函数执行失败!\n");
    }

      

    if (fd.StatementHandle != NULL) {

        SQLFreeHandle(SQL_HANDLE_STMT, fd.StatementHandle);
    }

    return nAffectedRows;
}

  


_LF_END_//------------------------------------------------------lf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2141461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ai扩图用什么软件?探索五大高效工具

Hey朋友们&#xff0c;最近在社交媒体上看到不少超清晰的美图&#xff0c;是不是特别羡慕&#xff1f; 别急&#xff0c;告诉你个秘密武器——ai扩图软件。这些神器能帮你智能扩展图片内容&#xff0c;让每张图都充满细节。 想知道都有哪些好用的ai扩图软件免费吗&#xff1f…

CentOS上使用rpm离线安装Mosquitto(Linux上Mqtt协议调试工具)附资源下载

场景 Windows上Mqtt服务器搭建与使用客户端工具MqttBox进行测试&#xff1a; Windows上Mqtt服务器搭建与使用客户端工具MqttBox进行测试_微软消息队列 测试工具-CSDN博客 Windows服务器上Mqtt服务器EMQX的安装使用&#xff1a; Windows服务器上Mqtt服务器EMQX的安装使用_wi…

Objects as Points基于中心点的目标检测方法CenterNet—CVPR2019

Anchor Free目标检测算法—CenterNet Objects as Points论文解析 Anchor Free和Anchor Base方法的区别在于是否在检测的过程中生成大量的先验框。CenterNet直接预测物体的中心点的位置坐标。 CenterNet本质上类似于一种关键点的识别。识别的是物体的中心点位置。 有了中心点之…

Python青少年简明教程:tkinter库入门

Python青少年简明教程&#xff1a;tkinter库入门 tkinter是Python的标准GUI&#xff08;图形用户界面&#xff09;库。它提供了一种快速而简单的方法来创建GUI应用程序。tkinter是Python自带的&#xff0c;无需额外安装&#xff0c;随 Python 安装包一起提供。 在Python 3.x中…

Leetcode—1137. 第 N 个泰波那契数【简单】

2024每日刷题&#xff08;160&#xff09; Leetcode—1137. 第 N 个泰波那契数 记忆化搜索实现代码 class Solution { public:int tribonacci(int n) {int zero 0;int one 1;int two 1;if(n 0) {return zero;}if(n 1) {return one;}if(n 2) {return two;}int ans 0;fo…

三重因素,巨人瘦身——从 IBM中国研发部裁员讲起

如何看待IBM中国研发部裁员&#xff1f;近日&#xff0c;IBM中国宣布撤出在华两大研发中心&#xff0c;引发了IT行业对于跨国公司在华研发战略的广泛讨论。这一决定不仅影响了众多IT从业者的职业发展&#xff0c;也让人思考全球化背景下中国IT产业的竞争力和未来发展方向。面对…

手机、平板电脑编程———未来之窗行业应用跨平台架构

一、平板编程优点 1. 便携性强 - 可以随时随地携带平板进行编程&#xff0c;不受地点限制&#xff0c;方便在旅行、出差或休息时间进行学习和开发。 2. 直观的触摸操作 - 利用触摸屏幕进行代码编辑、缩放、拖动等操作&#xff0c;提供了一种直观和自然的交互方式。 …

TypeScript:高级类型

一、交叉类型&#xff08;Intersection Types&#xff09; 交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型&#xff0c;它包含了所需的所有类型的特性。 例如&#xff0c; Person & Serializable & Loggable同时是 Person …

建模杂谈系列256 规则函数化改造

说明 之前尝试用FastAPI来构造规则&#xff0c;碰到的问题是由于请求量过大(TPS > 1000), 从而导致微服务端口资源耗尽。所以现在的point是: 1 如何使用函数来替代微服务(同时要保留使用微服务的优点)2 进一步抽象并规范规则的执行3 等效合并规则的方法 内容 0 机制讨论…

Vue2源码解读

vue源码_哔哩哔哩_bilibili 1.Vue源码路径目录解读 Vue2源码的路径目录被设计得非常清晰&#xff0c;每个文件夹都承担着特定的职责和功能。以下是这些主要文件夹&#xff08;compiler、core、platform、server、sfc、shared&#xff09;的详细解读&#xff1a; 1. compiler …

LLM大模型部署实战指南:Ollama简化流程,OpenLLM灵活部署,LocalAI本地优化,Dify赋能应用开发

1. Ollama 部署的本地模型(&#x1f53a;) Ollama 是一个开源框架&#xff0c;专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计。&#xff0c;这是 Ollama 的官网地址&#xff1a;https://ollama.com/ 以下是其主要特点和功能概述&#xff1a; …

VLMEvalKit 评测实践:InternVL2 VS Qwen2VL

一、InternVL2简介 InternVL2是由上海人工智能实验室OpenGVLab发布的一款多模态大模型&#xff0c;其中文名称为“书生万象”。该模型在多学科问答&#xff08;MMMU&#xff09;任务上表现出色&#xff0c;成为国内首个在该任务上性能突破60的模型&#xff0c;被誉为开源多模态…

k8s 微服务 ingress-nginx 金丝雀发布

目录 一 什么是微服务 二 微服务的类型 三 ipvs模式 3.1 ipvs模式配置方式 四 微服务类型详解 4.1 clusterip 4.2 ClusterIP中的特殊模式headless 4.3 nodeport 4.4 loadbalancer 4.5 metalLB 4.6 externalname 五 Ingress-nginx 5.1 ingress-nginx功能 5.2 部署…

5. Python之数据类型

Python数据类型有数值型&#xff0c;字符串型&#xff0c;布尔型等等 内置函数type()&#xff0c;可以查看变量的数据类型 。 一、数值类型 整数&#xff08;没有小数部分&#xff0c;包含正整数&#xff0c;负整数&#xff0c;0&#xff0c;默认为十进制数&#xff09;&…

C++ 类域+类的对象大小

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 概念概述 类定义了一个新的作用域&#xff0c;类的所有成员都在类的作用域中&#xff…

华为杯数学建模资料大全、入门指导攻略、获奖数据分析、选题建议

这里收集的资料个人认为已经非常全也非常值了&#xff0c;这么多资料收集成本真的不低 数学建模比赛资料部分&#xff08;需要私聊找我&#xff09; 华为杯创办以来每一年的比赛题目原题&#xff08;包括A到F题&#xff09;华为杯每年每种题目的优秀获奖作品论文 近几年的华…

2022高教社杯全国大学生数学建模竞赛C题 问题一(2) Python代码演示

目录 1.2 结合玻璃的类型,分析文物样品表面有无风化化学成分含量的统计规律数据预处理绘图热力图相关系数图百分比条形图箱线图小提琴图直方图KED图描述性统计分析偏度系数峰度系数其它统计量1.2 结合玻璃的类型,分析文物样品表面有无风化化学成分含量的统计规律 数据预处理 …

回归预测|基于鲸鱼优化随机森林数据的数据回归预测Matlab程序 多特征输入单输出WOA-RF

回归预测|基于鲸鱼优化随机森林数据的数据回归预测Matlab程序 多特征输入单输出WOA-RF 文章目录 一、基本原理鲸鱼优化算法&#xff08;WOA&#xff09;随机森林&#xff08;RF&#xff09;WOA-RF的结合总结 二、实验结果三、核心代码四、代码获取五、总结 一、基本原理 WOA-R…

服务器断电重启后报XFS文件系统错误 XFS (dm-0)_ Metadata I_O error

一、现象 服务器被意外断电&#xff0c;导致重启机器后报错&#xff0c;系统错误 XFS (dm-0): Metadata I/O error 二、解决方法 2.1 重启服务器&#xff0c;进入单用户模式 服务器系统为&#xff1a; centos7.9 开机按e 定位到ro 然后修改ro为rw(“rw init/sysroot/bin/sh”…

2024-1.2.12-Android-Studio配置

本地博客: https://k1t0111.github.io/ K1T0 最近在做一些app方向的移动技术开发学习&#xff0c;但是由于AS的配置问题&#xff0c;市面上找不到最新的2024版本的AS的相关配置。笔者也是踩了很多坑&#xff0c;因此想写一篇文章记录一下最新的AS 2024 1.2.12的对应java环境的一…