SnowConvert AI - Top-Level Code Units Report

什么是顶级代码单元?

顾名思义,代码单元是最基础、可独立执行的最小元素。在大多数情况下,这些单元是语句,但它们也包括脚本文件,因为它们是作为单个元素执行。

一些代码单元可以嵌套在其他代码单元中。在代码单元层级结构中,当某个代码单元上方不存在其他上级单元时,该单元即被称为顶级代码单元

什么是超出范围的顶级代码单元?

Out-of-scope Top-Level Code Units are Code Units that are out of the conversion scope of SnowConvert AI. Because of this, these code units are not considered when calculating the conversion rate. Each of these code units will not have a conversion rate (it will appear as N/A).

如果输入代码仅包含超出范围的代码单元,则整个迁移的代码行转换率将为 0%。

以下 CREATE TRIGGER 被视为超出范围的代码单元。

CREATE OR REPLACE TRIGGER my_trigger
    AFTER 
    UPDATE
    ON my_table
    FOR EACH ROW
BEGIN
   NULL;
END;
Copy

顶级代码单元示例

在下一部分中,我们可以看到一些顶级代码单元的示例。

查询

在以下示例中,我们这里有一个 SELECT 语句。此语句是单个顶级代码单元。

SELECT * FROM table1;
Copy

在此示例中,我们有一个嵌套的 SELECT 语句嵌套在另一个 SELECT 语句中。整个查询算作单个顶级代码单元。

SELECT * FROM (SELECT * FROM table1);
Copy

对象

使用 DDL 创建的对象算作单个顶级代码单元,即使它内部包含其他代码单元也是如此。

以下语句使用查询创建视图。在这种情况下,整个 CREATE VIEW 算作单个顶级代码单元。

CREATE VIEW view1 AS SELECT * FROM table1;
Copy

以下 CREATE PROCEDURE 语句算作单个顶级代码单元,即使它内部包含多个语句也是如此。

CREATE PROCEDURE procedure1
AS
BEGIN
    DELETE FROM table1;
END;
Copy

命令

SQL 文件中的独立命令被视为顶级代码单元。

一个 COMMIT 语句算作单个顶级代码单元。

COMMIT;
Copy

Oracle 中的包体

一个包可以在其主体内定义多个元素。包体被视为顶级代码单元,因为如果不创建整个包体,就无法单独创建这些元素。包体内的元素或代码单元将不算作顶级代码单元。

以下代码将报告为单个 CREATE PACKAGE BODY 代码单元。

CREATE PACKAGE package_body1 IS
    FUNCTION function1
    RETURN VARCHAR
    IS
    BEGIN
        RETURN 'HELLO'';
    END;
END;
Copy

Teradata 脚本文件

BTEQ 或 TPUMP 之类的 Teradata 脚本文件作为独立的代码单元执行。因此,整个文件被视为单个顶级代码单元。这些文件内其他可能的代码单元将不算作顶级代码单元。

以下 BTEQ 脚本文件将作为单个 BTEQ 顶级代码单元进行报告。

.LOGON e/fml,notebook
.COMPILE FILE = example.spl;
COMMIT;
CALL samplesp1 (8888, pAmount);
.LOGOFF
Copy

包含 GOTO 的 Transact SQL 批处理

Transact-SQL 的每条语句都可以独立执行。在大多数情况下,这些语句各个都被视为顶级代码单元。但是,当某个批处理包含指向同一批处理内标签的 GOTO 语句时,必须确保这些语句能正确运行,否则它们将无法独立执行。因此,包含 GOTO 语句的批处理中的各语句将不被视为顶级代码单元,只有整个批处理才算作一个单元。

以下代码示例将作为单个 GOTO/LABEL 代码单元进行报告:

DECLARE @Counter int;  
SET @Counter = 1;  
WHILE @Counter < 10  
BEGIN   
    SELECT @Counter  
    SET @Counter = @Counter + 1  
    IF @Counter = 4 GOTO Branch_One
    IF @Counter = 5 GOTO Branch_Two  
END  
Branch_One:  
    SELECT 'Jumping To Branch One.'  
    GOTO Branch_Three;
Branch_Two:  
    SELECT 'Jumping To Branch Two.'  
Branch_Three:  
    SELECT 'Jumping To Branch Three.';
GO
Copy

在其他报告中,代码单元方法论是如何体现的?

其他报告中也介绍了代码单元方法论。本部分说明这些值如何显示,或者如何与其他报告相关。

问题报告

issues-report.md

问题报告的每一行都有关于受问题影响的代码单元的一些信息。与代码单元相关的列如下:

  • 代码单元数据库: 这是发现问题的顶级代码单元所在的数据库。它仅适用于作为对象的代码单元。

  • 代码单元架构: 这是发现问题的顶级代码单元所在的架构。它仅适用于作为对象的代码单元。

  • 代码单元包: 这是发现问题的顶级代码单元所在的包。它仅适用于作为对象的代码单元。

  • 代码单元名称: 这是发现问题的顶级代码单元的名称。它仅适用于命名代码单元,例如对象。此名称不由数据库、架构或包限定。

  • 代码单元 ID: 这是发现问题的顶级代码单元的 ID。该名称是限定名称,将为具有重复名称的代码单元添加一个数字。

  • 代码单元: 这是发现问题的顶级代码单元的类型。

  • 代码单元大小: 这是发现问题的顶级代码单元的大小。

对象引用报告和缺失对象报告

object-references-report.md

missing-objects-report.md

对象引用报告的每一行都包含有关引用另一个元素的顶级代码单元的信息。这些引用的元素可能不是顶级元素,因此这些其他值可能不包含在顶级代码单元报告中。

与对象引用报告类似,缺失对象报告包含有关顶级代码单元的信息,该代码单元引用了代码中找不到的元素。

  • 调用方代码单元: 这是引用另一个元素的顶级代码单元的类型。

  • 调用方代码单元数据库: 这是引用另一个元素的顶级代码单元的数据库。

  • 调用方代码单元架构: 这是引用另一个元素的顶级代码单元的架构。

  • 调用方代码单元名称: 这是引用另一个元素的顶级代码单元的名称。

  • 调用方代码单元全名: 这是引用另一个元素的顶级代码单元的全名。

顶级代码单元报告中的信息

描述

分区密钥

转换的唯一标识符。

文件类型

代码单元所在文件的类型。(SQL、BTEQ 等)

类别

每个代码单元所属的更广泛的类或类型。

代码单元

此元素所属的代码单元的类型。

Source Database

The database where the source code unit is located.

Source Schema

The schema where the source code unit is located.

Source Name

The original name of the source code unit as it appears in the source system.

Code Unit Id

The unique identifier of the Code Unit with qualified name and numbering for code units with repeated names.

文件名

对象所在文件的名称。使用从输入目录开始的相对路径。

行号

代码单元所在文件内的行号。

代码行数

代码单元的总代码行数。

EWI 计数

代码单元内找到的 EWIs 的数量。您可以 在此处 了解有关 EWIs 的更多信息。

FDM 计数

代码单元内找到的 FDMs 的数量。您可以 在此处 了解有关 FDMs 的更多信息。

PRF 计数

The amount of PRFs found within the code unit. You can learn more about PRFs here.

最高 EWI 严重性

<p>代码单元中存在的最高 EWI 严重性。<br>严重性顺序如下:</p><ul><li>N/A(如果没有任何 EWIs)</li><li>低</li><li>中等</li><li>高</li><li>严重</li></ul>

已使用的 UDFs

代码单元中所有用户定义函数的名称。如果有多个 UDFs,则使用管道分隔所使用的 UDF 的名称。

EWI

在代码单元中找到的所有 EWIs 的代码。这些代码由管道分隔,不包含重复的代码。

FDM

在代码单元中找到的所有 FDMs 的代码。这些代码由管道分隔,不包含重复的代码。

PRF

在代码单元中找到的所有 PRFs 的代码。这些代码由管道分隔,不包含重复的代码。

转换状态

<p>代码单元转换的最终状态。</p><p>可能的转换状态为:</p><ul><li>NotSupported:当代码单元的转化率为 0% 时。</li><li>部分:当代码单元的转换率介于 0% 和 100% 之间时。</li><li>成功:当代码单位转换率为 100% 时。</li></ul>

LoC 转换百分比

转换百分比基于代码行。一行代码可能有支持和不支持的片段,具体取决于输入代码的格式化方式。在这些情况下,整行都被视为不支持。

Deployment Order

The deployment order is the topological level of each code unit based on its dependencies. It shows the right order in which the code units should be deployed to avoid missing dependencies during the deployment phase.

Language

The programming language or SQL dialect of the source code unit.

示例

假设 ORACLE SQL 中的以下 CREATE TABLE 位于其名为 table_example.sql 的文件中。

CREATE TABLE my_table (
  my_column DATE DEFAULT TO_DATE(CURRENT_DATE, 'J'),
  NOT A VALID COLUMN
);
Copy
CREATE OR REPLACE TABLE my_table (
   my_column TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/ DEFAULT PUBLIC.JULIAN_TO_GREGORIAN_DATE_UDF(CURRENT_DATE(), 'J')
--                                                                                                                                                                          ,
-- ** SSC-EWI-0001 - UNRECOGNIZED TOKEN ON LINE '3' COLUMN '3' OF THE SOURCE CODE STARTING AT 'NOT'. EXPECTED 'Column Definition' GRAMMAR. LAST MATCHING TOKEN WAS ',' ON LINE '2' COLUMN '52'. FAILED TOKEN WAS 'NOT' ON LINE '3' COLUMN '3'. CODE '15'. **
--  NOT A VALID COLUMN
 )
 COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
 ;
Copy

顶级代码单元报告将包含前面显示的表的单个条目。

以下是将在此 CREATE TABLE 语句的条目中报告的所有值:

  • 分区键 值将取决于迁移,因此此处的值会有所不同。

  • 文件类型 将是 SQL,因为它是在扩展名为 .sql 的文件上迁移的。

  • 类别 将是 TABLE,因为 CREATE TABLE 语句是 TABLE 代码单元类别的一部分。

  • 代码单元 本身将是 CREATE TABLE

  • 找到此代码单元的 文件名 将是 table_example.sql。

  • 假设 CREATE TABLE 语句位于文件的开头,则 行号 将为 1。

  • 代码行数 的数字将为 4。

  • EWI 计数 列将报告 1,因为输出代码有一个解析 EWI。

  • FDM 计数 列将报告 1,因为输出代码存在与数据类型相关的 FDM 问题。

  • PRF 计数 将报告 0,因为输出代码中不存在 PRF 问题。

  • 在这种情况下,最高 EWI 严重性 将为“严重”,因为这是示例解析 EWI 的严重性。另一个的严重性为“低”。

  • 使用的 UDFs 列将是 JULIAN_TO_GREGORIAN_DATE_UDF,因为此自定义的用户定义函数已添加,以转换输入代码的 TO_DATE 函数。

  • EWI 列将报告“SSC-EWI-0001”,因为这是输出代码中添加的 EWIs 之一。

  • ** FDM ** 列将报告“SSC-FDM-OR0042”,因为这是输出代码中添加的 FDMs 之一。

  • PRF 列将报告“不适用”,因为输出代码中不存在 PRF 问题。

  • 转换状态 将为“部分”,因为如果没有 EWIs,该代码单元中只有部分片段能够迁移。

  • LoC 转换百分比 为 50%,因为在 4 行中,只有 2 行成功转换。

Deployment Order

The deployment order column represents the correct order to deploy each code unit into Snowflake.

The following code exemplifies in depth how the deployment order is calculated.

CREATE TABLE TABLE1 ( -- level 0, no dependencies
   COL1 INT
);

CREATE TABLE TABLE2 ( -- level 0, no dependencies
   COL1 INT
);

CREATE VIEW VIEW1 -- level 4, depends on level-3 objects
AS SELECT * FROM VIEW2, VIEW3;

CREATE VIEW VIEW2 -- level 3, depends on level-2 objects
AS SELECT * FROM VIEW4, VIEW5, VIEW3;

CREATE VIEW VIEW4 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE1, TABLE2;

CREATE VIEW VIEW5 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE1;

CREATE VIEW VIEW3 -- level 2, depends on level-1 objects
AS SELECT * FROM VIEW6;

CREATE VIEW VIEW6 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE2;
Copy

The deployment order starts with 0, so code units without any dependencies will start at this level. In the example above, TABLE1 and TABLE2 will have a level 0 .

For the next level, we will focus on code units that depend on code units of level 0. VIEW4, VIEW5, and VIEW6 depend directly on TABLE1 and TABLE2, so their level will be 1.

After identifying all the code units of level 1 , we will focus on code units of level 2. In that particular scenario, just VIEW3 depends on VIEW6 , so VIEW3 will be level 2.

Once we identify all code units of level 2, we will focus on level 3. In the example above, VIEW2 depends on VIEW4, VIEW5 and VIEW3, however, the highest dependency level is 2, so, VIEW2 will be of level 3.

Finally, we got VIEW1, which depends on VIEW2 and VIEW3. Since VIEW2 is the dependency with higher level, VIEW1 will get level 4.

After making all the calculations, the top-level code units report will look something like the following table.

Code Unit Id

Deployment Order

VIEW1

4

VIEW2

3

VIEW3

2

VIEW4

1

VIEW5

1

VIEW6

1

TABLE1

0

TABLE2

0

Limitations

There are some scenarios where the deployment order may not calculate the right level for a specific code unit.

Code Units with Missing Dependencies

Deployment of code units that depend (directly or indirectly) on missing objects is not possible. Although SnowConvert AI calculates the deployment order as best it can, a missing dependency will cause deployment errors. For code units with missing dependencies, SnowConvert AI adds an asterisk (*) alongside the deployment order. E.g.

CREATE TABLE TABLE1 ( -- level 0, no dependencies
  COL1 INT
);

CREATE VIEW VIEW1 -- level 1*, depends on level-0 objects and has a missing dependency
AS SELECT * FROM TABLE1, TABLE2;

CREATE VIEW VIEW2 -- level 2*, depends on level-1* objects 
AS SELECT * FROM VIEW1;
Copy

The example above shows VIEW1 referencing a missing TABLE2 and VIEW2 referencing ,VIEW1 which indirectly refers TABLE2 . VIEW1 has a direct missing reference and VIEW2 an indirect missing reference. The top-level code units report will look something like the following table.

Code Unit Id

Deployment Order

TABLE1

0

VIEW1

1*

VIEW2

2*

Code Units referencing DDLs defined inside Stored Procedures, Anonymous Blocks, etc

In some scenarios, the deployment order may not be correct because the referenced element was defined inside another code unit. E.g.

CREATE TABLE TABLE1 (
  COL1 INT
);

CREATE OR REPLACE PROCEDURE PROC1 (param1 NUMBER)
IS
BEGIN
    CREATE VIEW VIEW1 
    AS
    SELECT * FROM TABLE1;
END;

CREATE VIEW VIEW2
AS SELECT * FROM VIEW1;
Copy

In the code above, VIEW2 references VIEW1, which will be created after executing the stored procedure. VIEW1 references TABLE1, so the procedure should be executed after creating the table. In that particular scenario, VIEW1 will not be included in the top-level code units report since it is contained by the stored procedure. In that case, for VIEW2 is not possible to know that VIEW1 depends on PROC1 to be created, and the deployment order may not be correct because of that. The following table shows the deployment order for the code above.

Code Unit Id

Deployment Order

TABLE1

0

PROC1

1

VIEW2

1

Despite VIEW1 and PROC1 having the same deployment order, VIEW1 will fail if the procedure was not executed first.

警告

Deployment Order support for Sequences is going to be delivered in a future version. By default, Code Units referencing sequences are not considering them to calculate the deployment order.

语言: 中文