将Oracle存储过程转换为SQL Server过程

时间:2018-07-30 05:57:04

标签: sql-server oracle stored-procedures

我已经在oracle中创建了一个存储过程。现在,我需要将相同的过程转换为SQL Server过程。由于我不擅长SQL过程,请帮助我。

以下是Oracle过程:

    create or replace
PROCEDURE "FTSREMOVESPECIALCHAR"
  AS strquery     VARCHAR2(4000 byte); 
  stmt         VARCHAR2(1000); 
  l_cursor     SYS_REFCURSOR; 
  TYPE result_rec IS RECORD (iid NUMBER(10, 0), 
    fulltextdetails VARCHAR2(4000 byte), 
    regex VARCHAR2(4000 byte)); 
  l_result_rec RESULT_REC; 
  idValue NUMBER(10, 0);
  fulltextdetailsValue VARCHAR2(4000 byte);
  fulltextWithoutSplChr VARCHAR2(4000 byte);
  regexValue VARCHAR2(4000 byte);
  minmatchValue NUMBER(10, 0);
  strQueryinsert  VARCHAR2(4000 byte);
BEGIN
     dbms_output.ENABLE(1000000);
    FOR c IN (SELECT table_name 
              FROM   user_tables 
              WHERE  table_name LIKE 'FULLTEXTLOOKTABLE_%')            
    LOOP 
        dbms_output.Put_line(c.table_name); 
        strquery := 'select ID, FullTextDetails, Regex  from ' || c.table_name; 
        BEGIN 
            OPEN l_cursor FOR strquery; 
            LOOP 
                FETCH l_cursor INTO l_result_rec;
                Exit when l_cursor%NOTFOUND;
                fulltextdetailsValue := l_result_rec.fulltextdetails;
                regexValue := l_result_rec.regex;

                dbms_output.Put_line('Before :' ||fulltextdetailsValue);
                fulltextdetailsValue := regexp_replace(fulltextdetailsValue, '[^[:alnum:] ]', NULL);
                dbms_output.Put_line('After : '||fulltextdetailsValue);
                dbms_output.Put_line('Before regexValue:' ||regexValue);
                regexValue := replace(regexValue, '([\~\-])', '([\~\-])?');
                regexValue := replace(regexValue, '(\!)', '(\!)?');
                regexValue := replace(regexValue, '([\@])', '([\@])?');
                regexValue := replace(regexValue, '(\#)', '(\#)?');
                regexValue := replace(regexValue, '([\$s\&])', '([\$s\&])?');
                regexValue := replace(regexValue, '(\%)', '(\%)?');
                regexValue := replace(regexValue, '(\^)', '(\^)?');
                regexValue := replace(regexValue, Q'[']',Q'['']');

                strQueryinsert := 'update '||c.table_name||' set fulltextdetails='''||fulltextdetailsValue||''' where id='||l_result_rec.iid;
                dbms_output.Put_line('strQueryinsert : ' ||strQueryinsert);
                EXECUTE IMMEDIATE
                strQueryinsert;

                strQueryinsert := 'update '||c.table_name||' set regex='''||regexValue||''' where id='||l_result_rec.iid;
                EXECUTE IMMEDIATE
                strQueryinsert;               
            END LOOP;
            EXECUTE IMMEDIATE
            'commit';
            close l_cursor;
        END; 
    END LOOP; 
END;

此过程将从数据库中以"FULLTEXTLOOKTABLE_"开头的所有表中获取数据。该表有4个columns(ID(int), FullTextDetails(nvarchar), Regex(nvarchar), MinMatchCount(int))。对于每个表,它将采用"FullTextDetails"列的值,并删除所有特殊字符,并采用

"Regex" and replace
([\~\-]) with ([\~\-])?
(\!) with (\!)?
([\@]) with ([\@])?
(\#) with (\#)?
([\$s\&]) with ([\$s\&])?
(\%) with (\%)?
(\^) with (\^)?

并使用新值更新列"FullTextDetails" and "Regex"。最后,更改被提交。

1 个答案:

答案 0 :(得分:1)

这里最困难的事情是如何处理正则表达式替换,因为T-SQL中没有这样的内置函数。幸运的是,您可以实现诸如使用SQL CLR集成显示here的方式-基本上,您可以编写.net对象,将它们映射到SQL对象并使用它们。您需要付出一些努力,但这是唯一的机会。

然后,其他事情非常简单。从这个系统对象中,您可以获取并遍历表名:

SELECT *
FROM [sys].[tables];

您可以使用cursor,但我更喜欢跳过它们。会是这样的:

DECLARE @Tables TABLE
(
    [name] SYSNAME
);

DECLARE @CurrentTableName SYSNAME;

INSERT INTO @Tables ([name])
SELECT [name]
FROM [sys].[tables]
--WHERE [name] LIKE 'FULLTEXTLOOKTABLE_%';

WHILE EXISTS(SELECT 1 FROM @Tables)
BEGIN;

    SELECT TOP 1 @CurrentTableName = [name]
    FROM @Tables;

    SELECT @CurrentTableName;

    DELETE FROM @Tables
    WHERE [name] = @CurrentTableName;

END;

对于构建和执行动态T-SQL语句,您有两个选择。您可以构建整个语句并为每个循环执行它,如下所示:

DECLARE @DynamicTSQLStatement NVARCHAR(MAX);

SET @DynamicTSQLStatement = N'UPDATE [dbo].[table] SET [text] = ''test'' WHERE [ID] = 1';

EXEC sp_executesql @DynamicTSQLStatement; 

或者您可以将sp_executesqlparameters一起使用,并创建一个模板,其中填充了当前值。

我希望这一点足以应付任务。