紧急求助,有没有将SQL Server的SQL翻译为Oracle的第三方组件? 40shaoyy]

发布时间:2016-12-6 8:56:13 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"紧急求助,有没有将SQL Server的SQL翻译为Oracle的第三方组件? 40shaoyy]",主要涉及到紧急求助,有没有将SQL Server的SQL翻译为Oracle的第三方组件? 40shaoyy]方面的内容,对于紧急求助,有没有将SQL Server的SQL翻译为Oracle的第三方组件? 40shaoyy]感兴趣的同学可以参考一下。

最近接到一个项目,不是很大,但客户要求数据库用oracle,而我们的系统是在sql server下做的,我们的系统在程序中嵌入了大量的SQL语句,如果全部手动翻译几乎是不可能的,我们的系统基于delphi的midas三层架构,幸好系统设计时将所有的SQL(包括客户端和中间层)都是通过中间层一个统一的接口来执行的,我想,如果在这个接口中将需要执行的SQL进行语法转换,就可以直接支持oracle了,但这种转换也算是一种高技术含量的活,想请教一下各位见多识广的大虾,有没有现成的第三方组件可以完成这个工作?例如,我传一个SQL Server规范的SQL给组件,组件返回一个支持Oracle规范的SQL给我就行了。感谢~!

异想天开.

引用 1 楼 dawugui 的回复:异想天开. 我觉得并非异想天开,事实上我已经找到这个工具(sqlways),里面有提供这样的功能,但可惜不是组件。

找到以后给我传一个 谢谢

这个不大现实,有些东西还是得手工做一下。。。。。

可以去oracle版块问问,或者直接咨询oracle的技术支持。。。

首先你的SQL语句是用SQL99的规范写的吗? 如果你的SQLSERVER上面不运行SP,只是直接SQL语句写的话,那你比较幸运,ORACLE和SQLSERVER在SQL语句上面的差异主要在函数上,比如日期函数之类的。这样改起来比较简单。 如果你在SQLSERVER上布置了大量的SP,那你只能慢慢改了,ORACLE和SQLSERVER的SP还是区别很大的。

呵,若是SP,改动反而更容易。。。。若是在客户端,那就只有到处搜索喽

引用 6 楼 guanjm 的回复:首先你的SQL语句是用SQL99的规范写的吗? 如果你的SQLSERVER上面不运行SP,只是直接SQL语句写的话,那你比较幸运,ORACLE和SQLSERVER在SQL语句上面的差异主要在函数上,比如日期函数之类的。这样改起来比较简单。 如果你在SQLSERVER上布置了大量的SP,那你只能慢慢改了,ORACLE和SQLSERVER的SP还是区别很大的。 SP很少

引用 7 楼 luckyrandom 的回复:呵,若是SP,改动反而更容易。。。。若是在客户端,那就只有到处搜索喽 所有SQL的执行,都是通过AppServer里一个的函数来完成的,也许不需要这样做~

挺麻烦的。

花了两天时间,基本上搞定(还有待完善,但最核心的已经可以,包括函数提取和替换算法已经搞定): unit SqlConvertToOracle; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs; Type    TSqlFuncInfo = record      Name: string;      ArgCount: integer;      Args: array [0..10] of string[100];    end; //最终需要调用的函数 function ConvertSQLToOracle(ASQL: string): string; //从SQL中提取函数信息 function GetFirstFuncInfo(ASQL, AFuncName: string; var ABegin, AEnd: integer; var AFunInfo: TSqlFuncInfo): boolean; //将原来的函数替换成新的函数(包括参数) function ReplaceFunctionByNew(ASQL: string; ABegin, AEnd: integer; AFuncInf, ANewFuncInf: TSqlFuncInfo): string; //转换SQl Server中以 = 表示的列别名,例如: Abc = Field1 转换为 Field1 Abc function ConvertFieldAlias(ASQL: string): string; implementation function ReplaceCommons(ASQL: string): string; begin   Result := StringReplace(ASQL, ' #', ' T_', [rfReplaceAll]);  //临时表的名称   Result := StringReplace(Result, ' as ', ' ', [rfReplaceAll]); //别名去掉as end; function ConvertTopNWord(ASQL: string): string; var   n, n2, i, topN: integer;   sTmp: string; begin   Result := ASQL;   n := pos(' top ', Result);   if n <= 0 then     Exit;   i := n + 4;   sTmp := '';   while Result[i] = ' ' do     inc(i);   while not (Result[i] in [' ', '(']) do   begin     sTmp := sTmp + Result[i];     inc(i);   end;   n2 := i - 1;   if sTmp <> '' then     topN := strtoint(sTmp)   else     topN := -1;   Delete(Result, n + 1, n2 - n); //删除原来的 top N,只留一个空格   n := pos(' where ', Result);   if n > 0 then     Result := Copy(Result, 1, n - 1) + ' where (' + copy(Result, n +6, length(Result)) + ') And ROWNUM <= ' + inttostr(TopN)   else     Result := Result + ' Where ROWNUM <= ' + inttostr(TopN); end; //转换SQl Server中以 = 表示的列别名,例如: Abc = Field1 转换为 Field1 Abc function ConvertFieldAlias(ASQL: string): string; var   st, n, k, j, p1, p2, p3, p4, p5: integer;   sTmp, sPttr, Word1, Word2, Word3, Word4, Word5: string;   b: boolean;   function _Check: boolean;   begin     Result := false;     if (pos('select', Word1) > 0) or (pos('select', Word3) > 0) then       Result := true     else     begin       k := p3;       while k <= p4 do       begin         if ASQL[k] = ',' then         begin           Result := true;           Exit;         end;         Inc(k);       end;     end;   end;    begin   Result := '';   sTmp := '';   //最近5个单词   Word1 := '';   Word2 := '';   Word3 := '';   Word4 := '';   Word5 := '';   n := 1;   //最近5个单词的尾部位置   p1 := 1;   p2 := 1;   p3 := 1;   p4 := 1;   p5 := 1;   b := false;   st := 0;   //扫描   while n <= Length(ASQL) do   begin     if ASQL[n] = '(' then       Inc(st)     else     if ASQL[n] = ')' then       Dec(st);     if (ASQL[n] in [' ', '=', #13, #10, ',']) and (st = 0) then     begin       Word1 := Word2;       Word2 := Word3;       Word3 := Word4;       Word4 := Word5;       Word5 := sTmp;       sTmp := '';       p1 := p2;       p2 := p3;       p3 := p4;       p4 := p5;       p5 := n;       while (n <= Length(ASQL)) and (ASQL[n] in [' ', ',', #13, #10]) do       begin        /// Result := Result + ASQL[n];         Inc(n);       end;       if b then       begin         b := false;         if _Check then         begin           sPttr := Word5 + ' ' + Word4;           j := (P5-1) - (P4 - Length(Word4)) + 1; //原串的长度           while Length(sPttr) < j do             sPttr := sPttr +' ';           j := 1;           for k := (P4 - Length(Word4)) to P5 - 1 do           begin             ASQL[k] := sPttr[j];             Inc(j);           end;          // Result := Result + Word5 + ' ' + Word4;         end;       end;       if ASQL[n]  = '=' then         b := true;       while (n <= Length(ASQL)) and (ASQL[n] in [' ', '=', ',', #13, #10]) do       begin       //  Result := Result + ASQL[n];         Inc(n);       end;                    end;         // Result := Result + ASQL[n];     sTmp := sTmp + ASQL[n];     Inc(n);   end;   Result := ASQL; end;

//从SQL中提取第一个指定名称的函数信息 function GetFirstFuncInfo(ASQL, AFuncName: string; var ABegin, AEnd: integer; var AFunInfo: TSqlFuncInfo): boolean; var   n, n2, k, ArgBegin, ArgEnd, st, ArgCount: integer;   sArgs: array [0..10] of string;   sTmp: string; begin   Result := false;   ArgBegin := -1; //参数开始   ArgEnd := -1;  //参数结束   AFunInfo.Name := AFuncName;   AFuncName := LowerCase(AFuncName);   n := pos(AFuncName, ASQL);   if n <= 0 then     Exit;   n2 := n;   while (n2 <= Length(ASQL)) and (ASQL[n2] <> '(') do     Inc(n2);   if n2 > Length(ASQL) then     Exit;   ArgBegin := n2 + 1;   st := 0;   n2 := n2 + 1;   while (n2 <= Length(ASQL))  do   begin     if ASQL[n2] = '(' then       Inc(st)      //状态机     else     if ASQL[n2] = ')' then     if st = 0 then     begin       ArgEnd := n2 - 1;       Break;     end     else       Dec(st);     Inc(n2);   end;   if ArgEnd = -1 then //参数不正确     Exit;   ABegin := n;   AEnd := n2;   sTmp := '';   ArgCount := 0;   k := ArgBegin; //参数开始   st := 0; //状态机,用来处理函数嵌套的情况   while k <= Argend do //分离参数   begin     if (ASQL[k] = ',') and (st = 0) then     begin       sArgs[ArgCount] := sTmp;       Inc(ArgCount);       sTmp := '';     end    else       sTmp := sTmp + ASQL[k];     if ASQL[k]= '(' then       Inc(st)     else     if ASQL[k] = ')' then       Dec(st);     Inc(k);         end;   if sTmp <> '' then   begin        //最后一个参数    sArgs[ArgCount] := sTmp;    Inc(ArgCount);   end;   if ArgCount > 10 then     ArgCount := 10;   AFunInfo.ArgCount := ArgCount;   for n := 0 to Argcount - 1 do    AFunInfo.Args[n] := sArgs[n];   Result := true;   end; //将原来的函数替换成新的函数(包括参数) function ReplaceFunctionByNew(ASQL: string; ABegin, AEnd: integer; AFuncInf, ANewFuncInf: TSqlFuncInfo): string; var   sNewFunc, sArgs: string;   i: integer; begin   //构造新函数的字串   sArgs := '';   for i := 0 to ANewFuncInf.ArgCount - 1 do     sArgs := sArgs + ANewFuncInf.Args[i] + ',';   if sArgs <> '' then     Delete(sArgs, length(sArgs), 1);     sNewFunc := ANewFuncInf.Name + '('+ sArgs + ')';   //替换原来的函数, ABegin 和 AEnd 是原来函数的起始位置   Result := Copy(ASQL, 1, ABegin - 1) + sNewFunc + Copy(ASQL, AEnd + 1, length(ASQL)); end; //替换参数一致,只是名称不同的函数 function ReplaceSameArgsFunctions(ASQL: string; AFuncName, ANewFuncName: string): string; begin   AFuncName := lowercase(AFuncName);   Result := StringReplace(ASQL, AFuncName+'(', ANewFuncName + '(', [rfReplaceAll]);   Result := StringReplace(Result, AFuncName+' (', ANewFuncName + '(', [rfReplaceAll]); //考虑函数名和括号之间有一个空格的情况 end; function Convert_GetDate(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'getdate', ABegin, AEnd, AFunInfo) do   begin     Result := Copy(Result, 1, ABegin - 1) + 'SYSTIMESTAMP' + Copy(Result, AEnd + 1, Length(Result));   end; end; //替换right函数 function Convert_Right(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'right', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 2 then       Break;     AFuncInfoNew.Name := 'SUBSTR';     AFuncInfoNew.ArgCount := 3;     AFuncInfoNew.Args[0] := AFunInfo.Args[0];     AFuncInfoNew.Args[1] := ' -' + trim(AFunInfo.Args[1]);     AFuncInfoNew.Args[2] := AFunInfo.Args[1];          Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; //替换Left函数 function Convert_Left(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'left', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 2 then       Break;     AFuncInfoNew.Name := 'SUBSTR';     AFuncInfoNew.ArgCount := 3;     AFuncInfoNew.Args[0] := AFunInfo.Args[0];     AFuncInfoNew.Args[1] := ' 1';     AFuncInfoNew.Args[2] := AFunInfo.Args[1];          Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; //替换Len函数 function Convert_Len(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'len', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 1 then       Break;     AFuncInfoNew.Name := 'LENGTH';     AFuncInfoNew.ArgCount := 1;     AFuncInfoNew.Args[0] := AFunInfo.Args[0];          Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; //替换IsNull函数 function Convert_IsNull(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'isnull', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 3 then       Break;     AFuncInfoNew.Name := 'NVL';     AFuncInfoNew.ArgCount := AFunInfo.ArgCount;     AFuncInfoNew.Args[0] := AFunInfo.Args[0];     AFuncInfoNew.Args[1] := AFunInfo.Args[1];     AFuncInfoNew.Args[2] := AFunInfo.Args[2];          Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; //替换SubString函数 function Convert_SubString(ASQL: string): string; var   AFunInfo, AFuncInfoNew: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'substring', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 3 then       Break;     AFuncInfoNew.Name := 'SUBSTR';     AFuncInfoNew.ArgCount := AFunInfo.ArgCount;     AFuncInfoNew.Args[0] := AFunInfo.Args[0];     AFuncInfoNew.Args[1] := AFunInfo.Args[1];     AFuncInfoNew.Args[2] := AFunInfo.Args[2];          Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; //替换DateDiff函数 function Convert_DateDiff(ASQL: string): string; var   AFunInfo: TSqlFuncInfo;   ABegin, AEnd, i: integer;   sPttr: string; begin   Result := ASQL;   while GetFirstFuncInfo(Result, 'datediff', ABegin, AEnd, AFunInfo)  do   begin     if AFunInfo.ArgCount < 3 then       Break;     if AFunInfo.Args[0] = 'month' then     begin      // AFuncInfoNew.Name := 'TRUNC';       sPttr := 'TRUNC(MONTHS_BETWEEN(' + AFunInfo.Args[2] + ' - ' + AFunInfo.Args[1] + '))';     end     else     begin      // AFuncInfoNew.Name := 'EXTRACT';       sPttr := 'EXTRACT(' + AFunInfo.Args[0] + ' from ' + AFunInfo.Args[2] + ' - ' + AFunInfo.Args[1] + ')';     end;     Result := Copy(Result, 1, ABegin - 1) + sPttr + Copy(Result, AEnd + 1, Length(Result));   //  Result := ReplaceFunctionByNew(Result, ABegin, AEnd, AFunInfo, AFuncInfoNew);   end; end; function ConvertFunctions(ASQL: string): string; begin   Result := ReplaceSameArgsFunctions(ASQL, 'isnull', 'NVL');   Result := ReplaceSameArgsFunctions(Result, 'substring', 'SUBSTR');   //先替换标准写法的参数相同的函数,对于非标准写法,例如函数名和括号间有空格,后再调用专门的函数处理   if pos('len(', Result) > 0 then     Result := StringReplace(Result, 'len(', 'LENGTH(', [rfReplaceAll]);   if pos('getdate()', Result) > 0 then     Result := StringReplace(Result, 'getdate()', 'SYSTIMESTAMP', [rfReplaceAll]);   if pos('len', Result) > 0 then     Result := Convert_Len(Result);   if pos('getdate', Result) > 0 then     Result := Convert_GetDate(Result);   if pos('right', Result) > 0 then     Result := Convert_Right(Result);   if pos('left', Result) > 0 then     Result := Convert_Left(Result);   if pos('isnull', Result) > 0 then     Result := Convert_IsNull(Result);   if pos('substring', Result) > 0 then     Result := Convert_SubString(Result);   if pos('datediff', Result) > 0 then     Result := Convert_DateDiff(Result);   Result := ConvertFieldAlias(Result);   end; function ConvertSQLToOracle(ASQL: string): string; begin   Result := ReplaceCommons(LowerCase(ASQL)); //替换基本的字符      if pos(' top ', Result) > 0 then         //转换top N 子句     Result := ConvertTopNWord(Result);   Result := ConvertFunctions(Result);    //替换函数 end; end.

转换示例: select top 100  itemcode as Code, Name2 = Discription+'adfs',  Left(Right('dfsdf' + CodeBar,10), 6),  right('asdfads', 32) , len('adfa', 23),  DateDiff(day, GetDate(), D2 + 33) from  oitm where IsNull(ItemCode, '') LIke '343%' and ItemCode in  (Select  Code as Code2 From  (select Code From table2 as B) as #t1) Oracel: select   itemcode code, discription+'adfs' name2  ,  SUBSTR(SUBSTR('dfsdf' + codebar, -10,10), 1, 6),  SUBSTR('asdfads', -32, 32) , LENGTH('adfa', 23),  EXTRACT(day from  d2 + 33 -  SYSTIMESTAMP) from  oitm where ( NVL(itemcode, '') like '343%' and itemcode in  (select  code code2 from  (select code from table2 b) T_t1) ) And ROWNUM <= 100

上一篇:以后想从事数据库工作 请问有哪些方向 20qq00ys]
下一篇:default pool 已满,怎么解决?? 20yecell]

相关文章

相关评论