使用 YAML 轉換 SQL 翻譯

本文說明如何使用 YAML 設定檔,在將 SQL 程式碼遷移至 BigQuery 時轉換該程式碼。本指南說明如何建立自己的設定 YAML 檔案,並提供這項功能支援的各種翻譯轉換範例。

使用 BigQuery 互動式 SQL 翻譯器、BigQuery Migration API 或執行批次 SQL 翻譯時,您可以提供 YAML 設定檔來修改 SQL 查詢翻譯。使用 YAML 設定檔,即可進一步自訂來源資料庫的 SQL 查詢轉譯作業。

您可以透過下列方式,指定要在 SQL 轉譯中使用的設定 YAML 檔案:

互動式 SQL 翻譯器、BigQuery Migration API 和批次 SQL 翻譯器,都支援在單一翻譯工作中使用多個 YAML 設定檔。詳情請參閱「套用多個 YAML 設定」。

設定 YAML 檔案規定

建立 YAML 設定檔前,請先詳閱下列資訊,確保 YAML 檔案與 BigQuery 遷移服務相容:

  • 您必須將設定 YAML 檔案上傳至 Cloud Storage bucket 的目錄,其中包含 SQL 轉譯輸入檔案。如要瞭解如何建立 bucket 並將檔案上傳至 Cloud Storage,請參閱「建立 bucket」和「從檔案系統上傳物件」。
  • 單一設定 YAML 檔案的大小不得超過 1 MB。
  • 單一 SQL 翻譯工作中使用的所有設定 YAML 檔案,總大小不得超過 4 MB。
  • 如果您使用 regex 語法進行名稱比對,請使用 RE2/J。
  • 所有設定 YAML 檔案名稱都必須包含 .config.yaml 副檔名,例如 change-case.config.yaml。config.yaml 不是有效的設定檔名稱。

建立 YAML 設定檔的操作說明

本節提供建立設定 YAML 檔案的一般指南:

每個設定檔都必須包含指定設定類型的標頭。object_rewriter 類型用於在設定 YAML 檔案中指定 SQL 翻譯。以下範例使用 object_rewriter 類型轉換名稱大小寫:

type: object_rewriter
global:
  case:
    all: UPPERCASE

實體選取

如要執行實體專屬轉換,請在設定檔中指定實體。所有 match 屬性皆為選用,請只使用轉換所需的 match 屬性。下列設定 YAML 會公開要比對的屬性,以便選取特定實體:

match:
  database: <literal_name>
  schema: <literal_name>
  relation: <literal_name>
  attribute: <literal_name>
  databaseRegex: <regex>
  schemaRegex: <regex>
  relationRegex: <regex>
  attributeRegex: <regex>

各項 match 屬性的說明:

  • database 或 db:project_id 元件。
  • schema:資料集元件。
  • relation:表格元件。
  • attribute:資料欄元件。僅適用於屬性選取
  • databaseRegex 或 dbRegex:使用規則運算式比對 database 屬性 (預先發布版)。
  • schemaRegex:比對 schema 屬性與規則運算式 (預先發布版)。
  • relationRegex:使用規則運算式比對 relation 屬性 (預先發布版)。
  • attributeRegex:使用規則運算式比對 attribute 屬性。僅適用於屬性選取 (預先發布版)。

舉例來說,下列設定 YAML 會指定 match 屬性,選取 testdb.acme.employee 資料表進行臨時資料表轉換。

type: object_rewriter
relation:
-
  match:
    database: testdb
    schema: acme
    relation: employee
  temporary: true

您可以使用 databaseRegex、schemaRegex、relationRegex 和 attributeRegex 屬性指定規則運算式,選取實體子集。以下範例會將 testdb 中 tmp_schema 架構的所有關係變更為暫時關係,只要名稱開頭為 tmp_ 即可:

type: object_rewriter
relation:
-
  match:
    schema: tmp_schema
    relationRegex: "tmp_.*"
  temporary: true

常值和 regex 屬性都不區分大小寫。您可以使用 regex 搭配停用的 i 旗標,強制執行區分大小寫的比對,如以下範例所示:

match:
  relationRegex: "(?-i:<actual_regex>)"

您也可以使用等效的短字串語法,指定完整實體。短字串語法應包含 3 個 (用於選取關係) 或 4 個 (用於選取屬性) 名稱區段,並以點分隔,例如 testdb.acme.employee。接著,系統會將這些區隔解讀為分別以 database、schema、relation 和 attribute 傳遞。這表示名稱會逐字比對,因此簡短語法不允許使用規則運算式。以下範例說明如何使用短字串語法,在設定 YAML 檔案中指定完整實體:

type: object_rewriter
relation:
-
  match : "testdb.acme.employee"
  temporary: true

如果資料表名稱包含點號,則無法使用簡短語法指定名稱。在這種情況下,您必須使用物件比對。以下範例會將 testdb.acme.stg.employee 資料表變更為臨時資料表:

type: object_rewriter
relation:
-
  match:
    database: testdb
    schema: acme
    relation: stg.employee
  temporary: true

設定 YAML 接受 key 做為 match 的別名。

預設資料庫

部分輸入 SQL 方言 (尤其是 Teradata) 不支援在完整名稱中使用 database-name。在這種情況下,比對實體最簡單的方法是省略 match 中的 database 屬性。

不過,您可以設定 BigQuery Migration Service 的 default_database 屬性,並在 match 中使用該預設資料庫。

支援的目標屬性類型

您可以使用 YAML 設定檔執行屬性類型轉換,將資料欄的資料類型從來源類型轉換為目標類型。設定 YAML 檔案支援下列指定類型:

  • BOOLEAN
  • TINYINT
  • SMALLINT
  • INTEGER
  • BIGINT
  • FLOAT
  • DOUBLE
  • NUMERIC (支援選用的精確度和規模,例如 NUMERIC(18, 2))
  • TIME
  • TIMETZ
  • DATE
  • DATETIME
  • TIMESTAMP
  • TIMESTAMPTZ
  • CHAR (支援選用精確度,例如 CHAR(42))
  • VARCHAR (支援選用精確度,例如 VARCHAR(42))

設定 YAML 範例

本節提供範例,說明如何建立各種設定 YAML 檔案,以便與 SQL 翻譯搭配使用。每個範例都會列出 YAML 語法,說明如何以特定方式轉換 SQL 翻譯,並附上簡短說明。每個範例也提供 teradata-input.sql 或 hive-input.sql 檔案和 bq-output.sql 檔案的內容,方便您比較 YAML 設定對 BigQuery SQL 查詢翻譯的影響。

下列範例使用 Teradata 或 Apache Hive 做為輸入 SQL 方言,並使用 BigQuery SQL 做為輸出方言。下列範例也使用 testdb 做為預設資料庫,並使用 testschema 做為結構定義搜尋路徑。

變更物件名稱大小寫

下列設定 YAML 會變更物件名稱的大小寫:

type: object_rewriter
global:
  case:
    all: UPPERCASE
    database: LOWERCASE
    attribute: LOWERCASE

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table x(a int);
      select * from x;
    
bq-output.sql
      CREATE TABLE testdb.TESTSCHEMA.X
      (
        a INT64
      )
      ;
      SELECT
          X.a
        FROM
          testdb.TESTSCHEMA.X
      ;
    

將資料表設為臨時資料表

下列設定 YAML 會將一般資料表變更為臨時資料表:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    temporary: true

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int);
    
bq-output.sql
    CREATE TEMPORARY TABLE x
    (
      a INT64
    )
    ;
    

將資料表設為臨時

下列設定 YAML 會將一般資料表變更為臨時資料表,並在 60 秒後到期。

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    ephemeral:
      expireAfterSeconds: 60

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int);
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a INT64
    )
    OPTIONS(
      expiration_timestamp=timestamp_add(current_timestamp(), interval 60 SECOND)
    );
    

設定分區到期時間

下列設定 YAML 會將分區資料表的到期時間變更為 1 天:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    partitionLifetime:
      expireAfterSeconds: 86400

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int, b int) partition by (a);
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a INT64,
      b INT64
    )
    CLUSTER BY a
    OPTIONS(
      partition_expiration_days=1
    );
    

變更資料表的外部位置或格式

下列設定 YAML 會變更資料表的外部位置和格式:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    external:
      locations: "gs://path/to/department/files"
      format: ORC

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int);
    
bq-output.sql
    CREATE EXTERNAL TABLE testdb.testschema.x
    (
      a INT64
    )
    OPTIONS(
      format='ORC',
      uris=[
        'gs://path/to/department/files'
      ]
    );
    

設定或變更資料表說明

下列設定 YAML 會設定資料表的說明:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    description:
      text: "Example description."

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int);
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a INT64
    )
    OPTIONS(
      description='Example description.'
    );
    

設定或變更資料表分區

下列設定 YAML 會變更資料表的分區配置,以便依日期資料欄分區:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    partition:
      simple:
        add: [a]
  -
    match: "testdb.testschema.y"
    partition:
      simple:
        remove: [a]

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a date, b int);
    create table y(a date, b int) partition by (a);
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a DATE,
      b INT64
    )
    PARTITION BY a;
    CREATE TABLE testdb.testschema.y
    (
      a DATE,
      b INT64
    )
    ;
    

下列設定 YAML 會變更資料表的分區配置,依範圍 bucket 分區:

type: object_rewriter
relation:
-
  key: "testdb.testschema.mytable"
  partition:
    range_bucket:
      column: "id"
      start: 0
      end: 100
      step: 10
      options:
        require_partition_filter: "TRUE"

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

snowflake-input.sql
     create table testschema.mytable (date timestamp_ntz, id number, content variant);
    
bq-output.sql
     create table testdb.testschema.mytable
      (
        date datetime,
        id int64,
        content json
      )
      partition by range_bucket(id, generate_array(0, 100, 10))
      options(
        require_partition_filter=true
      );
    

設定或變更資料表分群

下列設定 YAML 會變更資料表的叢集配置:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    clustering:
      add: [a]
  -
    match: "testdb.testschema.y"
    clustering:
      remove: [b]

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

hive-input.sql
    create table x(a int, b int);
    create table y(a int, b int) clustered by (b) into 16 buckets;
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a INT64,
      b INT64
    )
    CLUSTER BY a;
    CREATE TABLE testdb.testschema.y
    (
      a INT64,
      b INT64
    )
    ;
    

變更資料欄屬性的類型

下列設定 YAML 會變更資料欄屬性的資料類型:

type: object_rewriter
attribute:
  -
    match:
      database: testdb
      schema: testschema
      attributeRegex: "a+"
    type:
      target: NUMERIC(10,2)

您可以將來源資料類型轉換為任何支援的目標屬性類型。

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
    create table x(a int, b int, aa int);
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
    (
      a NUMERIC(31, 2),
      b INT64,
      aa NUMERIC(31, 2)
    )
    ;
    

新增外部資料湖泊連線

下列設定 YAML 會將來源資料表標示為外部資料表,指向儲存在外部資料湖泊中的資料,並由資料湖泊連線指定。

type: object_rewriter
relation:
-
  key: "testdb.acme.employee"
  external:
    connection_id: "connection_test"

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

hive-input.sql
    CREATE TABLE x
    (
      a VARCHAR(150),
      b INT
    );
    
bq-output.sql
    CREATE EXTERNAL TABLE x
    (
      a STRING,
      b INT64
    )
    WITH CONNECTION `connection_test`
    OPTIONS(
    );
    

變更輸入檔案的字元編碼

根據預設,BigQuery 移轉服務會嘗試自動偵測輸入檔案的字元編碼。如果 BigQuery 移轉服務可能誤判檔案編碼,您可以使用 YAML 設定檔明確指定字元編碼。

下列設定 YAML 將輸入檔案的明確字元編碼指定為 ISO-8859-1。

type: experimental_input_formats
formats:
- source:
    pathGlob: "*.sql"
  contents:
    raw:
      charset: iso-8859-1

全域類型轉換

下列設定 YAML 會在所有指令碼中將資料類型變更為另一種,並指定要在轉譯指令碼中避免的來源資料類型。這與「變更資料欄屬性的類型」設定不同,後者只會變更單一屬性的資料類型。

BigQuery 支援下列資料類型轉換:

  • DATETIME 至 TIMESTAMP
  • TIMESTAMP到DATETIME (可選填時區)
  • TIMESTAMP WITH TIME ZONE到DATETIME (可選填時區)
  • CHAR 至 VARCHAR

在以下範例中,設定 YAML 會將 TIMESTAMP 資料類型轉換為 DATETIME。

type: experimental_object_rewriter
global:
  typeConvert:
    timestamp: DATETIME

設定預設時區

資料庫方言對不同的日期和時間相關資料類型,有不同的語意和名稱。無論輸入方言的資料類型名稱為何,翻譯服務都會在 YAML 設定中標準化下列術語:

  • datetime 是 Y-M-D H:M:S 的組合,不固定在任何特定時區。datetime 代表時鐘時間,而非特定時間點。
  • timestamp 代表特定或絕對時間點,因此會隱含固定在特定時區,這可能是工作階段層級或資料庫設定。
  • timestamptz 代表特定時間點,例如 timestamp,但與 timestamp 不同的是,它會帶有特定時區偏移。雖然 2019-06-01 12:00:00+4 和 2019-06-01 06:00:00-2 代表相同的時間點,但系統會將兩者視為不同的 timestamptz 值。

在 Teradata 等方言中,current_date、current_time 或 current_timestamp 等日期時間相關函式會根據隱含設定的工作階段時區參數傳回時間戳記。BigQuery 則一律會傳回世界標準時間 (UTC) 的時間戳記。為確保兩種方言的行為一致,可能需要相應設定時區。

如果來源資料庫的預設時區不是世界標準時間,建議您指定翻譯的預設時區。這樣可保留時區,確保翻譯後的查詢能正確運作。

在以下範例中,YAML 設定會將 TIMESTAMP 和 TIMESTAMPTZ 資料類型轉換為 DATETIME,並將目標時區設為 Europe/Paris。

如要瞭解有效的字串時區值,請參閱「時區」。

type: experimental_object_rewriter
global:
  typeConvert:
    timestamp:
      target: DATETIME
      timezone: Europe/Paris
    timestamptz:
      target: DATETIME
      timezone: Europe/Paris

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

snowflake-input.sql
      create table x(c_timestamp timestamp_ltz, c_timestamptz timestamp_tz, c_datetime timestamp_ntz);

      select c_timestamp from x where c_timestamp > current_timestamp(0);
      select c_timestamptz from x where c_timestamptz > cast(current_timestamp(0) as timestamp_tz);
      select c_datetime from x where c_datetime > cast(current_timestamp(0) as timestamp_ntz);
    
bq-output.sql
      CREATE TABLE x
      (
        c_timestamp DATETIME,
        c_timestamptz DATETIME,
        c_datetime DATETIME
      )
      ;
      SELECT
          x.c_timestamp
        FROM
          test.x
        WHERE x.c_timestamp > datetime(current_timestamp(), 'Europe/Paris')
      ;
      SELECT
          x.c_timestamptz
        FROM
          test.x
        WHERE x.c_timestamptz > datetime(current_timestamp(), 'Europe/Paris')
      ;
      SELECT
          x.c_datetime
        FROM
          test.x
        WHERE x.c_datetime > datetime(current_timestamp(), 'Europe/Paris')
      ;
    

在以下範例中,設定 YAML 會將 DATETIME 資料類型轉換為 TIMESTAMP。

根據預設,TIMESTAMPTZ 會轉換為 TIMESTAMP,不需設定。

type: experimental_object_rewriter
global:
  typeConvert:
    datetime:
      target: TIMESTAMP

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

snowflake-input.sql
      create table x(c_timestamp timestamp_ltz, c_timestamptz timestamp_tz, c_datetime timestamp_ntz);

      select c_timestamp from x where c_timestamp > current_timestamp(0);
      select c_timestamptz from x where c_timestamptz > cast(current_timestamp(0) as timestamp_tz);
      select c_datetime from x where c_datetime > cast(current_timestamp(0) as timestamp_ntz);
    
bq-output.sql
      CREATE TABLE x
      (
        c_timestamp TIMESTAMP,
        c_timestamptz TIMESTAMP,
        c_datetime TIMESTAMP
      )
      ;
      SELECT
          x.c_timestamp
        FROM
          test.x
        WHERE x.c_timestamp > current_timestamp()
      ;
      SELECT
          x.c_timestamptz
        FROM
          test.x
        WHERE x.c_timestamptz > current_timestamp()
      ;
      SELECT
          x.c_datetime
        FROM
          test.x
        WHERE x.c_datetime > current_timestamp()
      ;
    

選取對帳單修改

下列設定 YAML 會變更 SELECT 陳述式中的星號投影、GROUP BY 和 ORDER BY 子句。

starProjection 支援下列設定:

  • ALLOW
  • PRESERVE (預設)
  • EXPAND

groupBy 和 orderBy 支援下列設定:

  • EXPRESSION
  • ALIAS
  • INDEX

在以下範例中,設定 YAML 會將星號投影設為 EXPAND。

type: experimental_statement_rewriter
select:
  starProjection: EXPAND

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table x(a int, b TIMESTAMP);
      select * from x;
    
bq-output.sql
      CREATE TABLE x
      (
        a INT64,
        b DATETIME
      )
      ;
      SELECT
          x.a
          x.b
        FROM
          x
      ;
    

UDF 規格

在多數情況下,即使 UDF 主體是以外部語言編寫,BigQuery SQL 翻譯工具也能自動剖析外部 user-defined function (UDF) 的資料定義語言 (DDL),判斷其輸入和輸出資料類型。不過,對於某些來源方言,翻譯工具可能無法自動編譯 UDF 簽章。為確保參照這些 UDF 的 SQL 陳述式能準確翻譯,且不必提供原始 DDL,您可以使用 YAML 設定檔明確註冊 UDF 簽章。

下列設定 YAML 會指定來源指令碼中使用的 user-defined function (UDF) 簽章。與中繼資料 ZIP 檔案類似,UDF 定義有助於更準確地翻譯輸入指令碼。

type: metadata
udfs:
  - "date parse_short_date(dt int)"

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table x(dt int);
      select parse_short_date(dt) + 1 from x;
    
bq-output.sql
      CREATE TABLE x
      (
        dt INT64
      )
      ;
      SELECT
          date_add(parse_short_date(x.dt), interval 1 DAY)
        FROM
          x
      ;
    

設定小數位數嚴格程度

根據預設,BigQuery 遷移服務會將數值精確度提高至指定小數位數可用的最高精確度。下列設定 YAML 會將精確度嚴格程度設為保留來源陳述式的小數精確度,藉此覆寫這項行為。

type: experimental_statement_rewriter
common:
  decimalPrecision: STRICT

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table x(a decimal(3,0));
    
bq-output.sql
      CREATE TABLE x
      (
        a NUMERIC(3)
      )
      ;
    

設定字串精確度嚴格程度

根據預設,BigQuery 遷移服務在翻譯 CHAR 和 VARCHAR 資料欄時,會省略字串精確度。這有助於避免在寫入值時發生截斷錯誤。部分 SQL 方言 (例如 Teradata) 會截斷超過寫入時最大精確度的值,而 BigQuery 在這種情況下會傳回錯誤。

如果應用程式不依賴來源方言的截斷行為,請考慮在翻譯後的類型定義中保留資料欄的精確度。

下列設定 YAML 會覆寫這項行為,方法是設定精確度嚴格程度,保留來源陳述式的字串精確度。

type: experimental_statement_rewriter
common:
  stringPrecision: STRICT

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table x(a varchar(3));
    
bq-output.sql
      CREATE TABLE x
      (
        a STRING(3)
      )
      ;
    

輸出名稱對應

您可以使用設定 YAML 對應 SQL 物件名稱。您可以根據對應的物件,變更名稱的不同部分。

靜態名稱對應

使用靜態名稱對應,對應實體的名稱。如果只想變更名稱的特定部分,其他部分保持不變,則只需加入需要變更的部分。

下列設定 YAML 會將資料表名稱從 my_db.my_schema.my_table 變更為 my_new_db.my_schema.my_new_table。

type: experimental_object_rewriter
relation:
-
  match: "my_db.my_schema.my_table"
  outputName:
    database: "my_new_db"
    relation: "my_new_table"

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table my_db.my_schema.my_table(a int);
    
bq-output.sql
      CREATE TABLE my_new_db.my_schema.my_new_table
      (
        a INT64
      )
    

您可以使用靜態名稱對應,更新公開使用者定義函式中名稱使用的區域。

以下範例會將 bqutil.fn UDF 中的名稱,從使用預設的 us 多區域,變更為使用 europe_west2 區域:

type: experimental_object_rewriter
function:
-
  match:
    database: bqutil
    schema: fn
  outputName:
    database: bqutil
    schema: fn_europe_west2

動態名稱對應

使用動態名稱對應功能,可同時變更多個物件,並根據對應的物件建立新名稱。

下列設定 YAML 會將前置字串 stg_ 新增至屬於 staging 結構定義的資料表,然後將這些資料表移至 production 結構定義,藉此變更所有資料表的名稱。

type: experimental_object_rewriter
relation:
-
  match:
    schema: staging
  outputName:
    schema: production
    relation: "stg_${relation}"

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table staging.my_table(a int);
    
bq-output.sql
      CREATE TABLE production.stg_my_table
      (
        a INT64
      )
      ;
    

指定預設資料庫和結構定義搜尋路徑

下列設定 YAML 指定了預設資料庫和結構定義搜尋路徑。

type: environment
session:
  defaultDatabase: myproject
  schemaSearchPath: [myschema1, myschema2]

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      SELECT * FROM database.table
      SELECT * FROM table1
    
bq-output.sql
      SELECT * FROM myproject.database.table.
      SELECT * FROM myproject.myschema1.table1
    

設定 NLS_DATE_FORMAT

下列設定 YAML 會將 NLS_DATE_FORMAT 參數設為 DD/MM/YYYY 格式。建議您指定 NLS_DATE_FORMAT,以隱含方式使用日期格式和轉換。如未設定,系統會使用預設的翻譯格式 DD-MON-RR。

type: environment
session:
  dateFormat: DD/MM/YYYY

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

oracle-input.sql
    create table x(dt date default '31/12/1999');
    insert into x values ('01/01/2000');
    
bq-output.sql
    CREATE TABLE testdb.testschema.x
      (
        DT DATETIME DEFAULT DATETIME '1999-12-31 00:00:00'
      )
      ;
      INSERT INTO testdb.testschema.x (DT)
        VALUES (DATETIME '2000-01-01 00:00:00')
      ;
    

全域輸出名稱重寫

下列設定 YAML 會根據設定的規則,變更指令碼中所有物件 (資料庫、結構定義、關係和屬性) 的輸出名稱。

type: experimental_object_rewriter
global:
  outputName:
    regex:
      - match: '\s'
        replaceWith: '_'
      - match: '>='
        replaceWith: 'gte'
      - match: '^[^a-zA-Z_].*'
        replaceWith: '_$0'

使用這個設定 YAML 檔案的 SQL 轉譯可能如下所示:

teradata-input.sql
      create table "test special chars >= 12"("42eid" int, "custom column" varchar(10));
    
bq-output.sql
      CREATE TABLE test_special_chars_employees_gte_12
      (
        _42eid INT64,
        custom_column STRING
      )
      ;
    

最佳化及提升翻譯 SQL 的效能

您可以對翻譯後的 SQL 套用選用轉換,藉此導入可改善效能或成本的變更。這些最佳化措施完全取決於個案,應與未修改的 SQL 輸出進行評估,以評估其對效能的實際影響。

下列設定 YAML 會啟用選用轉換。設定接受最佳化清單,以及接受參數的最佳化,以及含有選用參數值的部分。

type: optimizer
transformations:
  - name: PRECOMPUTE_INDEPENDENT_SUBSELECTS
  - name: REWRITE_CTE_TO_TEMP_TABLE
    parameters:
      threshold: 1
最佳化 選用參數 說明
PRECOMPUTE_INDEPENDENT_SUBSELECTS scope: [PREDICATE, PROJECTION] 新增 DECLARE 陳述式來重寫查詢,將 PREDICATE 子句或 PROJECTION 中的運算式替換為預先計算的變數。這會被視為靜態述詞,可減少讀取的資料量。如果省略範圍,預設值為 PREDICATE (即 WHERE 和 JOIN-ON 子句)。

將純量子查詢擷取至 DECLARE 陳述式,會使原始述詞變成靜態,因此能改善執行計畫。這項最佳化作業會導入新的 SQL 陳述式。
REWRITE_CTE_TO_TEMP_TABLE threshold: N 如果對相同一般資料表運算式 (CTE) 的參照超過 N 個,則將 CTE 重新編寫為臨時資料表。這可降低查詢複雜度,並強制執行一般資料表運算式一次。如果省略 N,預設值為 4。

如果多次參照非一般 CTE,建議使用這項最佳化功能。 導入臨時資料表會產生額外負擔,可能比最終多次執行低複雜度或低基數 CTE 的負擔更大。這項最佳化作業會導入新的 SQL 陳述式。
REWRITE_ZERO_SCALE_NUMERIC_AS_INTEGER bigint: N 如果精確度在 N 內,則將零刻度 NUMERIC/BIGNUMERIC 屬性重寫為 INT64 類型。如果省略 N,預設值為 18。

如果來源方言沒有整數類型,建議您在翻譯時使用這項最佳化功能。變更資料欄類型時,必須檢查所有下游用途,確認類型相容性和語意變更。例如,分數除法變成整數除法,或程式碼預期數值。

Snowflake 翻譯預設會啟用這項最佳化功能,適用於精確度不超過 38 的零小數位數值。這項最佳化功能可確保 Snowflake INTEGER (在 Snowflake 中隱含表示為 NUMBER(38,0)) 會轉譯為 BigQuery INT64,而非 BIGNUMERIC(38)。

如果應用程式使用的數字精確度超過 18,建議您停用這項功能,確保 BigQuery 能處理應用程式所需的完整值範圍。
DROP_TEMP_TABLE 為指令碼中建立的所有暫存資料表新增 DROP TABLE 陳述式,且不會在指令碼結束時捨棄。這樣一來,臨時資料表的儲存空間計費週期就會從 24 小時縮短為指令碼執行時間。這項最佳化作業會導入新的 SQL 陳述式。

如果指令碼執行完畢後,不會再存取臨時資料表進行任何進一步處理,建議使用這項最佳化功能。這項最佳化作業會導入新的 SQL 陳述式。
REGEXP_CONTAINS_TO_LIKE 將部分類別的 REGEXP_CONTAINS 比對模式重寫為 LIKE 運算式。

如果沒有其他程序 (例如巨集替換) 依賴輸出 SQL 中保持不變的規則運算式模式常值,建議使用這項最佳化功能。
ADD_DISTINCT_TO_SUBQUERY_IN_SET_COMPARISON 將 DISTINCT 子句新增至子查詢,做為 [NOT] IN 運算子的值組合。

如果子查詢結果的基數 (不重複值的數量) 遠低於值的數量,建議使用這項最佳化功能。如果未滿足這項前提條件,這項轉換可能會對效能造成負面影響。
APPROXIMATE_RANGE_PARTITIONS 將非連續或非常規整數分區配置,轉換為 BigQuery 支援的連續等大小分區範圍,藉此近似這些配置。根據預設,這類分區配置不會影響翻譯 DDL 陳述式中的資料表分區配置。

如果來源資料表使用非連續分區函式 (例如 Teradata RANGE_N 函式),且 BigQuery 中大小相等的分區配置有助於提升效能,建議您使用這項最佳化功能。

最佳化示例

下列最佳化作業會將精確度小於或等於 38 的零小數位數數值類型,轉換為 BigQuery 中的 INT64。

# An INTEGER is internally represented as NUMBER(38,0) in Snowflake.
# To convert Snowflake INTEGER to INT64 in BigQuery, enable the rewrite for precision <= 38.
# Note that this can produce incorrect results if your application logic uses more than 18 digits of precision.
#
# This configuration is enabled by default for the Snowflake Dialect.
type: optimizer
transformations:
  - name: REWRITE_ZERO_SCALE_NUMERIC_AS_INTEGER
    parameters:
      bigint: 38

經過這項最佳化後,SQL 翻譯可能如下所示:

snowflake-input.sql
      CREATE TABLE numbers(i INTEGER, n NUMERIC(10,0));
    
bq-output.sql
      CREATE TABLE numbers(i INT64, n INT64);
    

下列設定會停用方言的最佳化功能,例如 Snowflake,預設為啟用。這項設定會根據輸入精確度,將數值類型轉換為 NUMERIC 或 BIGNUMERIC,而非預設的 INT64。

type: optimizer
transformations:
  - name: REWRITE_ZERO_SCALE_NUMERIC_AS_INTEGER
    enabled: false

經過這項最佳化後,SQL 翻譯可能如下所示:

snowflake-input.sql
      CREATE TABLE numbers(i INTEGER, n NUMERIC(10,0));
    
bq-output.sql
      CREATE TABLE numbers(i BIGNUMERIC(38), n NUMERIC(29));
    

建立以 Gemini 為基礎的設定 YAML 檔案

如要生成 AI 輸出內容,SQL 轉譯輸入內容的來源目錄必須包含設定 YAML 檔案。

需求條件

AI 輸出的設定 YAML 檔案必須有 .ai_config.yaml 後置字串。例如:rules_1.ai_config.yaml。

支援的欄位

您可以使用下列欄位設定 AI 翻譯輸出內容:

  • suggestion_type (選用):指定要生成的 AI 建議類型。支援的建議類型如下:
    • QUERY_CUSTOMIZATION (預設):根據設定 YAML 檔案中指定的轉譯規則,生成 SQL 程式碼的 AI 建議。
    • TRANSLATION_EXPLANATION:生成文字,其中包含翻譯後的 GoogleSQL 查詢摘要,以及來源 SQL 查詢與翻譯後的 GoogleSQL 查詢之間的差異和不一致之處。
  • rewrite_target (選用):如要將翻譯規則套用至輸入 SQL,請指定 SOURCE_SQL;如要將翻譯規則套用至輸出 SQL,請指定 TARGET_SQL (預設)。
  • instruction (選用):以自然語言描述目標 SQL 的變更。Gemini 強化版 SQL 翻譯會評估要求,並進行指定變更。
  • examples (選用):提供 SQL 範例,說明要如何修改 SQL 模式。

您可以視需要新增其他 translation_rules 和 examples。

範例

下列範例會建立 Gemini 專用的 YAML 設定檔,可用於 SQL 轉譯。

移除預設翻譯輸出查詢中的 upper 函式

translation_rules:
- instruction: "Remove upper() function"
  examples:
  - input: "upper(X)"
    output: "X"

建立多項翻譯規則,自訂翻譯輸出內容

translation_rules:
- instruction: "Remove upper() function"
  suggestion_type: QUERY_CUSTOMIZATION
  rewrite_target: TARGET_SQL
  examples:
  - input: "upper(X)"
    output: "X"
- instruction: "Insert a comment at the head that explains each statement in detail.
  suggestion_type: QUERY_CUSTOMIZATION
  rewrite_target: TARGET_SQL

從翻譯輸入查詢中移除 SQL 註解

translation_rules:
- instruction: "Remove all the sql comments in the input sql query."
  suggestion_type: QUERY_CUSTOMIZATION
  rewrite_target: SOURCE_SQL

使用預設 LLM 提示詞生成翻譯說明

這個範例使用翻譯服務提供的預設 LLM 提示,生成文字說明:

translation_rules:
- suggestion_type: "TRANSLATION_EXPLANATION"

使用您自己的自然語言提示生成翻譯說明

translation_rules:
- suggestion_type: "TRANSLATION_EXPLANATION"
  instruction: "Explain the syntax differences between the source Teradata query and the translated GoogleSQL query."

單一 YAML 設定檔中有多種建議類型

translation_rules:
- suggestion_type: "TRANSLATION_EXPLANATION"
  instruction: "Explain the syntax differences between the source Teradata query and the translated GoogleSQL query."
- instruction: "Remove upper() function"
  suggestion_type: QUERY_CUSTOMIZATION
  rewrite_target: TARGET_SQL
  examples:
  - input: "upper(X)"
    output: "X"
- instruction: "Remove all the sql comments in the input sql query."
  suggestion_type: QUERY_CUSTOMIZATION
  rewrite_target: SOURCE_SQL

套用多個 YAML 設定

在批次或互動式 SQL 翻譯中指定 YAML 設定檔時,您可以在單一翻譯工作中選取多個 YAML 設定檔,以反映多項轉換。如果多項設定發生衝突,其中一項轉換可能會覆寫另一項。建議您在每個檔案中使用不同類型的設定,以免在同一項翻譯工作中發生轉換衝突。

以下範例列出為單一 SQL 轉譯工作提供的兩個獨立設定 YAML 檔案,一個用於變更資料欄屬性,另一個用於將資料表設為暫時:

change-type-example.config.yaml:

type: object_rewriter
attribute:
  -
    match: "testdb.testschema.x.a"
    type:
      target: NUMERIC(10,2)

make-temp-example.config.yaml:

type: object_rewriter
relation:
  -
    match: "testdb.testschema.x"
    temporary: true

使用這兩個設定 YAML 檔案的 SQL 翻譯可能如下所示:

teradata-input.sql
    create table x(a int);
    
bq-output.sql
    CREATE TEMPORARY TABLE x
    (
      a NUMERIC(31, 2)
    )
    ;