【问题标题】:Converting Oracle Stored Procedure to SQL Server Procedure将 Oracle 存储过程转换为 SQL Server 过程
【发布时间】:2018-07-30 14:17:40
【问题描述】:

我在 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"。最后提交更改。

【问题讨论】:

    标签: sql-server oracle stored-procedures


    【解决方案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 一起使用,并创建一个填充了当前值的模板。

    我希望这些点足以处理任务。

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 2018-05-06
      • 2020-10-12
      • 2021-08-17
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2020-06-06
      • 2011-02-15
      相关资源
      最近更新 更多