随机算法解决生产调度问题 C# Oracle
2020-06-06 07:42
615 查看
解决这样一个问题,设想机器有500台(注塑机),工单有3000张,每张工单只能分配到特定范围的机器(按照注塑机吨位分配),并且每张工单可以用日产能算出需要多少天,如何一次分配,既使每张工单都能分到机器,又让每台机器都分到工单,并且尽量保证注塑机效率最高(效率最高的意思是开机率最高)。
另外,注塑机出产品可以一个模具出不同的产品,所以很多时候需要考虑给一张工单搭配一个生产数量差不多的联产品,以保证效率。
using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace GAInJobShop { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { MachineQuery(); } private void MachineQuery() { string sql; sql = @"SELECT eci01 machine,machine_ton,machine_down FROM injection_plan_machine ORDER BY eci01"; DataTable dt= OracleHelper.ExecuteDataTable(sql); dt.Columns.Add("Select",typeof(bool)); dt.Columns["Select"].SetOrdinal(0); dataGridView1.DataSource = dt; //dt.Columns["Select"].DefaultValue = false; for (int i = 0; i < dataGridView1.RowCount; i++) { dataGridView1.Rows[i].Cells["Select"].Value = false; if (dataGridView1.Rows[i].Cells["machine_down"].Value.ToString() == "Y") { dataGridView1.Rows[i].Cells["Select"].Value = true; } } } private void GA() { string sql; //更新需要排的工單 sql = "TRUNCATE TABLE injection_plan"; OracleHelper.ExecuteNonQuery(sql); sql = @"insert into injection_plan SELECT CAST(0 AS INT) Ver ,SFB01 job_num, SFB102 machine, SFB13 start_date, SFB15 end_date, SFB05 partnum, SFB08 prod_qty, SFB09 complete_qty, sfb08-sfb09 uncomplete_qty, A1 daily_plan_qty, CEIL((sfb08-sfb09)/A1) need_qty, get_forward_date(CEIL((sfb08-sfb09)/A1)) estimate_complete_date, TA_IMA001 suggestion_workshop, TC_MMJ09 ton, gong_mu, tc_mmi01 mold FROM SFB_FILE LEFT JOIN IMA_FILE ON IMA01 = SFB05 LEFT JOIN OEB_FILE ON OEB01 = SFB22 AND OEB03 = SFB221 LEFT JOIN mu_ju_zui_da_chan_neng2 ON sfb05=tc_mmj03 WHERE SFB04 <> '8' AND SFB01 LIKE '%511-%' AND SFB02 NOT IN ('7', '8') AND SFB08 <> SFB09 AND sfb13>get_forward_date(-45) AND A1 IS NOT NULL ORDER BY sfb102,sfb13"; OracleHelper.ExecuteNonQuery(sql); //MessageBox.Show("已經更新工單!!!!"); //產生第二代,為了把沒有機台的隨機排到機台 sql = @"insert into injection_plan SELECT 1 Ver, job_num, machine, start_date, end_date, partnum, prod_qty, complete_qty, uncomplete_qty, daily_plan_qty, need_days, estimate_complete_date, suggestion_workshop, ton, gong_mu, mold FROM injection_plan where Ver=0 and need_days>" + NeedDays.Text + " "; OracleHelper.ExecuteNonQuery(sql); //MessageBox.Show("產生第二代!!!!"); //sql = @"SELECT job_num,ton,gong_mu,mold FROM injection_plan WHERE ver=1 ORDER BY machine"; //DataTable NotScheduleJobNumDt = OracleHelper.ExecuteDataTable(sql); DataTable NotScheduleJobNumDt = new DataTable(); DataTable NotScheduleMachineDt = new DataTable(); Random rd = new Random(int.Parse(DateTime.Now.ToString("ss")) + 20); Random rd2 = new Random(int.Parse(DateTime.Now.ToString("ss"))); Random rd3 = new Random(int.Parse(DateTime.Now.ToString("ss")) + 30); Random rd4 = new Random(int.Parse(DateTime.Now.ToString("ss")) + 40); int randkey, randkey2, randkey3, randkey4; OracleConnection conn = new OracleConnection(OracleHelper.connStr); conn.Open(); OracleCommand cmd = conn.CreateCommand(); OracleDataAdapter adapter = new OracleDataAdapter(cmd); //MessageBox.Show("二代已隨機更新生產線!!!!"); //產生第二代,為了把沒有機台的隨機排到機台 sql = @"insert into injection_plan SELECT 2 Ver, job_num, machine, start_date, end_date, partnum, prod_qty, complete_qty, uncomplete_qty, daily_plan_qty, need_days, estimate_complete_date, suggestion_workshop, ton, gong_mu, mold FROM injection_plan where Ver=1 "; cmd.CommandText = sql; cmd.ExecuteNonQuery(); //MessageBox.Show("三代已隨機更新生產線!!!!"); //開始變異 /* sql = @"SELECT ECI01 FROM eci_file WHERE eci03 IN ('INJA','INJB','INJC','INJD','INJE') AND eci01 LIKE '%J%' AND eciacti='Y' AND eci01<>'JL01' AND eci03 IN ('INJA','INJB') AND LENGTH(ECI01)=5 UNION ALL SELECT ECI01 FROM eci_file WHERE eci03 IN ('INJA','INJB','INJC','INJD','INJE') AND eci01 LIKE '%J%' AND eciacti='Y' AND eci01<>'JL01' AND eci03 NOT IN ('INJA','INJB') AND LENGTH(ECI01)=4 order by eci01"; cmd.CommandText = sql; DataTable datatable4 = new DataTable(); adapter.Fill(datatable4); NotScheduleMachineDt.Clear(); NotScheduleMachineDt = datatable4; */ //fitness sql = @"TRUNCATE TABLE injection_plan_fitness"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); sql = @"insert into injection_plan_fitness(ver,dev_days) SELECT ver,ROUND(STDDEV(need_days),3) dev_days FROM ( SELECT ver,machine,SUM(need_days) need_days FROM injection_plan WHERE ver>=0 GROUP BY ver,machine) GROUP BY ver"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); //已發料的工單不再進行重新排機 sql = @"TRUNCATE TABLE CanScheduleJobnum"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); sql = @" insert into CanScheduleJobnum SELECT job_num FROM injection_plan WHERE ver=2 and job_num not in ( SELECT DISTINCT job_num FROM ( SELECT sfa06, injection_plan.* FROM injection_plan LEFT JOIN sfa_file ON job_num = sfa01 WHERE ver = 2 AND sfa06> 0))"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); //計算每次變異的工單張數 sql = @"SELECT CEIL(COUNT(*)*(" + P.Text + "/100)) FROM injection_plan WHERE ver=2"; int MutationJobQty = int.Parse(OracleHelper.ExecuteDataTable(sql).Rows[0][0].ToString()); for (int i = 0; i < int.Parse(Generation.Text); i++) { label14.BeginInvoke(new Action(() => { label14.Text=i.ToString(); })); //遺傳使用精英模式 int Mutation = int.Parse(EliteGeneration.Text); Mutation = int.Parse(EliteGeneration.Text) - i / 10000 * 15;//進化壓力,越到後面壓力越大,利於收斂 if (Mutation < 30) { Mutation = 30; } sql = @"SELECT ver,dev_days FROM ( select ver,dev_days from injection_plan_fitness order by dev_days ) WHERE ROWNUM<=" + Mutation + " "; cmd.CommandText = sql; DataTable datatable53 = new DataTable(); adapter.Fill(datatable53); if (datatable53.Rows.Count == Mutation) { if (decimal.Parse(datatable53.Rows[0][1].ToString()) == decimal.Parse(datatable53.Rows[Mutation - 1][1].ToString())) { //收斂退出條件 break; } } randkey4 = rd4.Next(0, datatable53.Rows.Count); sql = @"insert into injection_plan SELECT " + (i + 3) + @" Ver, job_num, machine, start_date, end_date, partnum, prod_qty, complete_qty, uncomplete_qty, daily_plan_qty, need_days, estimate_complete_date, suggestion_workshop, ton, gong_mu, mold FROM injection_plan where Ver=" + datatable53.Rows[randkey4][0] + " "; //精英模式複製 cmd.CommandText = sql; cmd.ExecuteNonQuery(); if (i <= 1000) { /* sql = @" SELECT job_num,PartNum,ton,gong_mu,mold FROM injection_plan WHERE job_num in ( SELECT job_num FROM CanScheduleJobnum) and ver=" + (i + 3) + @" and machine IS NULL "; */ sql = @" SELECT t0.job_num,PartNum,prod_qty,ton,gong_mu,mold FROM injection_plan t0 left join CanScheduleJobnum t1 on t0.job_num=t1.job_num where t1.job_num is not null and ver=" + (i + 3) + @" and machine IS NULL "; } else { /* sql = @" SELECT job_num,PartNum,ton,gong_mu,mold FROM injection_plan WHERE job_num in ( SELECT job_num FROM CanScheduleJobnum) and ver=" + (i + 3) + @" and (machine is null or (machine IN ( SELECT machine FROM ( SELECT machine,SUM(need_days) need_days FROM injection_plan WHERE ver=" + (i + 3) + @" GROUP BY machine ) WHERE need_days>=" + int.Parse(Days.Text) + @" AND machine IS NOT NULL )))"; */ sql = @"SELECT t0.job_num,t0.PartNum,t0.prod_qty,t0.ton,t0.gong_mu,t0.mold FROM injection_plan t0 LEFT JOIN ( SELECT machine FROM ( SELECT machine,SUM(need_days/gong_mu) need_days FROM injection_plan WHERE ver=" + (i + 3) + @" GROUP BY machine ) WHERE need_days>=" + int.Parse(Days.Text) + @" AND machine IS NOT NULL ) t1 ON t0.machine=t1.machine LEFT JOIN CanScheduleJobnum t3 ON t0.job_num=t3.job_num WHERE t3.job_num IS NOT NULL AND ver=" + (i + 3) + @" and (t0.machine is NULL OR t1.machine IS NOT NULL) "; } cmd.CommandText = sql; DataTable datatable51 = new DataTable(); adapter.Fill(datatable51); NotScheduleJobNumDt.Clear(); NotScheduleJobNumDt = datatable51; if (NotScheduleJobNumDt.Rows.Count == 0) { continue; } //對1%的進行變異 for (int j = 0; j < MutationJobQty - 1; j++) { randkey = rd.Next(0, NotScheduleJobNumDt.Rows.Count); //工單只排對應噸位的注塑機 if (NotScheduleJobNumDt.Rows[randkey]["ton"].ToString().Length == 0) { NotScheduleJobNumDt.Rows[randkey]["ton"] = 200; } if (i <= 1000) { sql = @"select * from injection_plan_machine WHERE machine_ton>=" + int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + @" and machine_ton<=" + (int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + int.Parse(Ton.Text)) + @" and MACHINE_DOWN='N' "; cmd.CommandText = sql; DataTable datatable6 = new DataTable(); adapter.Fill(datatable6); NotScheduleMachineDt.Clear(); NotScheduleMachineDt = datatable6; } else { /* sql = @"select * from injection_plan_machine WHERE machine_ton>=" + int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + @" and machine_ton<=" + (int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + int.Parse(Ton.Text))+@" and ECI01 IN ( SELECT machine FROM ( SELECT machine,SUM(need_days) need_days FROM injection_plan WHERE ver=" + (i + 3) + @" GROUP BY machine ) WHERE need_days<" + int.Parse(Days.Text) + @" AND machine IS NOT NULL) union all select * from injection_plan_machine where eci01 not in(select machine from injection_plan where machine is not null and ver="+(i+3)+") "; */ sql = @"select t0.* from injection_plan_machine t0 LEFT JOIN ( SELECT machine FROM ( SELECT machine,SUM(need_days/gong_mu) need_days FROM injection_plan WHERE ver=" + (i + 3) + @" GROUP BY machine ) WHERE need_days<" + int.Parse(Days.Text) + @" AND machine IS NOT NULL ) t1 ON t0.eci01=t1.machine WHERE machine_ton>=" + int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + @" and machine_ton<=" + (int.Parse(NotScheduleJobNumDt.Rows[randkey]["ton"].ToString()) + int.Parse(Ton.Text)) + @" AND t1.machine IS NOT NULL and t0.MACHINE_DOWN='N' union all select t00.* from injection_plan_machine t00 LEFT JOIN ( select machine from injection_plan where machine is not null and ver=" + (i + 3) + @" ) t01 ON t00.eci01=t01.machine WHERE t01.machine IS NULL and t00.MACHINE_DOWN='N' "; cmd.CommandText = sql; DataTable datatable6 = new DataTable(); adapter.Fill(datatable6); NotScheduleMachineDt.Clear(); NotScheduleMachineDt = datatable6; } if (NotScheduleMachineDt.Rows.Count == 0) { continue; } randkey2 = rd2.Next(0, NotScheduleMachineDt.Rows.Count); sql = @"update injection_plan set machine='" + NotScheduleMachineDt.Rows[randkey2]["ECI01"] + @"' where job_num='" + NotScheduleJobNumDt.Rows[randkey]["job_num"].ToString() + "' and ver=" + (i + 3) + " "; cmd.CommandText = sql; cmd.ExecuteNonQuery(); //現在考慮1個模具出2個膠件的情況,找到剛才這張工單使用的模具,找到應模具使用的料號, //找到料號對應的工單,更新之 //先處理2個料號共模具 其他的暫時不處理 2020年1月10日10:19:40 if (NotScheduleJobNumDt.Rows[randkey]["gong_mu"].ToString() == "2") { //找出共模的料號 sql = @"SELECT tc_mmj03 FROM tc_mmj_file WHERE tc_mmj01='" + NotScheduleJobNumDt.Rows[randkey]["mold"] + @"' AND tc_mmj03<>'" + NotScheduleJobNumDt.Rows[randkey]["PartNum"] + "' "; cmd.CommandText = sql; DataTable datatable211 = new DataTable(); adapter.Fill(datatable211); //用這個料號去找一個可以排的工單號 //sql = @"SELECT job_num FROM injection_plan // WHERE partnum='" + datatable211.Rows[0][0].ToString() + @"' // and ver=1 and job_num<>'" + NotScheduleJobNumDt.Rows[randkey]["job_num"].ToString() + @"' // and job_num in (select job_num from CanScheduleJobnum) ";//可以排的工單號 /* sql = @"SELECT job_num FROM injection_plan WHERE partnum='" + datatable211.Rows[0][0].ToString() + @"' and ver=1 and job_num<>'" + NotScheduleJobNumDt.Rows[randkey]["job_num"].ToString() + @"' and exists (select * from CanScheduleJobnum t0,injection_plan t1 where t0.job_num=t1.job_num) AND ROWNUM=1 ORDER BY ABS(prod_qty-" + NotScheduleJobNumDt.Rows[randkey]["prod_qty"] + ") ASC ";//可以排的工單號 //排數量跟他最接近的那個共模工單 */ sql = @"select job_num from ( SELECT row_number() OVER (ORDER BY ABS(prod_qty-" + NotScheduleJobNumDt.Rows[randkey]["prod_qty"] + @") ASC) seq ,job_num FROM injection_plan WHERE partnum='" + datatable211.Rows[0][0].ToString() + @"' and ver=1 and job_num<>'" + NotScheduleJobNumDt.Rows[randkey]["job_num"].ToString() + @"' and exists (select * from CanScheduleJobnum t0,injection_plan t1 where t0.job_num=t1.job_num) ) where seq=1 "; cmd.CommandText = sql; DataTable datatable212 = new DataTable(); adapter.Fill(datatable212); //找不到共模的工單號,就不處理了,繼續下一次循環 if (datatable212.Rows.Count == 0) { continue; } //更新這個工單號的機台 randkey3 = 0; sql = @"update injection_plan set machine='" + NotScheduleMachineDt.Rows[randkey2]["ECI01"] + @"' where job_num='" + datatable212.Rows[randkey3]["job_num"].ToString() + "' and ver=" + (i + 3) + " "; cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } sql = @"insert into injection_plan_fitness(ver,dev_days,max_days,min_days) SELECT ver,ROUND(STDDEV(need_days),5) dev_days,max(need_days) max_days,min(need_days) min_days FROM ( SELECT ver,machine,round(SUM(need_days/gong_mu),2) need_days FROM injection_plan WHERE ver=" + (i + 3) + @" GROUP BY ver,machine) GROUP BY ver"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); ClearMemory(); } conn.Close(); label11.BeginInvoke(new Action(() => { label11.Text = "~~~計算完畢~~~"; })); label11.BeginInvoke(new Action(() => { label18.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); })); } private void button1_Click(object sender, EventArgs e) { label18.Text = "結束時間"; if (label11.Text == "正在計算中。。。。。。") { MessageBox.Show("正在計算中,請不要再次點擊"); return; } label10.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); var t1 = Task.Run(() => GA()); label11.Text = "正在計算中。。。。。。"; } [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize); /// <summary> /// 释放内存 /// </summary> public static void ClearMemory() { GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); } } private void button2_Click(object sender, EventArgs e) { } private void button2_Click_1(object sender, EventArgs e) { } private void button2_Click_2(object sender, EventArgs e) { string sql; for (int i = 0; i < dataGridView1.Rows.Count; i++) { if ((Convert.ToBoolean(dataGridView1.Rows[i].Cells["Select"].Value) == true)) { string machine = ""; machine = dataGridView1.Rows[i].Cells["machine"].Value.ToString(); sql = @"update injection_plan_machine set MACHINE_DOWN='Y' where eci01='" + machine + "' "; OracleHelper.ExecuteNonQuery(sql); } else { string machine = ""; machine = dataGridView1.Rows[i].Cells["machine"].Value.ToString(); sql = @"update injection_plan_machine set MACHINE_DOWN='N' where eci01='" + machine + "' "; OracleHelper.ExecuteNonQuery(sql); } } MachineQuery(); } private void button3_Click(object sender, EventArgs e) { string sql; sql = @"SELECT * FROM ( SELECT * FROM injection_plan_fitness ORDER BY dev_days) WHERE ROWNUM<100"; dataGridView2.DataSource = OracleHelper.ExecuteDataTable(sql); } private void button4_Click(object sender, EventArgs e) { string sql; sql = @"SELECT ROWNUM,t0.* FROM ( SELECT machine,ROUND(SUM(need_days/gong_mu),0) need_days,COUNT(*) job_qty,MAX(ton) ton FROM injection_plan WHERE ver="+GenerationQuery.Text+@" AND machine NOT IN('FC31','FBC09','JB22','JB02') GROUP BY machine ORDER BY NEED_DAYS ASC) t0"; dataGridView3.DataSource = OracleHelper.ExecuteDataTable(sql); } private void button5_Click(object sender, EventArgs e) { string sql = @"select * from injection_plan where ver="+InjectionG.Text+" "; dataGridView4.DataSource = OracleHelper.ExecuteDataTable(sql); } private void button6_Click(object sender, EventArgs e) { if (label18.Text == "結束時間") { DateTime startTime = Convert.ToDateTime(label10.Text); DateTime endTime = DateTime.Now; TimeSpan ts = endTime - startTime; //int seconds = (int)ts.TotalSecond; int sec = (int)ts.TotalSeconds; label16.Text = (Math.Round(float.Parse(label14.Text) / sec, 2)).ToString("0.00"); } else { DateTime startTime = Convert.ToDateTime(label10.Text); DateTime endTime = Convert.ToDateTime(label18.Text); TimeSpan ts = endTime - startTime; //int seconds = (int)ts.TotalSecond; int sec = (int)ts.TotalSeconds; label16.Text = (Math.Round(float.Parse(label14.Text) / sec, 2)).ToString("0.00"); } } private void button7_Click(object sender, EventArgs e) { string sql = @"select * from injection_plan where ver=" + InjectionG.Text + " "; ExcelHelper.ToExcel(OracleHelper.ExecuteDataTable(sql)); } private void button8_Click(object sender, EventArgs e) { if ((Convert.ToBoolean(dataGridView1.Rows[0].Cells[0].Value) == false)) { for (int i = 0; i < dataGridView1.Rows.Count; i++) { if ((Convert.ToBoolean(dataGridView1.Rows[i].Cells[0].Value) == false)) { dataGridView1.Rows[i].Cells[0].Value = "True"; } } } else { for (int i = 0; i < dataGridView1.Rows.Count; i++) { if ((Convert.ToBoolean(dataGridView1.Rows[i].Cells[0].Value) == true)) { dataGridView1.Rows[i].Cells[0].Value = "False"; } } } } private void button9_Click(object sender, EventArgs e) { mychart.ChartAreas.Clear(); //图表区 mychart.Titles.Clear(); //图表标题 mychart.Series.Clear(); //图表序列 mychart.Legends.Clear(); //图表图例 //新建chart图表要素 mychart.ChartAreas.Add(new ChartArea("chartArea")); mychart.ChartAreas["chartArea"].AxisX.IsMarginVisible = false; mychart.ChartAreas["chartArea"].Area3DStyle.Enable3D = false; mychart.Series.Add("均方差回歸"); //mychart.Titles.Add("均方差回歸"); //标题 //mychart.Titles[0].Font = new Font("宋体", 12); mychart.Series["均方差回歸"].ChartType = SeriesChartType.Point; //图标类型 mychart.Series["均方差回歸"]["PieLineColor"] = "Black"; //mychart.Legends.Add(new Legend("legend")); mychart.Palette = ChartColorPalette.BrightPastel; mychart.ChartAreas["chartArea"].AxisY.LabelStyle.IsStaggered = true; Legend tu_li = new Legend(); mychart.Legends.Add(tu_li); tu_li.Alignment = StringAlignment.Center; tu_li.Docking = Docking.Top; tu_li.Font= new Font("宋体", 24); ; string sql3 = "SELECT ver,dev_days FROM injection_plan_fitness ORDER BY ver"; DataTable dt2; dt2 = OracleHelper.ExecuteDataTable(sql3); mychart.Series["均方差回歸"].Points.DataBind(dt2.AsEnumerable(), "VER", "DEV_DAYS", ""); mychart.Series["均方差回歸"].LabelForeColor = Color.Blue; } } }
相关文章推荐
- C#连接Oracle查询数据乱码问题解决
- C#连接oracle的方式以及问题解决.
- 解决C#中用Oracle执行存储过程返回DataSet的问题
- c#读写oracle 中文乱码问题解决
- 解决Oracle in 超过1000个问题 C#拼接字符串
- C# 无客户端连接oracle 11g 乱码问题解决
- C#连接Oracle中文乱码问题解决方法
- 解决C#中用Oracle执行存储过程返回DataSet的问题
- c#访问Oracle问题及解决方法
- Oracle诊断案例----如何捕获问题SQL解决过度CPU消耗问题
- 解决问题记录(1)-使用OleDbProvider连接Oracle出错
- C# winform中不规则窗体制作的解决方案(已经解决24位色以上不能正常显示问题)
- 如何解决 JMeter 通过 JDBC 访问 Oracle 和 MySQL 的问题 (留言中有 Test Plan 实例下载)
- Oracle中捕获问题SQL解决CPU过渡消耗
- oracle+jsp中blob类型存储大文本问题解决方法
- 分页显示问题的解决方法(jsp,sqlserver,mysql,oracle)
- Enterprise Library - Data Block oracle返回 cursor 问题的解决
- 解决ORACLE CLIENT中中文字符问题
- Oracle出现了问题“无法使用系统回滚段”并解决
- oracle9问题解决:oracle initialization or shutdown in progress