在做连接Oracle数据库之前需要Oracle数据库dll包:
最好是放在Plugins文件夹下,
如果你没有,我这里有链接https://download.csdn.net/download/qq_40120946/11256313
亲测有效,一定要注意版本问题,不然发布不出来。
其次,要在Unity playersetting中把版本改为.net4.6
到这里基础配置已经完成。
在连接Oracle数据库,我们需要知道它的操作步骤。
这个问题,这个步骤不管是进行通信,连接其他数据,或者其他程序,大致都按照这个内容来的。
第一步,初始化配置
第二步,打开连接
第三步,对获取(或者其他。。想不到怎么措辞了0.0)数据进行操作
第四步,关闭连接
具体实现如下:
public class LinkOracle:MonoBehaviour
{
public static LinkOracle Instance;
#region 连接配置数据
[SerializeField] string IP = "192.168.0.106";
[SerializeField] string port = "355";
[SerializeField] string oracleName = "orcl";
[SerializeField] string user = "sh119";
[SerializeField] string password = "1234";
#endregion
private OracleConnection con;//数据库
private void Awake()
{
Instance = this;
}
public void Start()
{
try
{
string connString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + IP + ")(PORT=" + port + "))(CONNECT_DATA=(SERVICE_NAME=" + oracleName + ")));Persist Security Info=True;User ID=" + user + ";Password=" + password;
//string connString = "User ID="+user+";Password="+password+";DBA Privilege=SYSDBA;Data Source=(DESCRIPTION = (ADDRESS_LIST= (ADDRESS = (PROTOCOL = TCP)(HOST = "+IP+")(PORT ="+port+"))) (CONNECT_DATA =(SERVICE_NAME = "+oracleName+")))";
con = new OracleConnection(connString);//第一步
if (con.State == ConnectionState.Closed) con.Open();//第二步
Debug.Log("连接成功!!");
}
catch (Exception ex)
{
Debug.Log("连接失败!!"+":"+ex.ToString());
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()//第四步
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
Debug.Log("关闭数据库!!");
}
/* 以下第三步 */
/// <summary>
/// 获取数据
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public OracleDataReader ExecuteSql(string sql)
{
OracleCommand cmd = new OracleCommand(sql, con);
OracleDataReader dr = null;
try
{
dr = cmd.ExecuteReader();
}
catch (OracleException e)
{
Debug.Log(e);
}
return dr;
}
/*--拿取指定数据 --*/
/// <summary>
/// 获取对应表数据
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public List<PO_VEMPOWER> Find_POData()
{
string sql = "select * from po_vempower";
List<PO_VEMPOWER> po = new List<PO_VEMPOWER>();
OracleCommand cmd = new OracleCommand(sql, con);
OracleDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
while (reader.Read())//Read()读取存在的数据,没有数据他不会读取
{
var dic = Find_PO_VEMPOWER(reader);
if (dic != null)
{
po.Add(dic);
}
}
reader.Close();
cmd.Dispose();
}
catch (OracleException e)
{
Close();
Debug.Log(e);
}
return po;
}
/// <summary>
/// 读取对应类字段数据
/// </summary>
/// <param name="reader"></param>
/// <returns></returns>
private PO_VEMPOWER Find_PO_VEMPOWER(OracleDataReader reader)
{
PO_VEMPOWER po = new PO_VEMPOWER()
{
ID = reader.IsDBNull(reader.GetOrdinal("ID")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
CODE = reader.IsDBNull(reader.GetOrdinal("CODE")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
NAME = reader.IsDBNull(reader.GetOrdinal("NAME")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
TYPE = reader.IsDBNull(reader.GetOrdinal("TYPE")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
STATE = reader.IsDBNull(reader.GetOrdinal("STATE")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
NUM = reader.IsDBNull(reader.GetOrdinal("NUM")) ? 0 : reader.GetFloat(reader.GetOrdinal("NUM")),
ZBLXDM = reader.IsDBNull(reader.GetOrdinal("ZBLXDM")) ? "" : reader.GetString(reader.GetOrdinal("STATE")),
};
return po;
}
}
/// <summary>
/// 数据库中车辆、人员、设备
/// </summary>
public class PO_VEMPOWER
{
public string ID { get; set; }
public string CODE { get; set; }
public string NAME { get; set; }
public string TYPE { get; set; }
public string STATE { get; set; }
public float NUM { get; set; }
public string ZBLXDM { get; set; }
}
说明:由于项目中只需要获取PO_VEMPOWER这个类,所以我就没有写通用的方式(以后会补充),
在执行字段读取时一定要知道目标类型与当前类型是否一致,如下:
对不上的话程序会抛异常。
在连接Oracle数据库遇到的问题:
1、连接串
连接串,一定要对,我在这里提供了两种方式,亲测都可以连上
在第二种方式中,DBA Privilege=SYSDBA;这个东西一定要问清楚,没有要求就把他删掉,(深坑....)
2,如果数据库没有打开,运行Unity程序很长的延时问题(Oracle默认30秒,太长了...)
一程序来说我们需要,我们只需要在连接串的结尾加上
Connection Timeout=3;
即可,3代表延迟3秒响应时间,这个可以自己设定。
string connString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + IP + ")(PORT=" + port + "))(CONNECT_DATA=(SERVICE_NAME=" + oracleName + ")));Persist Security Info=True;User ID=" + user + ";Password=" + password+"Connection Timeout=3;";
但对于unity还有5秒左右的延迟时间,
对于这个问题我的解决方式是Ping一下服务器,如下
/// <summary>
/// 是否能 Ping 通指定的主机
/// </summary>
/// <param name="ip">ip 地址或主机名或域名</param>
/// <returns>true 通,false 不通</returns>
private bool Ping(string ip)
{
bool w_blnReturn = false;
try
{
System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
options.DontFragment = true;
string data = "Test Data!";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 800; // Timeout 时间,单位:毫秒
System.Net.NetworkInformation.PingReply reply = p.Send(ip, timeout, buffer, options);
if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
w_blnReturn = true;
else
w_blnReturn = false;
}
catch (Exception ex)
{
//异常日志
Debug.Log(ex.Message);
w_blnReturn = false;
}
return w_blnReturn;
}
这两个方式一结合,程序启动时间瞬间提上不少。
到这,连接Oracle服务器基本完成了。