Oracle和SQLServer的语法区别SQL语言支持这一部分概述了Transact-SQL和PL/SQL语言语法之间的相同点和不同点,并给出转换策略。要将OracleDML语句和PL/SQL程序迁移到SQLServer时,请按下列步骤执行:1.验证所有SELECT、INSERT、UPDATE和DELETE语句的语法是有效的。进行任何必要的修改。2.把所有外部联接改为SQL-92标准外部联接语法。3.用相应SQLServer函数替代Oracle函数。4.检查所有的比较运算符。5.用“+”字符串串联运算符代替“||”字符串串联运算符。6.用Transact-SQL程序代替PL/SQL程序。7.把所有PL/SQL游标改为非游标SELECT语句或Transact-SQL游标。8.用Transact-SQL过程代替PL/SQL过程、函数和包。9.把PL/SQL触发器转换为Transact-SQL触发器。10.使用SETSHOWPLAN语句,优化查询性能。SELECT语句Oracle和MicrosoftSQLServer使用的SELECT语句语法类似。OracleMicrosoftSQLServerSELECT[/*+optimizer_hints*/][ALL|DISTINCT]select_list[FROM{table_name|view_name|select_statement}][WHEREclause][GROUPBYgroup_by_expression][HAVINGsearch_condition][STARTWITHUCONNECTBY][{UNION|UNIONALL|INTERSECT|MINUS}SELECTU][ORDERBYclause][FORUPDATE]SELECTselect_list[INTOnew_table_]FROMtable_source[WHEREsearch_condition][GROUPBY[ALL]group_by_expression[,Un][WITH{CUBE|ROLLUP}][HAVINGsearch_condition][ORDERBYorder_expression[ASC|DESC]]Inaddition:UNIONOperatorCOMPUTEClauseFORBROWSEClauseOPTIONClauseSQLServer不支持Oracle特定的基于开销的优化程序提示,它必须被删除。建议使用的技术是,使用SQLServer基于开销的优化程序。有关详细信息,请参见本章后面的“SQL语句优化”。SQLServer不支持Oracle的STARTWITHUCONNECTBY子句。在SQLServer中,可以创建完成相同任务的存储过程替代它。SQLServer不支持Oracle的INTERSECT和MINUS集合运算符。可使用SQLServerEXISTS和NOTEXISTS子句,实现相同的结果。在下面示例中,使用INTERSECT运算符,用于查找学生登记的所有课程的代码和名称。注意,EXISTS运算符是如何代替INTERSECT运算符的。返回的数据是相同的。OracleMicrosoftSQLServerSELECTCCODE,CNAMEFROMDEPT_ADMIN.CLASSINTERSECTSELECTC.CCODE,C.CNAMEFROMSTUDENT_ADMIN.GRADEG,DEPT_ADMIN.CLASSCWHEREC.CCODE=G.CCODESELECTCCODE,CNAMEFROMDEPT_ADMIN.CLASSCWHEREEXISTS(SELECT'X'FROMSTUDENT_ADMIN.GRADEGWHEREC.CCODE=G.CCODE)在此例中,使用MINUS运算符,查找那些没有任何学生登记的课程。OracleMicrosoftSQLServerSELECTCCODE,CNAMEFROMDEPT_ADMIN.CLASSMINUSSELECTC.CCODE,C.CNAMEFROMSTUDENT_ADMIN.GRADEG,DEPT_ADMIN.CLASSCWHEREC.CCODE=G.CCODESELECTCCODE,CNAMEFROMDEPT_ADMIN.CLASSCWHERENOTEXISTS(SELECT'X'FROMSTUDENT_ADMIN.GRADEGWHEREC.CCODE=G.CCODE)INSERT语句Oracle和MicrosoftSQLServer使用的INSERT语句语法类似。OracleMicrosoftSQLServerINSERTINTO{table_name|view_name|select_statement}[(column_list)]{values_list|select_statement}INSERT[INTO]{table_name[[AS]table_alias]WITH(table_hint_limited[Un])|view_name[[AS]table_alias]|rowset_function_limited}{[(column_list)]{VALUES({DEFAULT|NULL|expression}[,Un])|derived_table|execute_statement}}|DEFAULTVALUESTransact-SQL语言支持对表和视图的插入,但不支持对SELECT语句的INSERT操作。如果Oracle应用程序代码执行对SELECT语句的插入操作,则必须对它进行修改。OracleMicrosoftSQLServerINSERTINTO(SELECTSSN,CCODE,GRADEFROMGRADE)VALUES('111111111','1111',NULL)INSERTINTOGRADE(SSN,CCODE,GRADE)VALUES('111111111','1111',NULL)Transact-SQLvalues_list参数提供了SQL-92标准关键字DEFAULT,但Oracle不支持。此关键字指定了,执行插入操作时使用列的默认值。如果指定列的默认值不存在,则插入NULL。如果该列不允许NULL,则返回一个错误消息。如果该列数据类型定义为timestamp,则插入下一个有序值。标识符列不能使用DEFAULT关键字。要生成下一个序列号,拥有IDENTITY属性的列不能列在column_list或values_clause中。不需使用DEFAULT关键字,来获取列的默认值。正如在Oracle中,如果列没有在column_list中引用,并且它有默认值,则默认值存放在列中。这是迁移时可使用的最兼容的方法。一个有用的Transact_SQL选项(EXECuteprocedure_name)是,执行一个过程并将其结果用管道输出到目标表或视图中。Oracle不允许这样做。UPDATE语句因为TransactSQL支持OracleUPDATE命令使用的绝大多数语法,所以只需要极少的修改。OracleMicrosoftSQLServerUPDATE{table_name|view_name|UPDATE{select_statement}SET[column_name(s)={constant_value|expression|select_statement|column_list|variable_list]{where_statement}table_name[[AS]table_alias]WITH(table_hint_limited[Un])view_name[[AS]table_alias]|rowset_function_limited}SET{column_name={expression|DEFAULT|NULL}|@variable=expression|@variable=column=expression}[,Un]{{[FROM{table_source}[,Un]][WHEREsearch_condition]}|[WHERECURRENTOF{{[GLOBAL]cursor_name}|cursor_variable_name}]}[OPTION(query_hint[,Un])]Transact-SQLUPDATE语句不支持对SELECT语句的更新操作。如果Oracle应用程序代码对SELECT语句进行更新,则可以把SELECT语句转换成一个视图,然后在SQLServerUPDATE语句中使用该视图名称。请参见前面“INSERT语句”中的示例。OracleUPDATE命令只能使用一个PL/SQL块中的程序变量。要使用变量,Transact-SQL语言并不需要使用块。OracleMicrosoftSQLServerDECLAREVAR1NUMBER(10,2);BEGINVAR1:=2500;UPDATESTUDENT_ADMIN.STUDENTSETTUITION_TOTAL=VAR1;END;DECLARE@VAR1NUMERIC(10,2)SELECT@VAR1=2500UPDATESTUDENT_ADMIN.STUDENTSETTUITION_TOTAL=@VAR1在SQLServer中,DEFAULT关键字可用于将一列设为其默认值。但不能使用OracleUPDATE命令,将一列设为默认值。Transact-SQL和OracleSQL均支持在UPDATE语句中使用子查询。但是,Transact-SQLFROM子句可用来创建一个基于联接的UPDATE。这一功能使UPDATE语法可读性更好,在某些情况下还能改善性能。OracleMicrosoftSQLServerUPDATESTUDENT_ADMIN.STUDENTSSETTUITION_TOTAL=1500WHERESSNIN(SELECTSSNFROMGRADEGWHEREG.SSN=S.SSNANDG.CCODE='1234')Subquery:UPDATESTUDENT_ADMIN.STUDENTSSETTUITION_TOTAL=1500WHERESSNIN(SELECTSSNFROMGRADEGWHEREG.SSN=S.SSNANDG.CCODE='1234')FROMclause:UPDATESTUDENT_ADMIN.STUDENTSSETTUITION_TOTAL=1500FROMGRADEGWHERES.SSN=G.SSNANDG.CCODE='1234'DELETE语句在大多数情况下,不需要修改DELETE语句。如果要对Oracle中的SELECT语句执行删除操作,则必须修改SQLServer语法,因为Transact-SQL不支持这一功能。Transact-SQL支持在WHERE子句中使用子查询,以及在FROM子句中使用联接。后者可产生更有效的语句。请参见前面“UPDATE语句”中的示例。OracleMicrosoftSQLServerDELETE[FROM]{table_name|view_name|select_statement}[WHEREclause]DELETE[FROM]{table_name[[AS]table_alias]WITH(table_hint_limited[Un])|view_name[[AS]table_alias]|rowset_function_limited}[FROM{table_source}[,Un]][WHERE{search_condition|{[CURRENTOF{{[GLOBAL]cursor_name}cursor_variable_name}]}][OPTION(query_hint[,Un])]TRUNCATETABLE语句Oracle和Microso