DBMS_PIPE 套裝程式 (永久訊息管道)

DBMS_PIPE 套裝程式可讓相同執行處理中的兩個或多個階段作業進行通訊。

Oracle Autonomous Database on Dedicated Exadata Infrastructure 支援 Oracle Database 19c 提供的核心 DBMS_PIPE 功能,以及擴充功能。

請參閱 Oracle Database 19c PL/SQL Packages and Types Reference 中的 DBMS_PIPEOracle Database 23ai PL/SQL Packages and Types Reference ,瞭解 Oracle Database 中提供的核心 DBMS_PIPE 功能詳細資訊。

DBMS_PIPE 永久訊息傳遞管道簡介

管線功能具有數個潛在的應用程式:外部服務介面、除錯、獨立交易和警示。

Autonomous Database 上,DBMS_PIPE 套件具有擴充功能,可支援持續性訊息傳遞管道。請參閱 Oracle Database 19c PL/SQL Packages and Types Reference 中的 DBMS_PIPEOracle Database 23ai PL/SQL Packages and Types Reference ,瞭解詳細資訊。

DBMS_PIPE 中的持續性訊息:

  • 支援傳送及擷取非常大的訊息。

  • 支援大量管道訊息。

  • 支援在單一資料庫內、跨多個資料庫和不同區域的資料庫之間共用訊息。

  • 支援使用相同雲端物件存放區位置 URI 的多個管道。

    持續性訊息傳遞功能可讓兩個或多個資料庫階段作業與儲存在雲端物件存放區中的訊息進行通訊。在管路中使用此功能訊息只能供目前的資料庫使用,或者可以在同一區域或不同區域中使用這些訊息。

    「永久訊息管」可以是任何一種支援的 DBMS_PIPE 類型:

    • 隱含管:使用 DBMS_PIPE.SEND_MESSAGE 函數以不明的管路名稱傳送訊息時,會自動建立訊息。
    • 明確管線:使用 DBMS_PIPE.CREATE_PIPE 函數與使用者指定的管線名稱建立。
    • 公用管道:任何具備 DBMS_PIPE 套裝軟體 EXECUTE 權限的使用者均可存取。
    • 私人管道:具有與管道建立者相同之使用者的階段作業可存取。

附註:

使用持續性訊息在不同資料庫之間傳送與接收訊息時,Oracle 建議您先呼叫 DBMS_PIPE.CREATE_PIPE,再傳送或接收訊息。使用 DBMS_PIPE.CREATE_PIPE 建立明確的管道可確保建立具有您所要存取權限的管道 (透過將 PRIVATE 參數設定為 FALSE 或使用預設值 TRUE)。

DBMS_PIPE 限制

DBMS_PIPE 套裝軟體不支援在使用不同字元集的資料庫之間傳送訊息。例如,如果您有一個使用 AL32UTF8 的 Autonomous Database 執行處理,以及另一個使用 WE8MSWIN1252 的執行處理,就無法在這兩個資料庫之間傳送含有 DBMS_PIPE 的訊息。在此情況下,如果您嘗試在這兩個資料庫之間傳送含有 DBMS_PIPE 的訊息,系統將會發出錯誤 ORA-12704

永久訊息的 DBMS_PIPE 子程式摘要

此表格列出 DBMS_PIPE 子程式並簡要說明。

表格 - DBMS_PIPE 套件子程式

子程式 描述

CREATE_PIPE 函數

建立管路 (專用管路需要)。

GET_CREDENTIAL_NAME 函數

傳回全域 credential_name 變數值。

GET_LOCATION_URI 函數

傳回當訊息儲存在「雲端物件存放區」時,用來作為預設位置 URI 的全域 location_uri 變數值。

傳回緩衝區中下一個項目的資料類型。

在本地端緩衝區內建立信件 。

RECEIVE_MESSAGE 函數

將已命名管道的訊息複製到本機緩衝區。

清除本機緩衝區的內容。

移除已命名的管道。

SEND_MESSAGE 函數

在具名管道上傳送訊息:如果具名管道不存在,這會隱含地建立公用管道。

SET_CREDENTIAL_NAME 程序

設定 credential_name 變數,作為儲存在「雲端物件存放區」之訊息的預設證明資料。

SET_LOCATION_URI 程序

設定全域 location_uri 變數,作為儲存在「雲端物件存放區」之訊息的預設位置 URI。

傳回唯一的階段作業名稱。

存取緩衝區中的下一個項目 。

CREATE_PIPE 函數

此功能會明確建立公用或專用管道。如果 private 旗標為 TRUE,則會將管道建立者指派為私人管道的擁有者。

明確建立的管道只能透過呼叫 REMOVE_PIPE 或關閉執行處理來移除。

語法

DBMS_PIPE.CREATE_PIPE (
   pipename     IN VARCHAR2,
   maxpipesize  IN INTEGER DEFAULT 66536,
   private      IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;

參數

表格 - CREATE_PIPE 函數參數

Parameter - 參數 描述

pipename

您正在建立的管道名稱。

當您呼叫 SEND_MESSAGERECEIVE_MESSAGE 時,必須使用此名稱。此名稱在執行處理中必須是唯一的。

注意:請勿使用以 ORA$ 開頭的管道名稱。這些保留供 Oracle 提供的程序使用。管線名稱的長度不應超過 128 個位元組,而且不區分大小寫。此時,名稱不能包含「全域化支援」字元。

maxpipesize

管道允許的最大大小 (位元組)。

管道上所有訊息的大小總計不得超過此數量。如果訊息超過此上限,就會被封鎖。

預設的 maxpipesize 為 66536 個位元組。

管的 maxpipesize 會成為管特徵的一部分,並會在管的生命週期中持續存在。值較大的 SEND_MESSAGE 呼叫者會增加 maxpipesize。值較小的來電者會使用現有、較大的值。

65536 的預設 maxpipesize 適用於所有管道。

private

使用預設值 TRUE 來建立專用管道。

當您呼叫 SEND_MESSAGE 時,可以隱含地建立公用管道。

傳回值

表格 - CREATE_PIPE 函數傳回值

傳回 描述

0

成功。

如果管道已存在,且嘗試建立該管道的使用者已獲授權使用該管道,則 Oracle 會傳回 0,表示成功,且管道中已存在的任何資料仍會保留。

ORA-23322

發生命名衝突,因此失敗。

如果有相同名稱的管道存在且是由其他使用者所建立,則 Oracle 會發出錯誤 ORA-23322,指出命名衝突。

異常狀況

表格 - CREATE_PIPE 函數異常狀況

例外 描述

Null pipe name

權限錯誤:相同名稱的管線已存在,您不能使用它 。

範例

建立名稱為 MY_PIPE1 的明確專用

DECLARE
  l_status INTEGER;
BEGIN
  l_status := DBMS_PIPE.create_pipe(
      pipename  => 'MY_PIPE1',
      private   => TRUE);
END;
/

GET_CREDENTIAL_NAME 函數

此函數會傳回將訊息儲存至「雲端物件存放區」時所使用的全域 credential_name 變數值。

語法

DBMS_PIPE.GET_CREDENTIAL_NAME
         RETURN VARCHAR2;

傳回值

傳回值 描述

credential_name

存取雲端物件儲存的證明資料名稱。

範例

DECLARE
  credential_name     VARCHAR2(400)
BEGIN
  credential_name := DBMS_PIPE.GET_CREDENTIAL_NAME;
END;
/

GET_LOCATION_URI 函數

此函數會傳回全域 location_uri 變數值,當管路訊息儲存至「雲端物件存放區」時,可作為預設位置 URI。

語法

DBMS_PIPE.GET_LOCATION_URI
        RETURN VARCHAR2;

傳回值

傳回值 描述
location_uri

物件 URI。

範例

DECLARE
  location_uri     VARCHAR2(400)
BEGIN
  location_uri := DBMS_PIPE.GET_LOCATION_URI;
END;
/

RECEIVE_MESSAGE 函數

此函數會將訊息複製到本機訊息緩衝區中。

語法

DBMS_PIPE.RECEIVE_MESSAGE (
   pipename          IN VARCHAR2,
   timeout           IN INTEGER  DEFAULT maxwait,
   credential_name   IN VARCHAR2 DEFAULT null,
   location_uri      IN VARCHAR2)
RETURN INTEGER;

參數

表格 - RECEIVE_MESSAGE 函數參數

Parameter - 參數 描述

pipename

您要接收訊息的管道名稱。

名稱開頭為 ORA$ 時,會保留供 Oracle 使用。

timeout

等待訊息的時間 (秒)。逾時 0 可讓您讀取而不封鎖。

逾時不包括執行使用 cache_func 參數指定之快取函數所花費的時間。

預設值:常數 MAXWAIT,其定義為 86400000 (1000 天)。

credential_name

用來儲存訊息之雲端存放區的證明資料名稱。

credential_name 是依照預設初始化為 NULL 的套裝軟體引數。

您可以在呼叫 DBMS_PIPE.RECEIVE_MESSAGE 之前設定此值。傳送的參數值優先於全域變數的值。

證明資料物件必須具備執行 DBMS_PIPE.RECEIVE_MESSAGE 之使用者的 EXECUTEREAD/WRITE 權限。

location_uri

用來儲存訊息之雲端存放區的位置 URI。

location_uri 是全域變數,依預設會起始為 NULL

您可以在呼叫 DBMS_PIPE.RECEIVE_MESSAGE 之前設定此值。傳送的參數值優先於全域變數的值。

傳回值

表格 - RECEIVE_MESSAGE 函數傳回值

傳回 描述

0

成功

1

已逾時。如果是隱含建立的管是空的,則將移除該管。

2

管線中的記錄對緩衝區而言太大。

3

發生岔斷。

ORA-23322

使用者的權限不足,無法從管道讀取。

使用注意事項

  • 若要從管道接收訊息,請先呼叫 RECEIVE_MESSAGE。當您收到訊息時,該訊息會從管道中移除,因此只能收到一次訊息。對於隱含建立的管,在從管中移除最後一個記錄後,管將被移除。

  • 如果您在呼叫 RECEIVE_MESSAGE 時指定的管道不存在,則 Oracle 會隱含地建立管道並等待接收訊息。如果訊息未在指定的逾時間隔內到達,則會傳回該呼叫並移除管道。

  • 收到訊息之後,您必須對 UNPACK_MESSAGE 進行一或多個呼叫,才能存取訊息中的個別項目。UNPACK_MESSAGE 程序已超載以解壓縮類型為 DATENUMBERVARCHAR2 的項目,另外還有兩個解壓縮 RAWROWID 項目的程序。如果您不知道您嘗試解壓縮的資料類型,請呼叫 NEXT_ITEM_TYPE 來判斷緩衝區中下一個項目的類型。

  • 持續性訊息保證只能由一個程序寫入或讀取。這可避免因並行寫入和讀取而導致訊息內容不一致。使用永久訊息傳遞管道時,DBMS_PIPE 只允許一項作業,傳送訊息或接收訊息在指定時間為作用中。不過,如果因進行中的作業而無法執行作業,則程序會定期重試,直到達到 timeout 值為止。

  • 如果您使用 Oracle Cloud Infrastructure Object Storage 來儲存訊息,可以使用 Oracle Cloud Infrastructure 原生 URI 或 Swift URI。但是,位置 URI 與憑證的類型必須相符,如下所示:

    • 如果您使用原生 URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,就必須在證明資料物件中使用原生 Oracle Cloud Infrastructure 簽署金鑰認證。

    • 如果您使用 Swift URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,則必須在證明資料物件中使用認證權杖認證。

異常狀況

表格 - RECEIVE_MESSAGE 函數例外

例外 描述

Null pipe name

權限錯誤。權限不足,無法從管道移除記錄。管道是由其他人所擁有。

SEND_MESSAGE 函數

此函數會在具名管道上傳送訊息。

訊息包含在本機訊息緩衝區中,並填入對 PACK_MESSAGE 的呼叫。您可以使用 CREATE_PIPE 明確地建立管道,否則會以隱含方式建立管道。

語法

DBMS_PIPE.SEND_MESSAGE (
    pipename          IN VARCHAR2,
    timeout           IN INTEGER DEFAULT MAXWAIT,
    credential_name   IN VARCHAR2 DEFAULT null,
    location_uri      IN VARCHAR2 )
RETURN INTEGER;

參數

表格 - SEND_MESSAGE 函數參數

Parameter - 參數 描述
credential_name

用來儲存訊息之雲端存放區的證明資料名稱。

credential_name 是依照預設初始化為 NULL 的套裝軟體引數。

您可以在呼叫 DBMS_PIPE.SEND_MESSAGE 之前設定此值。傳送的參數值優先於全域變數的值。

證明資料物件必須具備執行 DBMS_PIPE.SEND_MESSAGE 之使用者的 EXECUTEREAD/WRITE 權限。

location_uri

用來儲存訊息之雲端存放區的位置 URI。

location_uri 是全域變數,依預設會起始為 NULL

您可以在呼叫 DBMS_PIPE.SEND_MESSAGE 之前設定此值。傳送的參數值優先於全域變數的值。

maxpipesize

允許的管道大小上限 (位元組)。

管道上所有訊息的大小總計不得超過此數量。如果訊息超過此上限,就會被封鎖。預設值為 65536 位元組。

管的 maxpipesize 會成為管特徵的一部分,並會在管的生命週期中持續存在。值較大的 SEND_MESSAGE 呼叫者會增加 maxpipesize。值較小的來電者只需使用現有、較大的值。

SEND_MESSAGE 程序中指定 maxpipesize 時,不需要另外呼叫即可開啟管道。如果您明確地建立管道,則可以使用選用的 maxpipesize 參數覆寫建立管道大小規格。

65536 的預設 maxpipesize 適用於所有管道。

pipename

您要在其上放置訊息的管道名稱。

如果您使用明確的管道,則這是您在呼叫 CREATE_PIPE 時指定的名稱。

注意:請勿使用以 'ORA$' 開頭的管道名稱。這些名稱保留供 Oracle 提供的程序使用。管線名稱的長度不應超過 128 個位元組,而且不區分大小寫。此時,名稱不能包含「全域化支援」字元。

timeout

嘗試將訊息置於管道上的等待時間 (秒)。

預設值是常數 MAXWAIT,其定義為 86400000 (1000 天)。

傳回值

表格 - SEND_MESSAGE 函數傳回值

傳回 描述

0

成功。

如果管道已存在,且嘗試建立該管道的使用者已獲授權使用該管道,則 Oracle 會傳回 0,表示成功,且管道中已存在的任何資料仍會保留。

如果以 SYSDBS/SYSOPER 身分連線的使用者重新建立管道,則 Oracle 會傳回狀態 0,但管道的所有權仍維持不變。

1

已逾時。

此程序可能會逾時,因為它無法取得管上的鎖頭,或是因為管仍然太滿而無法使用。如果是隱含建立的管是空的,則將移除該管。

3

發生岔斷。

如果已隱含地建立管並且是空的,則將其移除。

ORA-23322

權限不足。

如果有相同名稱的管道存在且是由其他使用者所建立,則 Oracle 會發出錯誤 ORA-23322,指出命名衝突。

使用注意事項

  • 持續性訊息保證只能由一個程序寫入或讀取。這可避免因並行寫入和讀取而導致訊息內容不一致。使用永久訊息傳遞管道時,DBMS_PIPE 只允許一項作業,傳送訊息或接收訊息在指定時間為作用中。不過,如果因進行中的作業而無法執行作業,則程序會定期重試,直到達到 timeout 值為止。

  • 如果您使用 Oracle Cloud Infrastructure Object Storage 來儲存訊息,可以使用 Oracle Cloud Infrastructure 原生 URI 或 Swift URI。但是,位置 URI 與憑證的類型必須相符,如下所示:

    • 如果您使用原生 URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,就必須在證明資料物件中使用原生 Oracle Cloud Infrastructure 簽署金鑰認證。

    • 如果您使用 Swift URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,則必須在證明資料物件中使用認證權杖認證。

異常狀況

表格 - SEND_MESSAGE 函數異常狀況

例外 描述

Null pipe name

權限錯誤。寫入管道的權限不足。此管是私人管路,由其他人負責。

SET_CREDENTIAL_NAME 程序

此程序會設定當管路訊息儲存在「雲端物件存放區」時,用來作為預設證明資料的 credential_name 變數。

語法

DBMS_PIPE.SET_CREDENTIAL_NAME (
   credential_name   IN VARCHAR2 );

參數

Parameter - 參數 描述

credential_name

存取雲端物件儲存的證明資料名稱。

使用備註

如果您使用 Oracle Cloud Infrastructure Object Storage 來儲存訊息,可以使用 Oracle Cloud Infrastructure 原生 URI 或 Swift URI。但是,位置 URI 與憑證的類型必須相符,如下所示:

  • 如果您使用原生 URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,就必須在證明資料物件中使用原生 Oracle Cloud Infrastructure 簽署金鑰認證。

  • 如果您使用 Swift URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,則必須在證明資料物件中使用認證權杖認證。

範例

BEGIN
     DBMS_PIPE.SET_CREDENTIAL_NAME(
       credential_name =>  'my_cred1');
END;
/

SET_LOCATION_URI 程序

此程序會設定全域 location_uri 變數。

語法

DBMS_PIPE.SET_LOCATION_URI (
   location_uri   IN VARCHAR2 );

Parameter - 參數

Parameter - 參數 描述
location_uri

物件或檔案 URI。URI 的格式取決於您使用的雲端物件儲存體服務,如需詳細資訊,請參閱雲端物件儲存體 URI 格式

使用備註

如果您使用 Oracle Cloud Infrastructure Object Storage 來儲存訊息,可以使用 Oracle Cloud Infrastructure 原生 URI 或 Swift URI。但是,位置 URI 與憑證的類型必須相符,如下所示:

  • 如果您使用原生 URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,就必須在證明資料物件中使用原生 Oracle Cloud Infrastructure 簽署金鑰認證。

  • 如果您使用 Swift URI 格式來存取 Oracle Cloud Infrastructure Object Storage ,則必須在證明資料物件中使用認證權杖認證。

範例

BEGIN
  DBMS_PIPE.GET_LOCATION_URI(
      location_uri  => 'https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/');
END;
/