Quantcast
Channel: SQL Anywhere Japan
Viewing all 49 articles
Browse latest View live

過去のブログ記事より : SQL Anywhere における TSQL と Watcom SQL 方言 のミックス

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2015/01/21/from-the-archives-mixing-sql-dialects

 

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 5 月に掲載したものです。その中で、Glenn は SQL Anywhere における 2 つの SQL 方言(TSQL と Watcom SQL)のビルトインのサポートについて語るとともに、ストアドプロシージャー内で方言をミックスすることによる潜在的な問題について説明しています。

 

 

1995年11月、現在も Watcom SQL と呼び続けている SQL Anywhere の方言に加えて、Transact-SQL をサポートした最初のバージョンである SQL Anywhere version 5.0 をリリースしました。 (ちなみに、私が関わった SQL Anywhere の最初のバージョンが SQL Anywhere 5.0 でした。入社したのはこのリリースの1か月前でした。)この 2 つの方言の SQL 構造には、多くの共通点があります。しかしながら、重要となる大きな違いが存在するのも事実です。
この 2 つの明らかに大きな違いは、文のデリミターの使用です。

 

Watcom SQL では、各文を区別するのにセミコロンを使用します。一方、Adaptive Server Enterprise がサポートする Transact-SQL 方言では、 BEGIN...ENDブロック内または文の間のデリミターは特定しません。

 

文のデリミターがある方言とない方言の両方をサポートするのは、技術的には非常に大きなチャレンジです。SQL Anywhere サーバーは、アプリケーションが何を送るのかわからないため、どちらの方言の構造もパースできなければなりません。また、片方の方言がいつ使われ、もう一方がいつ使われるのか把握できなければならないからです。

 

2つの方言間の最も重要なセマンティックな違いは、おそらくエラーの処理方法にあります。SQL Anywhere のマニュアルでは、下記のように記述されています。

デフォルトのプロシージャーエラーの処理方法は、Transact-SQL 方言と Watcom 方言では大きく異なります。

 

Watcom 方言のプロシージャーは、デフォルトでは、エラーに遭遇すると calling 環境に対して SQLSTATE と SQLCODE 値を返し、終了(exit)します。Watcom SQL ストアドプロシージャー内に EXCEPTION 文を使用して明示的なエラーハンドリングを構築することもできます。あるいは、プロシージャーに対して、エラーに遭遇した場合は ON EXCEPTION RESUME 文を使用して次の文でプロシージャーを継続するように指示することもできます。

 

Transact-SQL 方言のプロシージャーがエラーに遭遇した場合には、続く文でもプロシージャーは継続して実行されます。最も最新の実行文のエラー状況は、グローバル変数 @@error で保持されます。この変数は、プロシージャーからのリターンを強制する文に続いてチェックすることができます。
例えば、以下の文では、エラーが発生した場合には終了(exit)します。
IF @@error != 0 RETURN

 

プロシージャーが実行を完了すると返される値を見れば、プロシージャーが成功したのか失敗したのかがわかります。この返されたステータスは、integerで、以下のようにアクセスすることができます。
DECLARE @Status INT
EXECUTE @Status = proc_sample
IF @Status = 0   PRINT 'procedure succeeded'
ELSE   PRINT 'procedure failed'

そのため、サーバーのプロパティが、使用されている SQL 方言はどちらなのかを認識していることが重要になります。

 

 

シンタックスの糸口

 

インプットの際に、SQL Anywhere サーバーパーサーは、Watcom SQL バッチ、Transact-SQL バッチ、Watcom SQL 方言文  (例 CREATE PROCEDURE)、または、Transact-SQL の方言文を予期する可能性があります。なぜならば、SQL Anywhere パーサーに対して、バッチ、プロシージャー、またはトリガーの方言が Transact-SQL であることを表す特別なシンタックス構造がいくつか存在するからです。

それには以下のものがあります。

 

  • 以下の Transact-SQL プロシージャーにあるような、プロシージャーボディーの前の AS 句の使用
    CREATE PROCEDURE showdept @deptname varchar(30)
    AS   SELECT Employees.Surname, Employees.GivenName   FROM Departments, Employees   WHERE Departments.DepartmentName = @deptname   AND Departments.DepartmentID = Employees.DepartmentID;
    Watcom 方言のプロシージャーでは、ANSI/ISO SQL標準のとおり BEGIN...ENDブロックを使用して、プロシージャーボディーを区別します。

 

  • トリガーにおける、trigger-time (BEFORE, AFTER, INSTEAD OF, または RESOLVE) の欠如。
    Adaptive Server Enterprise 15.0 でサポートされる Transact-SQL 方言では、すべてのトリガーは文レベルのトリガーです。
    SQL Anywhere では、そのようなトリガーは、AFTER STATEMENTトリガーとして作成されます。
    サポートされている Transact-SQL シンタックスは、以下のとおりです。
    CREATE TRIGGER [owner .]trigger_name
    ON [owner .]table_name
    FOR [ INSERT | UPDATE | DELETE ]
    AS ...
    SQL Anywhere における Transact-SQL のサポートは、Adaptive Server Enterprise 15.5 のリリースで最近導入された INSTEAD OFトリガーは(まだ)サポートしていません。

 

  • プロシージャー、トリガー、関数、または SELECT文における、SELECT リスト表現、または変数割り当てをエイリアシング するための Transact-SQL '=' オペレーターの使用:
    SELECT @var = 'literal string'
    Watcom SQL 方言では、SET 文を使用します。
    SET @var = 'literal string';

 

  • ストアドプロシージャーへの 引数内のデフォルト値を区別するための '=' の使用。Watcom SQL 方言では DEFAULT句を使用します。

 

  • ストアドプロシージャーパラメーターの仕様の後の OUTPUTまたは OUTの使用:
    CREATE PROCEDURE showdept @deptname varchar(30) OUTPUT
    AS ...
    Watcom SQL シンタックスでは、以下のようになります。
    CREATE PROCEDURE showdept ( OUT @deptname varchar(30) )
    BEGIN ...

 

  • Transact-SQL 文 COMMIT TRANSACTIONROLLBACK TRANSACTION、または PREPARE TRANSACTION の使用

 

逆に、特定のシンタックスがその文(単数または複数)が Watcom SQL 方言であることを見極めるインスタンスには 2種類あります。

 

  • CREATE [OR REPLACE] VARIABLE 文と

 

  • それぞれの文を切り離すのにセミコロンが使用されている Watcom-SQL 方言 BEGIN...ENDブロックとオプショナルのラベル、変数宣言(s) 、そしてEXCEPTION句です。

 

 

例:共通のテーブル表現

 

標準 SQL:2008 とSQL Anywhere では、共通テーブル表現として知られる SQL 構造をサポートしています。これは、WITHキーワードを使用して、何が効果的なインラインのビュー定義なのかを宣言します。 WITH RECURSIVEは、再帰クエリを再構築するのに使用されるシンタックスです。

 

文のデリミターを活用しない SQL 方言の中で、共通テーブル表現をサポートするのは、他の様々な SQL 構造の中で使用される WITHキーワードのため困難です。

 

例えば、SQL Anywhere では、共通のテーブル表現の定義は、制約定義上の Transact-SQL WITH句のオプショナルの使用と競合するかもしれません。
なぜならば、SQL Anywhere は、Transact-SQL プロシージャーの共通テーブル表現をサポートしていないからです。しかしながら、クエリの FROM句 (文法のコンフリクトが問題ではないところ) に作成されたテーブル内に埋め込まれた場合には使用することができます。

 

余談として、Microsoft SQL Server 2008 は、オプション的に文のデリミター(セミコロン)を含む Transact-SQL プロシージャーをサポートしています。そして、Transact-SQL のオリジナルの(セミコロンでない)シンタックスに関しては、deprecate (廃止予定) です。また、Adaptive Server Enterprise とは異なり、Microsoft SQL Server は共通テーブル表現をサポートしています。しかしながら、例えば、バッチで使用される場合には、前の文は、セミコロンで終了する必要があります。もちろん、許されるのであれば、文法の競合で、LALR(1) - または、LALR(2) - パーサーの中に生成されます。

 

 

SQL Anywhere の SQL インプットのパース方法

 

すでに述べたとおり、SQL Anywhere は、Watcom SQL と Transact-SQL 方言の両方をサポートする必要があります。アプリケーションが何を送るのかはサーバーにはわからないため、SQL Anywhere パーサーは、パースインプットに対して複数の方法で、反復的に試みます。これは、「パースゴール」と呼ばれています(WATCOM SQL バッチ、Transact-SQL バッチ、SQL 文)。より効率性を上げるため、その接続で最後にパースに成功した文の方言を最初に試みます。

 

エラーがあった場合にはどうなるでしょう ? エラーの場合は、サーバーは代替のゴールを試みます。

説明すると、以下の複合文があるとします。


  1. begin 
  2.   declare @var int 
  3.   select @var = 100 
  4.   WITH CountEmployees( DepartmentID, n ) AS 
  5.   ( SELECT DepartmentID, COUNT( * ) AS
  6.     FROM Employees GROUPBY DepartmentID ) 
  7.   SELECT DepartmentID, n 
  8.   FROM CountEmployees 
  9.   WHERE n <= @var 
  10. end

 

ここに、文のデリミターが欠如する Transact-SQL 複合文があります。しかしながら、サーバーは、これがa priori(演繹的、先天的)であることを知らないため、最初は単一の SQL 文としてパースを試み、失敗します。

その後、サーバーはそのブロックを Watcom SQL 方言の複合文としてパースしようとします。しかしながら、

パーサーは、DECLARE文の最後を表すセミコロンがないため、行25から26の DECLARE @var INT SELECTを理解できず、失敗します。

そして、Transact-SQL バッチとしてパースを試みます。しかしながら、SQL Anywhere の Transact-SQL でサポートしていない行27 の最初の共通テーブル表現が原因で、これも失敗します。

 

それでは、これら3つの別々の試みからどのエラーが返されるでしょうか?簡単に回答すると、「ベストなもの」になります。

SQL Anywhere で使用されているメトリックは、パーサーがより深く進めば進むほど、予測された方言によりマッチするようになります。

そのため、この例で返されるエラーは、Transact-SQL のためで、これは、"Syntax error near 'WITH' on line 4" です。

Watcom SQL の試みは、 "Syntax error near 'DECLARE' on line 3" のエラーになりました。これは、サーバーが Transact-SQL 方言を試みた後に抑制したものです。

 

この例におけるポイントは、SQL 方言をミックスする場合、クライアントに返されるエラーメッセージは、インプットをパースする際のサーバーによる最善の試みに基づいているということです。
そして、その結果その特定のエラーは、直観的ではないかもしれません。上の例では、 BEGINブロックで使用されている共通テーブル表現ブロックper se (それ自体、本質的に)に問題はありません。単に、共通テーブル表現が Transact-SQL 方言の SQL Anywhere の実装においてサポートされていないだけです。Transact-SQL 方言が仮定されたのは、パーサーが Transact-SQL の文法を使用した複合文をとおしてさらに進めたからです。上のブロックに、セミコロンを追加していたならば、この複合文もエラーになっていたでしょう。

 

  1. BEGIN 
  2.   DECLARE @var int
  3.   SELECT @var = 100; 
  4.   WITH CountEmployees( DepartmentID, n ) AS 
  5.   ( SELECT DepartmentID, COUNT( * ) AS
  6.     FROM Employees GROUPBY DepartmentID ) 
  7.   SELECT DepartmentID, n 
  8.   FROM CountEmployees 
  9.   WHERE n <= @var; 
  10. END

 

この文のデリミターは、すぐに複合文を Transact-SQL としてパースすることを終了します。しかし、行36 の変数割り当てのための Transact-SQL シンタックスの使用は、Watcom SQL 方言を使用した文のパースに相反することになります。

この場合、後のエラーが返されるエラーです。


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。


過去のブログ記事より : SQL Anywhere におけるキーワードとアップグレード

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2015/01/28/from-the-archives-keywords-and-upgrades

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2010 年 4 月に掲載したものです。その中で、Glenn は SQL Anywhere パーサーがどのようにしてキーワードを認識するのか説明しています。

 

 

SQL Anywhereでは、新しいバージョンがリリースされるたびに追加の SQL 機能を実装してきました。これらは、標準 SQL の強化によってもたらされたものや、我々独自の製品イノベーションによるものです。

 

例えば SQL Anywhere の version 12 では、標準SQL:2008 の 「distinct predicate」をサポートしています。これは、シンタックス X IS [ NOT ] DISTINCT FROM Y を持ち、二つの表現値を比較して、NULL をイコールの比較演算子として扱うことが可能です。

 

distinct predicate は、状況によってはたいへん便利です。特にストアドプロシージャーパラメーターを含み、表現が NULL でありうる場合に異なる SQL 構造を特定する必要性を好まない場合に便利です。

 

(余談ですが: distinct predicate がユーティリティーを持つ可能性がある一方で、同時に、SQL の "normal" 3-valued logic からのこのような偏りは、間違いなく、すでに混乱していてどこかで長々と議論されている NULL に絡む問題を増加させることになります。)

 

distinct predicate の場合、そのシンタックスは直線的な採用と実装が可能です。なぜならば、そのシンタックスには、- 間違いなく幾分不格好ですが - 少なくとも新しい予約語は含まれないからです。残念ながら、SQL では、追加の機能性が追加のキーワードを必要とすることがルールであることがよくあります。これらのキーワードは、文をパースする際に、曖昧性を避けるために予約語にする必要があります。

 

我々は、SQL Anywhere サーバーのYACC のカスタムビルドの実装に対して、「non_keywords」 接続オプションを長く提案してきました。このオプションは、識別子として使用できるようユーザーまたはアプリケーション側で特定のキーワードをオフにすることができます。

例えば、以下のように特定することができます。

 

  1. SETOPTION non_keywords = 'TRUNCATE, SYNCHRONIZE'

 

SQL Anywhere のバージョン 12 では、この柔軟性を一歩進め、追加の接続オプション "reserved_keywords" をサポートしています。

この新しいオプション実装の背景には、サーバーがより容易に、自動的に、out-of-the-box (箱から出してすぐの状態) でアップグレードできるようにするという意図があります。例外として、お客様のアプリケーションとの競合の可能性が高い時場合の SQL 文法からのキーワードは除きます。

 

具体的な例として、SQL Anywhere 12 では、MySQL アプリケーションを開発する人にはよく知られている LIMIT OFFSET 句をサポートしています。

LIMITOFFSETは、機能的には SELECT TOP ... START AT とほぼ同じです。しかしながら、LIMITを SQL 文法に導入するには、これが予約キーワードである必要があります。潜在的には、「limit」 を識別子として使用する既存のアプリケーションを壊してしまうことになります。そのため、LIMITのサポートは導入したものの、デフォルトではこれを無効にしておくことにしました。LIMIT 句 の使用を有効にするには、以下経由のキーワードとして有効にすることができます。

 

  1. SETOPTIONPUBLIC.reserved_keywords = 'LIMIT'

 

サーバー内でワードがキーワードとして識別されたかどうかは、以下で決まります。 (優先順に):

  • SQL Anywhere の予約語のリストに現れる
  • reserved_keywords オプションでオンになっている
  • non_keywordsオプションを使用してオフになっている

 

reserved_keywordsオプションにより、SQL 言語の拡張サポートにおけるさらなる柔軟性を提供できるようになりました。

今後のSQL Anywhere リリースで追加される SQL 機能において、このオプション を有効活用したいと考えています。

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

SAP SQL Anywhere 17 解説本プレゼントキャンペーン実施中 !! ぜひご応募ください。

$
0
0

最新版であるSAP SQL Anywhere 17を前提とした技術解説書「「SAP SQL Anywhere 17 自己管理型RDBMS入門ガイド」のプレゼントキャンペーンを実施中です。

 

ご希望の方は、SAPジャパンホームページのトップぺージからご応募ください。

SQLAnywhere本トップページ.png

 

トップページからのリンクがない場合は、こちらの登録ページより直接ご登録ください。

 

書籍の詳細につきましては、こちらをご参照ください。

sqlanywhere17.jpg

過去のブログ記事より : より柔軟な方法でSQL Anywhere へデータをロードする - パート 1

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/04/16/loading-data-in-more-flexible-ways--part-un

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 7 月に掲載したものです。その中で、Glenn は SQL Anywhere へのデータロードの方法として OPENSTRING句について語っています。

 

 

 

 

フラットファイルのコンテンツを SQL Anywhere サーバーに、あるいは逆に SQL Anywhere サーバーから転送することが必要な場合があります。
Version 11より前のバージョンでは、フラットファイルからのインポートは、以下の方法が可能でした(コードを書いて実行するのではなく)。

 

  • LOAD TABLE 文を使用する;
  • DBISQL ツールから INPUT 文を使用する;
  • xp_read_file() プロシージャーを使用してロードする; または
  • リモートデータアクセスサービスを使用して、フラットファイルに対してプロキシーテーブルを構築する

 

上のソリューションそれぞれに、プラス面とマイナス面があります。
最初の 2 つのオプションでは、データをロードするためのテーブルの作成が必要になります。LOAD TABLEは、INPUTよりも高速です。しかし、欠点が 2 つあります。まず、サーバーマシンから直接ファイルにアクセス可能である必要があります。そして、挿入される個々の行がトランザクションログで記録されないようにする必要があります(複雑なリカバリ)。
3番目のオプションもまた、サーバーマシンに対してローカルにある必要があります。残念ながら、xp_read_file() は、パーシングが必要になる曖昧な値を作成してしまいます。
4番目のオプションであるプロキシーテーブルは、外部サーバー、EXTERNLOGINオブジェクトなどを作成する必要があり、これを使うのはさらに面倒です。

 

Version 11 では、フラットファイルとのインタラクションをより柔軟に処理できるようになりました。このブログ記事では、 OPENSTRINGで提供される機能について説明します。そして、次の記事で、追加のオプションについて説明します。

 

 

OPENSTRING

 

これらの新機能を説明するにあたり、StatCounter で生成された CSV アウトプットファイルをサーバーにアップロードします。このファイルの最初の数行については以下のとおりです ( StatCounter のアカウントを1月20日に登録しました )。

 

  1. Day,Date,Page Loads,Unique Visitors,First Time Visitors,Returning Visitors
  2. Tuesday,20th January 2009,"83","48","46","2"
  3. Wednesday,21st January 2009,"163","108","102","6"
  4. Thursday,22nd January 2009,"127","105","99","6"
  5. Friday,23rd January 2009,"126","91","87","4"
  6. Saturday,24th January 2009,"42","37","35","2"
  7. Sunday,25th January 2009,"52","38","36","2"
  8. Monday,26th January 2009,"171","133","119","14"
  9. Tuesday,27th January 2009,"157","110","101","9"

 

プロキシーテーブル、LOAD TABLE、あるいは INPUT INTOを使用するのではなく、テーブルの作成は作成しないことにし、シンプルに OPENSTRINGを使用して、SELECT文ではフラットファイルを直接参照することにします。

 

OPENSTRINGは、インプットパラメーターがフラットファイルか(列)変数のどちらかであるテーブル表現です。 特定された場合には、サーバーはそのファイルのインプットをパースし、OPENSTRING表現の句内で特定するスキーマをマッチさせながら、バーチャルテーブルの行を構築します。テーブル表現の SQL 文法は以下のとおりです。

 

  1. <openstring-expression>::= OPENSTRING ( { FILE | VALUE } <string-expression> ) WITH ( <rowset-schema> ) [ OPTION ( <scan-option> ...  ) ]
  2. <rowset-schema>::= <column-schema-list> | TABLE [owner.]table-name [ ( column-list ) ]
  3. <column-schema-list>::= { <column-name> <user-or-base-type> | FILLER( ) } [ , ... ]
  4. <column-list> ::= { <column-name> | FILLER( ) } [ , ... ]
  5. <scan-option> ::= BYTE ORDER MARK { ON | OFF }
  6.         | COMMENTS INTRODUCED BY <comment-prefix>
  7.         | DELIMITED BY <string>
  8.         | ENCODING <encoding>
  9.         | ESCAPE CHARACTER <character>
  10.         | ESCAPES { ON | OFF }
  11.         | FORMAT { TEXT | BCP }
  12.         | HEXADECIMAL { ON | OFF }
  13.         | QUOTE <string>
  14.         | QUOTES { ON | OFF }
  15.         | ROW DELIMITED BY <string>
  16.         | SKIP integer
  17.         | STRIP { ON | OFF | LTRIM | RTRIM | BOTH }

 

OPENSTRINGのオプションは、LOAD TABLEで可能なそれらにマッチすることに注意してください。このケースでは、Excel-CSV ファイルは、カンマで定義されるフィールドを使用します。また、最初の行には実際の値の処理では無視されなければならない属性名が含まれます。
このインプットファイルから直接結果セットを作成する SQL 文は以下のとおりです。

 

  1. SELECT stat_weekday,
  2.       CAST ( ( REGEXP_SUBSTR( str_stat_date, '[0-9]+(?=(st|nd|th|rd|ST|ND|TH|RD )\s.*)' )
  3.                     || REGEXP_SUBSTR( str_stat_date, '(?<=[0-9]+(st|nd|th|rd|ST|ND|TH|RD)).*' ) ) AS DATE ) as stat_date,
  4.       page_loads, unique_visitors, first_time_visitors, returning_visitors
  5. FROM OPENSTRING( VALUE READ_CLIENT_FILE ('c:\gpaulley\blog\summary-6July2009.csv' ) )
  6.     WITH( stat_weekday char(10), str_stat_date char(30), page_loads int, unique_visitors int, first_time_visitors int, returning_visitors int)
  7.         OPTION( SKIP 1 DELIMITED BY ',' ) AS summary

 

上の文のポイントをいくつか挙げます:

 

  • OPENSTRINGへのパラメータは、VALUEまたは FILE のどちらかです。もし FILEが特定されている場合には、そのフラットファイルは、サーバーマシンに対してローカルになければなりません; このケースでは、このファイルは私のコンピューターにあります。
    Version 11 では、READ_CLIENT_FILE機能をサポートしています。これは、SQL Anywhere の CMDSEQ ワイヤプロトコルを使用して、クライアントマシンから、ファイルのコンテンツをフェッチするものです。READ_CLIENT_FILEは、OPENSTRINGが続いて行を作成するためにパースする内部文字列を作成します。

  • WITH 句は、ファイルのスキーマを特定します。ファイル内の文字列からのサーバーデータ型へのコンバージョンは、自動的に実行されます。しかしながら、StatCounter によって生成された CSV ファイルは、年日付値 (例えば '21st January 2009')を含んでいたため、日の値は、文字列としてパースされます。

  • SQL Anywhere がDATEへコンバートすることが可能な修正された文字列を生成するために、REGEXP_SUBSTR機能を使います。
    これは、version 11 のもう1つの新機能で、SQL Anywhere の正規表現のサポートに伴って実装されました。
    ここでは、REGEXP_SUBSTRの最初の使用では、肯定の先読みゼロ幅アサーションを使用して、省略された、数値的な、月の特定の日付を返します。REGEXP_SUBSTRの 2 つめのインスタンスは、似ていますが、肯定の先読みゼロ幅アサーションを使用して、文字列の残りを返します。文字列を連結させた場合には、この2つの機能は、 '21st January 2009' を '21 January 2009' にコンバートします。サーバーは、DATE_ORDER 接続オプションによって ('DMY') を適切に選択し、自動的にこのコンバージョンを扱うことが可能です。

  • READ_CLIENT_FILE を使用するには、以下の 2 つが必要になります:

    • データベースは、ALLOW_READ_CLIENT_FILE オプションを有効にして、クライアントファイルアクセスを有効にする必要があります。このオプションは、DBA 権限を持つユーザーのみ設定可能です。

    • READ_CLIENT_FILEを実行するユーザーは、READCLIENTFILE権限が必要です。

 

このクエリのスクリーンショットと結果セットは以下のとおりです。

regexp_substr.png

 

OPENSTRINGは、 - INSERTMERGEを含む - どの DML 文でも現れるテーブル表現です。また、そのクエリのスコープ内のどの列変数をも参照することが可能です。
さらに、OPENSTRINGをビュー内で有効利用することができます。
ビュー定義が確立されると、ビューからフラットファイルを使用しているプロシージャーまたはアプリケーションがシームレスにアップデート DML 文をそのビューに対して発行できるように、INSTEAD OF トリガーを作成することが可能です。


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

過去のブログ記事より : より柔軟な方法で SQL Anywhere へデータをロードする - パート 2

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/04/30/loading-data-in-more-flexible-ways--part-deux

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 7 月に掲載したものです。その中で、Glenn は データがクライアントにある場合に、LOAD TABLE を使用して SQL Anywhere にデータをロードする方法について語っています。

 

 

このトピックに関する私の以前のブログ記事では、READ_CLIENT_FILE()機能を使用した SQL Anywhereの CSV ファイルのクエリー内からの直接の参照機能について説明しました。

今回のブログ記事では、Version 11 以降でサポートされている LOAD TABLE文の同様の拡張機能について説明したいと思います。

 

 

LOAD TABLE でクライアントに存在するファイルをロードする

 

SQL Anywhere サーバーにおける、データを retrieve するための READ_CLIENT_FILE()を使用したクライアントへのコールバック機能は、LOAD TABLEでも使用可能です。 以前の SQL Anywhere のバージョンでは、LOAD TABLEは、サーバーマシンから直接アクセス可能なファイルへのアクセスのみ可能でした。現在のバージョンでは、適切な権限 (READCLIENTFILE authority) があり、有効化 (the ALLOW_READ_CLIENT_FILE database option) されていれば、クライアントマシンからファイルを直接サーバーのデータベースやテンポラリーテーブルへロードすることが可能です。

 

StatCounterアカウントから生成した CSV ファイルの処理について説明したパート 1 に続いて、LOAD TABLE を使用して、CSV ファイルをパーマネントテーブルにロードする例を以下に示します。

 

  1. CREATETABLE visitor_summary ( 
  2.     dayoftheweek    CHAR(9) NOTNULL
  3.     record_date    CHAR(30) NOTNULL
  4.     page_loads      INTNOTNULL
  5.     unique_visitors INTNOTNULL
  6.     first_time_visitors INTNOTNULL
  7.     returning_visitors INTNOTNULL ); 
  8. LOADTABLE visitor_summary USING CLIENT FILE 'c:\gpaulley\blog\Summary-6July2009.csv' DELIMITED BY',' SKIP 1 

 

USING CLIENT FILE は、サーバー上のファイルのコンテンツをマテリアライズしません。なぜならば、クライアントファイルは 任意のサイズである可能性があるからです。

 

Version 11では、LOAD TABLEはファイルをロードする以上のことをサポートしています。LOAD TABLE のシンンタックスには、USING VALUE 句が含まれ、OPENSTRING にとって同様のやり方である CHARNCHARBINARYLONG VARCHARLONG NVARCHARLONG BINARY 型のいずれの拡張からもテーブルへのデータロードが可能です。

 

そのため、上記の LOAD TABLE文は、以下のように書くことが可能です。

 

  1. LOADTABLE visitor_summary USING VALUE READ_CLIENT_FILE('c:\gpaulley\blog\Summary-6July2009.csv' ) DELIMITED BY',' SKIP 1 

 

 

テーブルカラムからデータをロードする

 

Version 11 では、LOAD TABLE 文には、他のテーブルの他のカラムからデータをロードするための明示的なシンタックスがあり、そのテーブルカラムには、BLOT または CLOB としての「行」が、1 つ以上含まれています (そのためサイズは 2GB に制限されています)。

例を挙げると:

 

  1. BEGIN 
  2.     DECLARE summary_data LONG VARCHAR
  3.     DECLARELOCALTEMPORARYTABLE summary_temp ( summary_line INTNOTNULLPRIMARYKEY, summary_contents LONG VARCHARNOTNULLNOINDEX) ONCOMMIT PRESERVE ROWS
  4.     SET summary_data = xp_read_file( 'c:\gpaulley\blog\Summary-6July2009.csv' ); 
  5.     INSERTINTO summary_temp VALUES ( 1, summary_data ); 
  6.     LOADTABLE visitor_summary USING COLUMN summary_contents FROM summary_temp ORDERBY summary_line SKIP 1 DELIMITED BY','WITH ROW 
  7. END 

 

シンタックスは以下のとおりで

 

  1. LOADTABLE ... USING COLUMN column_name FROM table_name ORDERBYkey [ loading options ] 

 

「table_name.column_name」からの値を処理するためのロードが発生します。ORDER BY句は、オプショナルではありません。プライマリキー、ユニークインデックス、または「table_name」のユニークな制約をカバーするカラムを参照することで「table_name」 内の行の total ordering を特定しなければなりません。LOADは、この order 内の「table_name」の全ての行を処理します。
テンポラリーテーブルに複数の行を挿入するよう上記の例を修正するならば、 (つまり:ライン14 のINSERTを重複):

 

  1. BEGIN 
  2.     DECLARE summary_data LONG VARCHAR
  3.     DECLARELOCALTEMPORARYTABLE summary_temp ( summary_line INTNOTNULLPRIMARYKEY, summary_contents LONG VARCHARNOTNULLNOINDEX) ONCOMMIT PRESERVE ROWS
  4.     SET summary_data = xp_read_file( 'c:\gpaulley\blog\Summary-6July2009.csv' ); 
  5.     INSERTINTO summary_temp VALUES ( 1, summary_data ); 
  6.     INSERTINTO summary_temp VALUES ( 2, summary_data ); 
  7.     INSERTINTO summary_temp VALUES ( 3, summary_data ); 
  8.     LOADTABLE visitor_summary USING COLUMN summary_contents FROM summary_temp ORDERBY summary_line SKIP 1 DELIMITED BY','WITH ROW LOGGING; 
  9. END 

 

その後、StatCounter のサマリーデータの各行の重複コピー3つが「visitor_summary」 にロードされます。

 

 

データとトランザクションログをロードする

 

LOAD TABLE over INSERT文を使用するパフォーマンス上の主なメリットは、実行スピードがより高速になるということです。
実行スピードがアップした方法の 1つとして、まずロード中のテーブル上のトリガーが fire しないということがあります。
もう1つのスピードアップテクニックとして、デフォルトではロード中のデータのコンテンツはトランザクションログには書かれていないということです。LOAD TABLE文のテキストのみが、ログに書かれます。これには、注意すべき重要なポイントがいくつかあります。

 

  • 高可用性システムの一部として、データベースがミラリングされている場合、新たにロードされたデータはミラーリングサーバーに送ることができません。

  • 同様に、LOAD TABLE を使用してロードされた行は、ログベースの同期  (Mobile Link または SQL Remote) では問題を引き起こす可能性があります。なぜならば、行自体はトランザクションログに現れないからです。

     

  • データベースのリカバリーが必要な場合には、LOAD TABLE文を返す必要があります。ロードされたオリジナルのファイルは、 サーバーがトランザクションログから LOAD TABLE 文を返すために利用可能でなければなりません。もしファイルが利用不可能な場合には、リカバリーはできません。もしファイルがオリジナルと異なる場合には、データベースが論理的に壊れてしまう可能性があります。

     

    SQL Anywhere の Version 11 では、LOAD TABLE に関連する問題に対して追加のメカニズムを提供しています。LOAD TABLE文でその文がどのようにログされるべきか明示的に特定するために WITH LOGGING 句を提供しています。可能なオプションは以下のとおりです。

     

    • WITH FILE NAME LOGGING 句。この句は、サーバーにあるファイルをロードする場合のサーバーのデフォルトの動作とマッチします。これは、トランザクションログに記録されるべき LOAD TABLE 文のみ発生します。このレベルのロギングは、表現またはクライアントファイルからロードされる場合には使用できません。LOAD TABLE文にロギングレベルを特定しない場合には、 以下を特定する場合のデフォルトレベルは WITH FILE NAME LOGGINGです。
         
      1. LOADTABLE ... FROM filename-expression 
      2. LOADTABLE ... USING FILE filename-expression 

       

    • WITH ROW LOGGING句。WITH ROW LOGGING句は、INSERT文としてトランザクションログ内に記録されるべきそれぞれの行を発生させます。このレベルのロギングは、同期が含まれるデータベースで推奨されます。またミラーリングでサポートされています。しかしながら、大量のデータをロードする場合には、このロギングのタイムは、パフォーマンスに影響を及ぼす可能性があり、トランザクションログの結果が非常に長くなります。

       

      このレベルはまた、計算カラムや CURRENT TIMESTAMPデフォルトなどのロード先のテーブルが非決定的値を含む場合のデータベースに理想的です。

       

    • WITH CONTENT LOGGING句。WITH CONTENT LOGGING句は、データベースサーバーにロードされている行のコンテンツを一緒に chunkさせます。これらの chunk は、例えば、トランザクションログからのリカバリーの最中など、後で行に再構成することができます。
      大規模なデータをロードしている場合には、このロギングタイプは、それぞれの行をロギングする場合と比較してパフォーマンスにほとんどインパクトを与えず、データ保護は強化されます。しかしながら、WITH CONTENT LOGGINGを使用すると、結果としてトランザクションログは長くなってしまいます。このレベルのロギングは、ミラーリングにかかわるデータベースや、あるいは後のリカバリーにオリジナルデータを維持しない場合などで推奨されます。

         

      WITH CONTENT LOGGING句は、データベースが同期に絡んでいる場合には使用することができません。

         

      LOAD TABLE文でロギングレベルを特定しない場合は、以下を特定した場合、WITH CONTENT LOGGINGがデフォルトのレベルになります。
         
      LOAD TABLE ... USING CLIENT FILE client-filename-expression
      LOAD TABLE ... USING VALUE value-expression
      LOAD TABLE ... USING COLUMN column-expression

       

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

過去のブログ記事より : 現実社会のディスク障害

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/07/23/disk-failures-in-the-real-world

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 10 月に掲載したものです。その中で、Glenn は 一般的なハードドライブの信頼性について語っています。2014年初に発表されたars technicaの記事によると、このブログが書かれた頃と比較して破損率に大きな変化はありません。もちろん、重要なデータであれば、ディスクの障害からデータを守るために、定期的なバックアップをとること、またリカバリーシナリオをテストすることが非常に重要です。

 

 

絶大なスケールのコンピューティング ランドスケーブが、コンピュータサイエンスの領域に貢献したものの一つとして、これらのシステムを統計的に研究することができるようになったということがあります。特に様々なハードウェアやソフトウェアの信頼性を証明または反証することが可能になりました。

 

ディスクドライブに関して言うと、ディスクドライブの信頼性に関するいくつかの大規模な研究 [2,3,4,7] がここ数年の間に発表されています。

特に、Google [4] が行った研究では、ドライブの使用が 3 年を経過すると、障害率が急速に増加 - 6 %から 10%間 - することを示しています。この 3 年という期間は、多くのディスクドライブメーカーが、3 年の保証期間を設けているのと同じ期間であり、たいへん興味深い点です。

また、彼らの研究では、ドライバの最新モデルでは、熱とドライブ障害の間の相関は低いことが示されています。これは、データセンター内でエアコンの使用を控える方向にある中  James Hamilton 氏が最近執筆したと同様です。

最近、FAST 2009 において Amazon の Alyssa Henry 氏 [6] がその基調講演で語った内容によると、Amazon Simple Storage (EC3) データサービスでは、ボード全体で年間 3 - 5 % のハードディスク障害がみられるそうです。しかしながら、Google の調査結果を考えると、Amazon の障害経験は、全てのディスクドライブメーカーに統一的にあてはまるものではないでしょう。

Iliadis氏と Hu氏 [3] は、低コストの磁気メディアへのトレンドが、結果として高い障害率につながっていると考えています。[7] Remzi Arpaci-Dusseauand 氏とウィスコンシン大学マディソン校の彼のチームでもこのようなまとめに至っています。とはいえ、少なくとも、ある程度払った分だけは得ることができるでしょう。

 

これらの研究で報告されている実際の障害率は、ディスクドライブメーカーから提供されている信頼性メトリックスとは大きく異なります。さらに、ディスクハードウェア障害は、このストーリーの一部でしかありません。ウィスコンシン大学の Remzi Arpaci-Dusseau 氏と彼の研究チームは、以前の研究において、磁気メディアにおける トランジェントなエラーは、よくあることであるとしています。2008年2月に、サンノゼで開催された the Linux Storage & Filesystem Workshop のまとめを引用すると、

Ric Wheeler (現 RedHat) 氏は、永続的なエラーハンドリングのトピックについて、セクターのハンドリングのよくないものも「全体障害」にわたってめざましく改善されたというコメントとともに紹介しました。そしてサイレントデータ破損に進み、ファイルシステムに構築されつつあるデータチェックサム(とりわけ BTRFS と XFS) と T 10 DIF の進むサポートによってここでの状況は改善していることにふれました。

「強制されたアンマウント」のトピックは、James Bottomley氏が少なくともブロックの観点では全てがとにかく機能しなければならないと主張し、長いディスカッションを引き起こしました ( USB ストレージ取り出しのサプライズが例として参照されました)。 Ric 氏は、NFS が未だ機能しないと反論し、他の人たちは、たとえブロックI/Oが機能したとしても、そのファイルシステムは inodes をまだリリースしない可能性があると指摘しました。Ted Ts'o 氏は、FAST '08 で発表される研究に興味を引きつけ、エラーがそのブロックとファイルシステムレイヤーでドロップしたり紛失したりした 1,300 のケースを示すことでこのディベートを締めました。(強調を追加しました)

下の [5] では、いくつかのファイルシステムにわたるトランジェントと「ハード」ファイルシステムエラーの欠如または mis-reporting について研究しています。 この研究の要約の最初のパラグラフは以下のとおりです。

ファイルシステムの信頼性は、エラーをいかにうまく propagate (伝播)するかに一部依存しています。我々は、統計的な分析テクニックである EDP を開発しました。これを使うとファイルシステムとストレージデバイスドライバがどのようにエラーコードを propagate するのか分析することができます。Linux 2.6 で全てのファイルシステムと 3 つの主なストレージデバイスを EDP 分析したところ、エラーが不正確に propagate されることが頻繁に発生していることを発見しました。1153 コール (13%) で、ハンドリングされることなくエラーコードがドロップしました。

書き込みキャッシュまたは障害発生中の書き込みは、さらなる問題を発生させる可能性があります。特に Linux システムにおける EXT3 の使用は、EXT3 の ジャーナルに書き込む場合のチェックサムのサポートの欠如 - これは EXT4 ではサポートされています - に起因する壊滅的なハードウェア障害によりファイルシステムを壊してしまう可能性があります。ウィスコンシンの Arpaci-Dusseau 氏と彼の研究チームは、最近このエラー分析を次のレベルに引き上げました [1]。彼らは、意図的かつシステマティックに、以前の研究から知られるファイルシステムで発生するある種のハードやトランジェント障害からリカバリするサーバーの能力を判断するために MySQL データベースにエラーを実装しました。この結果は、先に述べた広範囲のディスク障害の研究とともに、全てのデータベース管理者が懸念する必要性があることを示していると言えるでしょう。私はデータベース管理者の皆様に以下の文献を読み、これらのバックアップを手元にキープすることをお奨めします。

 

 

 

[1] Sriram Subramanian, Yupu Zhang, Rajiv Vaidyanathan, Haryadi S. Gunawi, Andrea C. Arpaci-Dusseau, Remzi H. Arpaci-Dusseau, and Jeffrey F. Naughton (April 2010). Impact of Disk Corruption on Open-Source DBMS. In Proceedings, 2010 IEEE International Conference on Data Engineering, Long Beach, California. To appear.

 

[2] Bianca Schroeder and Garth A. Gibson (February 2007). Disk failures in the real world: What does an MTTF of 1,000,000 hours mean to you?In Proceedings, 5th USENIX Conference on File and Storage Technologies, San Jose, California, pp. 1-16.

 

[3] Ilias Iliadis and Xiao-Yu Hu (June 2008). Reliability Assurance of RAID Storage Systems for a Wide Range of Latent Sector Errors. Proceedings of the International Conference on Networking, Architecture, and Storage, Chongqing, China. IEEE Computer Society, ISBN 978-0-7695-3187-8.

 

[4] Eduardo Pinheiro, Wolf-Dietrich Weber, and Luiz André Barroso (February 2007). Failure Trends in a Large Disk Drive Population. In Proceedings, 5th USENIX Conference on File and Storage Technologies, San Jose, California, pp. 1-16.

 

[5] Haryadi S. Gunawi, Cindy Rubio-González, Andrea C. Arpaci-Dusseau, Remzi H. Arpaci-Dusseau, and Ben Liblit (February 2008). EIO: Error Handling is Occasionally Correct.In Proceedings, 6th USENIX Conference on File and Storage Technologies, San Jose, California, pp. 207-222.

 

[6] Alyssa Henry (February 2009). Cloud Storage FUD (Failure, Uncertainty, and Durability). Keynote address, 7th USENIX Conference on File and Storage Technologies, San Francisco, California.

 

[7] Lakshmi N. Bairavasundaram, Garth R. Goodson, Bianca Schroeder, Andrea C. Arpaci-Dusseau, and Remzi H. Arpaci-Dusseau (February 2008). An Analysis of Data Corruption in the Storage Stack. In Proceedings of the 6th USENIX Symposium on File and Storage Technologies (FAST '08), San Jose, California, pp. 223-238.

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

過去のブログ記事より : ベンチマークと測定バイアス

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/06/11/benchmarks-and-measurement-bias

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 3 月に掲載したものです。その中で、Glenn はシンプルなベンチマークや測定バイアスへのフォーカスの危険性について語っています。

 

 

 

私は、ここ数週間、SQL Anywhereが関わるもの、関わらないものにかかわらず、公開されている複数のパフォーマンス分析を見てきました。

概して、これらの「ベンチマーク」は、非常にシンプルでした。シンプルなベンチマークは、複雑なものと比較して開発の努力は少なくてすむため、これは想像の範囲でしたが。

 

私が頻繁に目にするパフォーマンス分析に、例えばシンプルに 1 つのテーブルに行をできるだけ高速に挿入できるかというようなものがあります。「Knowing that value is a Good Thing (TM)」(その価値を知ることは良いことです) - そして、私たちのラボでもこれの(その他も)価値を判断するために特定のテストをします。しかしながら、データベースアプリケーションのパフォーマンス分析には、以下の 2 点を指摘したいと思います。

 

  1. ほとんどの場合、このようなシンプルなテストはアプリケーションの動作をうまく表していないため、あまり意味がありません。また
  2. シンプルなオペレーションのきめの細かいテストは、幅広いパフォーマンス要素に依存する可能性があり、効率性のわずかな差であってもテスト結果を大幅にゆがめてしまう可能性があります。

 

2 つ目について、Raj Jain 氏のパフォーマンス分析の書籍 [1] 「Common Mistakes and How to Avoid Them」(よくある間違いとその間違いを避ける方法) の第 2 章から以下を引用したいと思います。

パフォーマンスに影響を及ぼす様々なシステムやワークロードパラメーターのランダム性を理解することはとても重要です。これらのパラメーターの中には、他よりは理解されているものもあります。例えば、アナリストは、コンピューターシステムにおけるページ参照の分散について知っているかもしれません。このような場合によくある間違いが、ディスクがボトルネックにある可能性があり、ページ参照よりもパフォーマンスへの影響があるかもしれないにもかかわらず、ページ参照分散を要素として使用してしまうことです。要素の選択は、関連性に基づいて行われべきで、アナリストの要素に関する知識にもとづいて行われるべきではありません。

 

実験的なセットアップにおける潜在的バイアスまたは明示的なバイアスのインパクトは、過小評価することができません。実際、最近の 論文[2] では、SPEC CPU2006 ベンチマークスイートのようなシンプルなコンパイラーベンチマークは、著者が「測定バイアス」と呼ぶ問題を避けるに十分なほど多様ではありません。この論文の概要は以下のとおりです。

 

この論文は、驚くべき結果を示しています。実験的なセットアップにおいて、表面的に無害な側面を変更することで、システムの調査員は実験から誤った結論を導きだしてしまう可能性があります。実験的なセットアップにおける無害な側面と思われるものは、実際には評価において大きなバイアスをもたらします。この現象は、自然科学や社会科学において測定バイアスと呼ばれています。我々の結果では、測定バイアスは、コンピューターシステムの評価において、「重要」かつ「よくあること」であることを表しています。「重要」という言葉で意味するところは、測定バイアスがパフォーマンス分析において効果を誇張するあるいは不正確な結論を導いてしまうということです。「よくあること」というのは、測定バイアスが、我々が試みた全てのアーキテクチャー(Pentium 4、Core 2、そして m5 03CPU)で試みたコンパイラーのどちらでも (gcc と Intel の C コンパイラー)、さらにはほとんどの SPEC CPU2006 C プログラムで起こることを意味しています。そのため、我々は測定バイアスを無視することはできません。にもかかわらず、ASPLOS、PACT、PLDI、CGO からの最近の 133 もの論文の文献調査において、測定バイアスについて適切に考慮された実験結果に基づく論文はありませんでした。

 

Mytkowicz 氏らの結果は、例えば、
(a)プログラムスタックのアライメントに影響するマシンの環境変数に必要なメモリの量や、
(b)キャッシュラインの「hot」ループのアライメントに影響する最終実行ファイルのコンパイルされたオブジェクトのリンクオーダーなど、
テストにおける環境的な要素で発生した測定バイアスが、このケースでは、O3 コンパイラー最適化の効果である測定されるべきパフォーマンス要素に打ち勝ってしまうことを示しています。
彼らの結果では、実験的なセットアップを修正することが、それ自体パフォーマンスを 0.8 から 1.1 にスピードアップさせてしまうことを示しています。これはつまり、これらの測定されていない要素によって、彼らのテストにおいてスピードが 20% 減速する可能性があり、また、10% アップする可能性があるということを示しています。
著者は、測定バイアスを避ける、あるいは検出するために、3つの提案をしています。これは私が見る限り、データベースアプリケーションのベンチマークでも同様に適用することが可能です。
それらは以下のものです。

 

  • より大きなベンチマークスイートを活用する。測定バイアスを要素から除外するに十分になるよう多様化させる。
  • 多数の実験的なセットアップを生成する。測定バイアスを発生させることで知られるパラメーターを変化させる。そして統計的メソッドを使用して結果を分析する。
  • 測定バイアスに直面している場合でも、描かれた結論が有効であると確信を得るための略式の分析(インターベンション、測定、確認)を使用する。

 

[2] に注意を向けてくれた同僚の Nathan Auch に感謝します。

 

[1] Raj Jain (1991). The Art of Computer Systems Performance Evaluation, John Wiley and Sons, New York. ISBN 0-471-50336-3.

[2] Todd Mytkowicz, Amer Diwan, Matthias Hauswirth, and Peter F. Sweeney (March 2009). Producing Wrong Data Without Doing Anything Obviously Wrong! In Proceedings, 14th International Conference on Architectural Support for Programming Languages and Operating Systems, Washington, DC, pp. 265-276.

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

過去のブログ記事より : SQL Anywhere で MERGE 文を使用する

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/02/11/using-the-merge-statement-with-sql-anywhere

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 4 月に掲載したものです。その中で、Glenn は SQL Anywhere における MERGE 文について解説しています。MERGE 文に関する最新の情報はこちらを参照ください。

 

 

 

 

MERGE文は、SQL:2003 ANSI/ISO の F312 の機能として登場しました。MERGEは、行のセットを挿入する必要があり、かつ、クリーニングまたは他の ETL (Extract-Transform-Load) プロセスが必要な時に便利です。MERGEを使用すると、1 つの文で新規データ挿入と既存の行の更新をセットで対応できる洗練されたロジックを実装することができます。

このブログ記事では、MERGE文の機能について簡単に概要を説明するとともに、SQL:2003 と SQL:2008 間でどのような変更があったのか、さらに SQL Anywhere でサポートされている拡張機能について説明します。

ここでは、私の同僚である Anil Goel が 2008 年 8月にラスベガスで開催された Sybase Techwave においてプレゼンした MERGE文とマテリアライズドビューに関する資料を借りて説明したいと思います。

 

 

テーブルに行を挿入する処理を行う場合、「INSERT-else-UPDATE」処理を実行する必要がある場合があります。これこそが、MERGE文を使用する理由です。さらには以下のようなメリットがあります。

 

INSERTの代替アクションを設定することができます。例えば

• 特定の行において条件次第で INSERTをスキップ、または UPDATEを行う

• 既存の行を DELETEする

などのように任意の条件を設定し、代替アクションを行わせることができます。

 

空ではないテーブルTがあり、以下のように入力行データ S を処理するとします。

 

  1. FOR each input row in S DO
  2.   IF EXISTING THEN // もし、行Sと同一の主キーの行が既にテーブルTに存在する場合
  3.     IF condition-1 THEN SKIP // 条件 1 にマッチした場合は処理をスキップ
  4.     ELSE IF condition-2 THEN ERROR //条件 2 にマッチした場合はエラーを返す
  5.     ELSE IF condition-3 THEN DELETE FROM T //条件 3 にマッチした場合はその行をテーブル T から削除
  6.     ELSE UPDATE T //条件 1 ~ 3 にマッチしなかったらその行を更新する
  7.   ELSE // 行 S と同一の行がテーブル T に存在しなかった場合
  8.     IF condition-4 THEN SKIP //条件 4 にマッチした場合は処理をスキップ
  9.     ELSE IF condition-5 THEN ERROR //条件 5 にマッチした場合はエラーを返す
  10.     ELSE INSERT INTO T //条件 4 ~ 5 にマッチしなかったら行 S を挿入する
  11. END

 

このロジック全体を、以下のような 1 つの MERGE文として実行することが可能です。以下の例では、テーブル T にクライアントマシン上のテキストファイルを読み込み、それに含まれる行をマージしています。これは、version 11 の OPENSTRING句を使用することでテーブルのように扱うことができます。

 

  1. MERGE INTO T
  2. USING (SELECT * FROM OPENSTRING( FILE '/usr/paulley/techwave/2008/data1.txt')
  3.           WITH( id INT, qty INT, cmt LONG VARCHAR)  S) S //CSVファイルを読み込み、区切り文字毎にid,qty,cmtという変数で以下扱えるようにします。行全体はSという変数となりますので各カラムにはS.カラム名、例えばidカラムならS.idという形でアクセスする事ができます。
  4. ON PRIMARY KEY
  5. WHENNOT MATCHED AND S.cmt = 'ignore'THEN SKIP //主キーの重複が発生せず、テキストファイル上の行のcmtカラムに相当するデータがignoreではなかった場合はこの行をスキップ
  6. WHENNOT MATCHED AND S.qty < 0  THEN RAISERROR //主キーの重複が発生せず、テキストファイル上の行のqtyカラムに相当するデータが0以下ではなかった場合はエラーを返す
  7. WHENNOT MATCHED AND S.qty = 0 THEN INSERT VALUES( S.id, 1 ) //主キーの重複が発生せず、テキストファイル上の行のqtyカラムに相当するデータが0の場合はテーブルTに( S.id, 1 ) を挿入する
  8. WHENNOT MATCHED THEN INSERT VALUES( S.id, S.qty ) //主キーの重複が発生せず、上記の3条件に合致しなかった場合はテーブルTに( S.id, S.qty )を挿入する
  9. WHEN MATCHED AND S.cmt = 'ignore'THEN SKIP
  10. WHEN MATCHED AND S.cmt = 'new'  THEN RAISERROR //主キーの重複が発生し、テキストファイル上の行のcmtカラムに相当する場所のデータがignoreの場合はこの行をスキップ
  11. WHEN MATCHED AND T.qty + S.qty
  12. ...

 

 

MERGE 文 - 概要

 

SQL:2003 で定義されている MERGE文は、最大でも WHEN MATCHED 1つと WHEN NOT MATCHED句1つしか許していません。

 

SQL:2003 MERGE文は、以下のとおりです。

 

• target-object の各行で、ソースとターゲットから 'matching' # 行を見つけるために、MERGEサーチ条件が source-object の各行を TRUE と評価するかどうか決める

• マッチする行が発見された場合には、エラーを生成する。

• 見つかった場合には、マッチング行 1 行を行のセットに追加し、存在する場合 WHEN MATCHED句で処理する。

• 存在する場合、WHEN NOT MATCHED句が target-object 行にマッチできない source-object の行を処理する。

 

SQL:2008 の Feature F313 では、複数の WHEN [NOT] MATCHED句をオプショナルのサーチ条件で許可しています。この場合、WHEN句の順番が問題になります。実行されるサーチ条件を満足させるのは、最初の WHEN句のマージアクションです。しかしながら、Feature F313 でも、標準の MERGE文はそれほどフレキシブルではありません。WHEN MATCHED句が実行できる唯一のオペレーションは、UPDATEであり、WHEN NOT MATCHED句が実行できる唯一のオペレーションは INSERTです。SQL Anywhere 11 では、MERGE文の機能をいくつかの方法で拡張しています。それらのいくつかは、2002年の SQL Anywhere version 8 で実装された、それまでの INSERT ... ON EXISTING文を引き継いでいます。

 

OPENSTRING構造 を使用して、クライアントマシン上のテキストファイルのデータを MERGEに使用できるように拡張しています。

• 明示的なカラムリストを使用して入力行データのカラムとMARGE 先のテーブルカラムのマッチングを変更できるように拡張しています。

WITH AUTO NAME構文を使用してカラム順ではなくカラム名によるカラムのマッチングができるように拡張しています。

MERGEサーチ条件は、プライマリーキー重複に基づく場合、省略形として ON PRIMARY KEYが使用可能です。

•  WHEN MATCHEDで実行できるアクションが拡張されています。

• 既存の行を DELETE

RAISERROR [ error-number ]

SKIP

• 既存の行を UPDATE [ DEFAULTS { ON | OFF }

WHEN NOT MATCHEDで実行できるアクションが拡張されています。

• 入力行データを INSERTする

RAISERROR[ error-number ]

SKIP

 

ターゲットテーブルの INSERT、DELETE、UPDATE、トリガーの構文と並び、MERGE文の構文の詳細は、SQL Anywhere のマニュアルに記載されています。

SQL Anywhere 11 でサポートされている MERGE文を BNF で記述すると以下のとおりです。

 

  1. merge                ::= "MERGE" "INTO" merge_into_tabterm merge_using
  2.                         simple_tabterm merge_on_clause merge_op_list
  3. merge_using          ::= "USING" | "USING WITH AUTO NAME"
  4. merge_into_tabterm  ::= ( tabref | "(" query_expr ")" as identifier
  5.                         | "(" "WITH" with_list query_expr ")" as identifier ) derived_collist
  6. merge_on_clause      ::= "ON" merge_search_cond
  7. merge_search_cond    ::= searchcond
  8.                         | "PRIMARY" "KEY"
  9.                         | "INDEX" indexname
  10. merge_op_list        ::= merge_op { "," merge_op }
  11. merge_op            ::= "WHEN MATCHED" "THEN" merge_matched_op
  12.                         | "WHEN MATCHED" "AND" searchcond "THEN"
  13.                           merge_matched_op
  14.                         | "WHEN NOT" "MATCHED" "THEN"
  15.                           merge_not_matched_op
  16.                         | "WHEN NOT" "MATCHED" "AND" searchcond
  17.                           "THEN" merge_not_matched_op
  18. merge_common_op      ::= "SKIP"
  19.                         | "RAISERROR"
  20.                         | "RAISERROR" integer_or_var
  21. merge_matched_op    ::= merge_common_op
  22.                         | "UPDATE SET" setlist
  23.                         | "UPDATE"
  24.                         | "UPDATE" "DEFAULTS" "ON"
  25.                         | "UPDATE" "DEFAULTS" "OFF"
  26.                         | "DELETE"
  27. merge_not_matched_op ::= merge_common_op
  28.                         | "INSERT" "VALUES" "(" ins_vallist ")"
  29.                         | "INSERT" "(" inscollist ")" "VALUES" "(" ins_vallist ")"
  30.                         | "INSERT"
  31. ins_vallist          ::= { ins_valitem "," } ins_valitem
  32. ins_valitem          ::= "DEFAULT" | expression
  33. inscollist          ::= { inscolname "," } inscolname
  34. inscolname          ::= identifier [ "." identifier ]

 

Techwave 2008 での我々のプレゼンに上記のコンテンツの大半を入れてくれた Anil Goel に感謝します。

 

 

===

 

SAP SQL Anywhere に関する詳細情報は、SAP SQL Anywhere SCN Communityページ <英語> を参照してください。

 

上記のコミュニティーに掲載されている技術情報は、順次SQL Anywhere Japan のブログに掲載しています。記事をリスト形式で表示するには、「sql_anywhere」のタグをクリックしてください。

 

SQL Anywhere に関してはまずはこちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。

 

SQL Anywhere に関して技術的な質問のある方はSCN の SAP 日本語コミュニティの「ディスカッション」機能をご利用ください。

不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。

 

 

 

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。


過去のブログ記事より : SQL Anywhere とその他データベースにおける「マテリアライズドビュー」の名称

$
0
0

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

http://scn.sap.com/community/sql-anywhere/blog/2014/02/25/materialized-view-terminology

 

 

この記事のオリジナルは、Glenn Paulleyが sybase.com に 2009 年 4 月に掲載したものです。その中で、Glenn は SQL Anywhere において我々がマテリアライズドビューと呼んでいる機能に関するベンダー間の名称の違いについて解説しています。

(*注:この記事は2009年に執筆されたもので、他DBMSに関しては、現在は異なる可能性があることに注意してください。)

 

また、SAP HANAアーキテクチャーにおいては、マテリアライズドビューは必要ないということを述べておきたいと思います。なぜならば、HANA の場合は全てのデータはメインメモリー上で利用可能で、オンザフライで処理/集約可能だからです。

 

===

 

商談中のお客様より、かなりの頻度で SQL Anywhereがマテリアライズドビューの機能をサポートしているかどうか (多くは同じ「マテリアライズドビュー」の他の名前で)尋ねられます。

 

そこで、代表的な商用 RDBMS 製品の「マテリアライズドビュー」に相当する名称を以下にまとめてみました。

 

DBMS名称WhenHowWho
MS SQL Serverインデックス付ビュー即時反映差分更新システム
IBM DB2マテリアライズド照会表即時 と 遅延差分更新 または 再構築システム または ユーザー
Oracleマテリアライズドビュー遅延反映(*注:現在は即時反映も可能)差分更新 または 再構築システム または ユーザー
SQL Anywhereマテリアライズドビュー即時 と 遅延差分更新 または 再構築システム または ユーザー

 

上記のテーブルでは、「when」(いつ反映されるか?) 列は、ベースとなるテーブルの行が 1 つまたはそれ以上変更された場合にマテリアライズドビューが更新されるタイミングを示しています。つまり、

 

  • 完全即時反映:
    • 同じ (更新の) トランザクションの一部としてマテリアライズドビューを更新
    • ベーステーブルの変更をビューデータにもととなるベーステーブルとの一貫性を保つ方法で伝播
    • ビューデータが古くなることはない。
    • 更新トランザクションの同時性を劣化させるとともに、ロックの競合とデッドロックを発生させる可能性が高くなる。

 

  • 遅延即時反映:
    • 依存するマテリアライズドビューを更新することなくベーステーブルに変更を適用
    • 差分更新が可能な場合、ログが変更(追記)される可能性がある。
    • クエリー実行時において、ビューにデータが反映されている場合には、結果を提供するためにビューを使用することが可能。もしくは、別のトランザクションを適用、またはマテリアライズドビューを再計算する。それが完了するまでクエリーの実行は待機

 

  • 遅延反映:
    • 関係するマテリアライズドビューを更新することなくベーステーブルに変更を適用
    • 差分更新が可能な場合、ログが変更(追記)される可能性がある。
    • 独立した非同時の処理で、通常は完全な再計算によってビューを更新
    • アプリケーションは、マテリアライズドビューが最新の状態でない場合があることを考慮している。

 

 

「how」のカラムは、ビューのベーステーブルが変更された場合にビューを最新の状態に保つ方法について示しています。

 

選択肢としては、

  • 再構築: 完全にビューを再計算する。
  • 差分更新: 再構築の形でなく変更された部分にのみマテリアライズドビューに個々の更新を適用する。しかし、これは全てにおいて可能なわけではなく、また効率性においてトレードオフがあります。大半の場合、即時反映のマテリアライズドビューでは、差分更新が行われています。

 

「マテリアライズドビュー」という名称は、標準化されていません。

なぜならば、マテリアライズドビューは、インデックスのように、パフォーマンス最適化の機能であるため、ANSI/ISO SQL 標準でカバーされていないからです。

SQL Anywhere に「マテリアライズドビュー」という名称を選択したのは、(単に)Oracle と合わせたというだけではなく、学術的な文書において「マテリアライズドビュー」の使用が比較的多くみられたからです。

 

 

上のテーブルに、Sybase IQ (現 SAP IQ)が省かれていることについて質問される方もいるかもしれません。

 

実は、Sybase IQ はマテリアライズドビューをサポートしていません。そのかわり、Sybase IQ は、関連する(少し古い)考え方である join index と呼ばれるものをサポートしています。(*注:現在 SAP IQ に join index の機能はありません。)

 

Join indicesは、もともと Patrick Valduriezによる論文1987 TODS paper [1]、その後 MCC で、そして現在は INRIA で解説されています。マテリアライズドビューと同様、join index は 2つのテーブル間の 内部結合 | 外部結合 | 完全外部結合 の結果をマテリアライズします。full-outer join index のメリットは、あらゆる 内部結合 | 外部結合 | 完全外部結合 を使用したクエリーの処理に対してシンプルにフィルタ条件を 適用することで使用することができることです。

 

違いは、マテリアライズドビューの方がより一般的であり、1対多の内部結合 | 外部結合 | 完全外部結合 を フィルタ条件、射影、グループ可等を行った後にマテリアライズすることが可能という点です。

バッチで更新するマテリアライズドビューは、任意の結合で代数使用した処理を含むことが可能です。

 

 

 

Techwave 2008 におけるマテリアライズドビューのプレゼンにこの文書を一緒にまとめてくれた同僚の Anil Goel に感謝します。

 


[1] Patrick Valduriez (June 1987). Join indices. ACM Transactions on Database Systems 12(2), pp. 218-246.

 

 

===

 

SAP SQL Anywhere に関する詳細情報は、SAP SQL Anywhere SCN Communityページ <英語> を参照してください。

 

上記のコミュニティーに掲載されている技術情報は、順次SQL Anywhere Japan のブログに掲載しています。記事をリスト形式で表示するには、「sql_anywhere」のタグをクリックしてください。

 

SQL Anywhere に関してはまずはこちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。

 

SQL Anywhere に関して技術的な質問のある方はSCN の SAP 日本語コミュニティの「ディスカッション」機能をご利用ください。

不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。

 

 

 

 

 


======================

ご購入に関するお問い合わせ

 

こちらよりお問い合わせください。

Viewing all 49 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>