這篇文章主要給大家介紹了關於asp.net開發中sql server轉換成oracle的相關資料,文中通過範例程式碼和圖文將實現的步驟一步步介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧。
前言
因為前段時間我們公司項目 要把sql server 轉oracle,發現網上這方面的資料較少,所以在這裡分享一下心得,也記錄一下問題,下面話不多說了,來一起看看詳細的介紹:
開始我研究了一段時間 然後下載了
oracle 11g 版本 和 PL/SQL(用戶端) 和sql server 不同的是 oracle 沒有自己的用戶端 需要用第三方的軟體運行 PL/SQL 就是一個 sqldeveloper 也是一個,PL/SQL 我覺得比較穩定一點。但是2個都安裝的話 剛好互補了
oracle 容易出現 無監聽 什麼 的錯誤 可以參考
http://www.jb51.net/article/91184.htm
然後再用
建立資料表空間 和使用者 這些網上都找得到的
好了 東西都安裝好了 下面開始 sql server 轉 oracle
首先是資料庫的轉換 我試了很多種方式,都是多多少少都是有點問題,因為是2個不同的資料庫,最後我還是決定自己寫個程式 轉換
代碼貼出來
連結字串
<add key="OracleConnectionString" value="Password=123;User ID=SA;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost )(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))"/> <add key="SqlServerConnectionString" value="server=localhost;database=Table;uid=sa;pwd=123"/>
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Data.OracleClient;using System.Data.SqlClient;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace TransplantSQL{ public partial class Form1 : Form { public static string OracleConnectionString = System.Configuration.ConfigurationSettings.AppSettings["OracleConnectionString"]; public static string SqlServerConnectionString = System.Configuration.ConfigurationSettings.AppSettings["SqlServerConnectionString"]; public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { OracleConnection con = new OracleConnection(OracleConnectionString); try { con.Open(); if (con.State == System.Data.ConnectionState.Open) { label5.Text = "串連成功"; } } catch (OracleException se) { label5.Text = "串連失敗"; } finally { con.Close(); } } private void button3_Click(object sender, EventArgs e) { SqlConnection con = new SqlConnection(SqlServerConnectionString); try { con.Open(); if (con.State == System.Data.ConnectionState.Open) { label4.Text = "串連成功"; } } catch (SqlException se) { label4.Text = "串連失敗"; } finally { con.Close(); } } private void button1_Click(object sender, EventArgs e) { if (textBox1.Text == "") { DataTable tablenames = GetTableNames(); foreach (DataRow item in tablenames.Rows) { string tablename = item["Name"].ToString().ToUpper(); setdata(tablename); } } else { setdata(textBox1.Text); } label2.Text = "成功"; } private static void setdata(string tablename) { // 尋找有沒有此表 如果沒有就加 int et = Convert.ToInt32(GetSingle("select count(*) from user_tables where table_name = '" + tablename + "'")); if (et <= 0) { DataTable tableInfo = GetTableInfo(tablename); string addtablesql = "CREATE TABLE {0}({1})"; string cs = string.Empty; string biaoshi = string.Empty; foreach (DataRow citem in tableInfo.Rows) { cs += citem["欄位名"].ToString(); if (citem["類型"].ToString() == "int" || citem["類型"].ToString() == "bit" || citem["類型"].ToString() == "decimal") { cs += " NUMBER(" + (Convert.ToInt32(citem["長度"]) > 38 ? 38 : Convert.ToInt32(citem["長度"])) + (Convert.ToInt32(citem["小數位元"])>0?(","+Convert.ToInt32(citem["小數位元"])):"") + ")"; } else if (citem["類型"].ToString() == "nvarchar" || citem["類型"].ToString() == "float") { cs += " VARCHAR2(" + (Convert.ToInt32(citem["長度"]) == -1 ? 4000 : Convert.ToInt32(citem["長度"]) * 2) + ")"; } else if (citem["類型"].ToString() == "datetime") { cs += " DATE"; } cs += citem["主鍵"].ToString() == "1" ? " primary key " : ""; if (citem["標識"].ToString() == "1") { biaoshi = citem["欄位名"].ToString(); } cs += citem["預設值"].ToString() != "" ? " default " + citem["預設值"].ToString() + " " : ""; cs += citem["允許空"].ToString() == "1" ? "," : " NOT NULL,"; } cs = cs.Substring(0, cs.Length - 1); string tempsql = string.Format(addtablesql, tablename, cs); GetSingle(tempsql); if (biaoshi != string.Empty) { #region 判斷是否有序號 沒有就建立 就是自動標識 int xuliehao = 0; try { xuliehao = Convert.ToInt32(GetSingle(string.Format(@"select Seq_{0}.nextval from sys.dual", tablename))); } catch { } if (xuliehao <= 0) { #region 為了讓序列不重複 取最大值為min 值 int max = Convert.ToInt32(GetSingle(string.Format("select max({1}) from {0}", tablename, biaoshi),null)); #endregion string sequence = string.Format(@"create sequence Seq_{0} start with {1} increment by 1 nomaxvalue minvalue 1 nocycle nocache", tablename, (max+1));//建立標識 GetSingle(sequence); } #endregion #region 建立序列的觸發器 string chufaqisql = string.Format(@"CREATE OR REPLACE TRIGGER T_{0} BEFORE INSERT ON {0} FOR EACH ROW WHEN (new.{1} is null) begin select Seq_{0}.nextval into:new.{1} from dual; end;", tablename, biaoshi);//建立觸發器 GetSingle(chufaqisql); #endregion #region 建立唯一約束 //string weiyisql = string.Format(@"create unique index U_{0} on {0} ({1})", tablename, biaoshi); //GetSingle(weiyisql); #endregion } //int count = Convert.ToInt32(GetSingle("SELECT count(1) FROM " + tablename)); //if (count < 10000) //{ DataSet ds = Query("SELECT * FROM " + tablename); DataTable dt = ds.Tables[0]; string columnsNames = string.Empty; string values = string.Empty; for (int i = 0; i < dt.Columns.Count; i++) { columnsNames += dt.Columns[i].ColumnName + ","; } columnsNames = columnsNames.Substring(0, columnsNames.Length - 1); foreach (DataRow dr in dt.Rows) { values = string.Empty; for (int i = 0; i < dt.Columns.Count; i++) { if (dr[i] != DBNull.Value) { if (dr[i].ToString() != "") { if (dt.Columns[i].DataType == Type.GetType("System.Double") || dt.Columns[i].DataType == Type.GetType("System.Decimal") || dt.Columns[i].DataType == Type.GetType("System.Int32")) { values += dr[i] + ","; } else if (dt.Columns[i].DataType == Type.GetType("System.String")) { values += "'" + dr[i].ToString().Replace('\'', '‘') + "',"; } else if (dt.Columns[i].DataType == Type.GetType("System.DateTime")) { values += "to_date('" + dr[i] + "','YYYY/MM/DD HH24:MI:SS'),"; } else if (dt.Columns[i].DataType == Type.GetType("System.Boolean")) { if (dr[i].ToString() == "False") { values += "0,"; } else { values += "1,"; } } } else { values += "chr(32),"; } } else { values += "NULL,"; } } values = values.Substring(0, values.Length - 1); string osql = "Insert into " + tablename + "(" + columnsNames + ") values(" + values + ")"; GetSingle(osql); } //} } } private static DataTable GetTableNames() { string sql = string.Format(@"SELECT Name FROM SysObjects Where XType='U' ORDER BY Name"); DataSet ds = Query(sql); return ds.Tables[0]; } private static DataTable GetTableInfo(string tableName) { string sql = string.Format(@"SELECT (case when a.colorder=1 then d.name else null end) 表名, a.colorder 欄位序號,a.name 欄位名, (case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '1'else '' end) 標識, (case when (SELECT count(*) FROM sysobjects WHERE (name in (SELECT name FROM sysindexes WHERE (id = a.id) AND (indid in (SELECT indid FROM sysindexkeys WHERE (id = a.id) AND (colid in (SELECT colid FROM syscolumns WHERE (id = a.id) AND (name = a.name))))))) AND (xtype = 'PK'))>0 then '1' else '' end) 主鍵,b.name 類型,a.length 佔用位元組數, COLUMNPROPERTY(a.id,a.name,'PRECISION') as 長度, isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as 小數位元,(case when a.isnullable=1 then '1'else '' end) 允許空, REPLACE(REPLACE(isnull(e.text,''),'(',''),')','') 預設值,isnull(g.[value], ' ') AS [說明] FROM syscolumns a left join systypes b on a.xtype=b.xusertype inner join sysobjects d on a.id=d.id and d.xtype='U' and d.name<>'dtproperties' left join syscomments e on a.cdefault=e.id left join sys.extended_properties g on a.id=g.major_id AND a.colid=g.minor_id left join sys.extended_properties f on d.id=f.class and f.minor_id=0 where b.name is not null And d.name='{0}' order by a.id,a.colorder", tableName); DataSet ds = Query(sql); return ds.Tables[0]; } public static DataSet Query(string SQLString) { using (SqlConnection connection = new SqlConnection(SqlServerConnectionString)) { DataSet ds = new DataSet(); try { connection.Open(); SqlDataAdapter command = new SqlDataAdapter(SQLString, connection); command.Fill(ds, "ds"); } catch (System.Data.SqlClient.SqlException ex) { throw new Exception(ex.Message); } return ds; } } public static object GetSingle(string SQLString) { using (OracleConnection connection = new OracleConnection(OracleConnectionString)) { using (OracleCommand cmd = new OracleCommand()) { try { PrepareCommand(cmd, connection, null, SQLString, null); object obj = cmd.ExecuteScalar(); cmd.Parameters.Clear(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return null; } else { return obj; } } catch (OracleException e) { throw e; } } } } private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, string cmdText, OracleParameter[] cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = CommandType.Text;//cmdType; if (cmdParms != null) { foreach (OracleParameter parameter in cmdParms) { if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) && (parameter.Value == null)) { parameter.Value = DBNull.Value; } cmd.Parameters.Add(parameter); } } } public static object GetSingle(string SQLString, params SqlParameter[] cmdParms) { using (SqlConnection connection = new SqlConnection(SqlServerConnectionString)) { using (SqlCommand cmd = new SqlCommand()) { try { PrepareCommand(cmd, connection, null, SQLString, cmdParms); object obj = cmd.ExecuteScalar(); cmd.Parameters.Clear(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return null; } else { return obj; } } catch (System.Data.SqlClient.SqlException e) { throw e; } } } } private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, string cmdText, SqlParameter[] cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = CommandType.Text;//cmdType; if (cmdParms != null) { foreach (SqlParameter parameter in cmdParms) { if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) && (parameter.Value == null)) { parameter.Value = DBNull.Value; } cmd.Parameters.Add(parameter); } } } }}
這個代碼適應於我的資料庫轉換 大家需要的話 可以修改一下
其中oracle 沒有自增長的 ,,而是序列 另外序列可以用觸發器觸發 麻煩了一點 整的來說 還算好啦
然後就是把我原來的程式 字串連結改成oracle 的連結 上面貼出來了
首先System.Data.SqlClient;
引用 改成System.Data.OracleClient;
然後 在看報錯的地方通通改掉就行了 從Sql 改為 Oracle 就行
然後我貼出一些 不報錯 但是sqlserver 和oracle 不同的地方
查詢前多少條資料
select * from (SELECT * FROM Table) where rownum<100
其他格式轉化成字串格式
select to_char(其他格式,字串格式) 如select to_char(sysdate,'yyyy-mm-dd') from dual
字串截取
(截取的字串,開始的位置,長度)
select substr('111222',3,2) from dual
字串格式轉化為時間格式
select to_date('2017-08-03','yyyy-mm-dd') from dual
sql參數化預留位置,不能用@用:
SELECT * FROM Table where ID=:ID
系統時間
getdate()
改成sysdate
擷取當前自動成長列ID
select Seq_Table.currval from dual
Seq_Table是自動成長列的名字,每個表都不一樣,所以需要找到當前
表設定的自動成長列對應的名字
都改完之後 等程式不報錯了 運行
會出現32和64位的什麼破問題 網上各種說法的都有 說項目屬性中 改成 X86 X64
但是這些對我都不管用 並且我覺得 這些東西改了之後 會對我原有的項目造成很多問題
所以我研究了很久 最終得出幾個結果
首先 如果是控制台 或表單 程式的話 直接把項目中 首選32位 勾上就行了
如果是 asp.net 頁面程式就沒這麼簡單了
我本機是64位系統 然後我安裝oracle 和用戶端都是64位 按道理不應該給我報什麼64位錯啊
然後網上說要安裝32位Instant Client Setup
然後我就下了一個 安裝了 程式就可以了 ,
但是我在伺服器上面 再次用同樣的方法又不行了,找了很多資料 最終 重新安裝了一下iis好了(其實是要重新註冊一遍framework)
安裝32位的版本最好和oracle 版本一樣
那時候我下了很多個版本 調試 有的時候 安裝 Instant Client Setup的時候會卡在一個點不動,可以多試幾次 如果還是不行 在重新找一個吧!
安裝完後 在控制台裡面可以找到的
另外貼出備份 還原的 命令 用CMD開啟 運行 修改對應參數
Exp sa/123@ORCL file=C:\OracleBack\back_%date:~0,4%%date:~5,2%%date:~8,2%.dmp owner=saIMP sa/123 BUFFER=64000 FILE=C:\OracleBack\back_20170821.dmp FROMUSER=SA TOUSER=SA