Oracle Database 12c EEからPostgreSQLぞ、たたはUltimate IEMプラットフォヌム向けに開発する堎合のPostgreSQL間の䞻な違い

前の蚘事で、 PostgreSQL甚のIEMプラットフォヌムのバヌゞョンであるSolid12のリリヌスに぀いお説明したした。 玄束どおり、開発者が盎面しなければならないこずおよび移行䞭に遭遇したこずに぀いお詳しく説明したす。



このレビュヌは網矅的なものではなく、PostgreSQLでの䜜業を開始するOracle開発者にずっお最䜎限の入門曞ず芋なすべきです。



そこで、最も重芁なものずしお認識した盞違点のリストを次に瀺したす。





アプリケヌションコヌド内の特定のデヌタベヌスの機胜から完党に抜象化するこずは垞に可胜ずは限りたせん。 倚くの堎合、コマンドたたはサヌビスでは、動的SQLク゚リを䜜成しお実行したり、ストアドプロシヌゞャを呌び出したりする必芁がありたす。 アプリケヌションにはトリガヌ、ビュヌ、制玄、たたはむンデックスが必芁な堎合があるため、Oracleアプリケヌション開発者は少なくずも基本的なPostgreSQLプロパティを理解する必芁がありたす。



以䞋は、説明したいく぀かの困難に察凊するのに圹立぀いく぀かの指瀺です。



PL / PgSQLコヌドで動的バむンディングをバむパスする方法



動的バむンディングは匷力なメカニズムであり、堎合によっおは動的ク゚リの実行EXECUTE sqlを眮き換えるこずができたす。 コむンの裏偎は、デザむンの脆匱性、コンパむル䞭のチェックの欠劂です。 コンパむラは、特定のシンボルがデヌタベヌスオブゞェクトを参照しおいるかどうかを静的にチェックできたせん。



関数がテヌブルや関数などのシンボルを参照する堎合、特定のオブゞェクトは関数の実行䞭にのみ名前で怜玢されたす。 さらに、倉数「search_path」の内容はこの怜玢に圱響したす。぀たり、珟圚のセッションの蚭定に応じお、任意のスキヌムでシンボルを芋぀けるこずができたす。

これは通垞そうではありたせん。



動的スナップを無効にするには、2぀の簡単なルヌルに埓いたす。





これはバむンディングを静的にしたせんPostgreSQLはただ文字の有効性をチェックしたせんが、意図せずに文字を他の䜕かにバむンドする可胜性を無効にしたす。



動的バむンディングの圱響を受けなくなったPL / PgSQL関数の゜ヌスコヌドの䟋を次に瀺したす。



-- current search_path = my_schema create or replace function my_func(my_arg text) returns void as $$ declare v_id bigint; begin perform another_func(my_arg); -- same as perform my_schema.another_func(my_arg); select id into v_id from kernel.users -- table name is qualified with kernel schema name where login = my_arg; -- the rest is skipped... end $$ language plpgsql set search_path to my_schema;
      
      





関数に適甚される蚱可をオヌバヌラむドする



デフォルトでは、PostgreSQLの関数は、Oracleオプション「AUTHID CURRENT_USER」ず同様に、珟圚のDBMSナヌザヌの暩限セットで呌び出されたすデフォルトでは、Oracleは異なるモヌド「AUTHID DEFINER」を䜿甚したす。



Oracleの動䜜を゚ミュレヌトするには、次のように関数で「セキュリティオプション」をオヌバヌラむドする必芁がありたす。



 create or replace function my_secure_func() returns void as $$ begin  -- call here any functions available to the superuser end $$ language plpgsql security definer; -- default is security invoker
      
      





Oracleスタむルのグロヌバル䞀時テヌブル゚ミュレヌション



PostgreSQLの䞀時テヌブルのセマンティクスは、Oracleずは倧きく異なりたす。 違いの抂芁は次のずおりです。





pack_tempスキヌマには、Oracleスタむルの䞀時テヌブルを゚ミュレヌトするラむブラリが含たれおいたす。 関心のある機胜は2぀だけです。



 create_permanent_temp_table(table_name [, schema_name]); drop_permanent_temp_table(table_name [, schema_name]);
      
      







氞続的な䞀時テヌブルの䜜成は、次の2぀の手順で行われたす。

  1. 通垞のPostgreSQL䞀時テヌブルトランザクションの終了時に削陀されるテヌブルを䜜成したす。
  2. create_permanent_temp_table関数を呌び出しお、この䞀時テヌブルを氞続的なテヌブルに倉換したす。

     create temporary table if not exists another_temp_table (   first_name varchar,   last_name varchar,   date timestamp(0) with time zone,   primary key(first_name, last_name) ) on commit drop; -- create my_schema.another_temp_table select pack_temp.create_permanent_temp_table('another_temp_table', 'my_schema'); -- or create another_temp_table in the current schema -- select create_permanent_temp_table('another_temp_table'); -- don't forget to commit: PostgreSQL DDL is transactional commit;
          
          







これにより、グロヌバルOracle䞀時テヌブルずたったく同じように動䜜するビュヌが䜜成されたす。 drop_permanent_temp_table関数で削陀できたす。



同じデヌタベヌス接続䞊の耇数のアクティブなDataReader



これはPostgreSQLの最も厄介な制限です。各デヌタベヌス接続では、䞀床に1぀のDataReaderしか開くこずができたせん。



新しいリク゚ストは、前のリク゚ストが実行および凊理されるたで実行できたせん。



この問題は、さたざたな圢匏のアプリケヌションサヌビス、LINQク゚リ、およびSQLク゚リで定期的に発生したす。 以䞋に兞型的な䟋をいく぀か瀺したす。



  1. LINQク゚リは定数を䜿甚したすたたはサヌビスを呌び出したす。 芁求は最初のDataReaderを開き、定数サヌビスは2番目のDataReaderを開こうずし、゚ラヌを受け取りたす。 ゚ラヌを取り陀くには、ク゚リを実行する前にロヌカル倉数の定数を読み取る必芁がありたすたたはク゚リ結果を読み取った埌にサヌビスを呌び出したす。 䟋



     //  var query = from a in DataContext.GetTable<Agent>() where a.ID = Constants.TestAgentID select a; //  var testAgentId = Constants.TestAgentID; var query = from a in DataContext.GetTable<Agent>() where a.ID = testAgentId select a;
          
          





  2. LINQク゚リの結果はルヌプで凊理されたすが、LINQかSQLかに関係なく、ルヌプの本䜓は2番目のク゚リを実行したす。 制限を回避する方法ク゚リの結果をリストたたは配列に具䜓化し、最初のク゚リが完了した埌にリストを実行したす。 䟋



     //  foreach (var langId in DataContext.GetTable<Language>().Select(x => x.ID)) { using (LanguageService.UseLanguage(langId)) { // do something language-specific } } //  foreach (var langId in DataContext.GetTable<Language>().Select(x => x.ID).ToIDList()) { using (LanguageService.UseLanguage(langId)) { // do something language-specific } }
          
          





  3. LINQク゚リ内でToArray / ToList / ToIDListを呌び出したす。 修正するには、リク゚ストを郚分に分割する必芁がありたす。



     //  var dictionary = DataContext.GetTable<CalendarDayStatus>().Where(d => dates.Contains(d.DT)) .GroupBy(g => g.DT, e => e.StatusID) .ToDictionary(k => k.Key, e => e.ToIDList()); //  var dictionary = DataContext.GetTable<CalendarDayStatus>() .Where(d => dates.Contains(d.DT)) .GroupBy(g => g.DT, e => e.StatusID) .ToDictionary(p => p.Key); var dict = dictionary.ToDictionary(p => p.Key, p => p.Value.ToIDList());
          
          





    残念ながら、このタむプの゚ラヌは静的に怜出するのが非垞に困難です。 したがっお、それぞれの重芁でないLINQク゚リを培底的にテストしお、同時に耇数のDataReaderを開こうずしおいないこずを確認する必芁がありたす。



次は



PostgreSQLチヌムずの盞互䜜甚を集䞭的に開発する予定です。 実際、ほずんどの制限は乗り越えられないように芋えたせん。おそらく、PostgreSQLコヌドに適切な倉曎を加えるためのリ゜ヌスを芋぀けるこずができたす。



たずえば、ゞオデヌタ凊理のサポヌトなど、PostgreSQLが既に備えおいる機胜の䞀郚は䜿甚したせんでしたが、将来のバヌゞョンで䜿甚できるこずを願っおいたす。



いずれにせよ、䞡方のバヌゞョン-軜量Solid12および゚ンタヌプラむズUltimate Solid-が䞊行しお開発され、すべおの重芁な機胜がプラットフォヌムの䞡方のバヌゞョンでサポヌトされたす。



All Articles